@@ -526,7 +526,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
526526 // `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
527527 crate fn early_resolve_ident_in_lexical_scope (
528528 & mut self ,
529- mut ident : Ident ,
529+ orig_ident : Ident ,
530530 ns : Namespace ,
531531 macro_kind : Option < MacroKind > ,
532532 is_import : bool ,
@@ -582,6 +582,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
582582 enum WhereToResolve < ' a > {
583583 DeriveHelpers ,
584584 MacroRules ( LegacyScope < ' a > ) ,
585+ CrateRoot ,
585586 Module ( Module < ' a > ) ,
586587 MacroUsePrelude ,
587588 BuiltinMacros ,
@@ -605,8 +606,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
605606
606607 assert ! ( force || !record_used) ; // `record_used` implies `force`
607608 assert ! ( macro_kind. is_none( ) || !is_import) ; // `is_import` implies no macro kind
608- let rust_2015 = ident . span . rust_2015 ( ) ;
609- ident = ident . modern ( ) ;
609+ let rust_2015 = orig_ident . span . rust_2015 ( ) ;
610+ let mut ident = orig_ident . modern ( ) ;
610611
611612 // Make sure `self`, `super` etc produce an error when passed to here.
612613 if ident. is_path_segment_keyword ( ) {
@@ -627,10 +628,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
627628 let mut innermost_result: Option < ( & NameBinding , Flags ) > = None ;
628629
629630 // Go through all the scopes and try to resolve the name.
630- let mut where_to_resolve = if ns == MacroNS {
631- WhereToResolve :: DeriveHelpers
632- } else {
633- WhereToResolve :: Module ( parent_scope . module )
631+ let mut where_to_resolve = match ns {
632+ _ if is_import && rust_2015 => WhereToResolve :: CrateRoot ,
633+ TypeNS | ValueNS => WhereToResolve :: Module ( parent_scope . module ) ,
634+ MacroNS => WhereToResolve :: DeriveHelpers ,
634635 } ;
635636 let mut use_prelude = !parent_scope. module . no_implicit_prelude ;
636637 let mut determinacy = Determinacy :: Determined ;
@@ -668,6 +669,26 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
668669 Err ( Determinacy :: Undetermined ) ,
669670 _ => Err ( Determinacy :: Determined ) ,
670671 }
672+ WhereToResolve :: CrateRoot => {
673+ let root_ident = Ident :: new ( keywords:: CrateRoot . name ( ) , orig_ident. span ) ;
674+ let root_module = self . resolve_crate_root ( root_ident) ;
675+ let binding = self . resolve_ident_in_module_ext (
676+ ModuleOrUniformRoot :: Module ( root_module) ,
677+ orig_ident,
678+ ns,
679+ None ,
680+ record_used,
681+ path_span,
682+ ) ;
683+ match binding {
684+ Ok ( binding) => Ok ( ( binding, Flags :: MODULE ) ) ,
685+ Err ( ( Determinacy :: Undetermined , Weak :: No ) ) =>
686+ return Err ( Determinacy :: determined ( force) ) ,
687+ Err ( ( Determinacy :: Undetermined , Weak :: Yes ) ) =>
688+ Err ( Determinacy :: Undetermined ) ,
689+ Err ( ( Determinacy :: Determined , _) ) => Err ( Determinacy :: Determined ) ,
690+ }
691+ }
671692 WhereToResolve :: Module ( module) => {
672693 let orig_current_module = mem:: replace ( & mut self . current_module , module) ;
673694 let binding = self . resolve_ident_in_module_unadjusted_ext (
@@ -816,7 +837,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
816837 } else if innermost_flags. contains ( Flags :: MACRO_RULES ) &&
817838 flags. contains ( Flags :: MODULE ) &&
818839 !self . disambiguate_legacy_vs_modern ( innermost_binding,
819- binding) {
840+ binding) ||
841+ flags. contains ( Flags :: MACRO_RULES ) &&
842+ innermost_flags. contains ( Flags :: MODULE ) &&
843+ !self . disambiguate_legacy_vs_modern ( binding,
844+ innermost_binding) {
820845 Some ( AmbiguityKind :: LegacyVsModern )
821846 } else if innermost_binding. is_glob_import ( ) {
822847 Some ( AmbiguityKind :: GlobVsOuter )
@@ -867,6 +892,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
867892 LegacyScope :: Empty => WhereToResolve :: Module ( parent_scope. module ) ,
868893 LegacyScope :: Uninitialized => unreachable ! ( ) ,
869894 }
895+ WhereToResolve :: CrateRoot => match ns {
896+ TypeNS | ValueNS => WhereToResolve :: Module ( parent_scope. module ) ,
897+ MacroNS => WhereToResolve :: DeriveHelpers ,
898+ }
870899 WhereToResolve :: Module ( module) => {
871900 match self . hygienic_lexical_parent ( module, & mut ident. span ) {
872901 Some ( parent_module) => WhereToResolve :: Module ( parent_module) ,
@@ -899,30 +928,43 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
899928
900929 // The first found solution was the only one, return it.
901930 if let Some ( ( binding, flags) ) = innermost_result {
902- if is_import && !self . session . features_untracked ( ) . uniform_paths {
903- // We get to here only if there's no ambiguity, in ambiguous cases an error will
904- // be reported anyway, so there's no reason to report an additional feature error.
905- // The `binding` can actually be introduced by something other than `--extern`,
906- // but its `Def` should coincide with a crate passed with `--extern`
907- // (otherwise there would be ambiguity) and we can skip feature error in this case.
908- if ns != TypeNS || !use_prelude ||
909- self . extern_prelude_get ( ident, true ) . is_none ( ) {
910- let msg = "imports can only refer to extern crate names \
911- passed with `--extern` on stable channel";
912- let mut err = feature_err ( & self . session . parse_sess , "uniform_paths" ,
913- ident. span , GateIssue :: Language , msg) ;
914-
915- let what = self . binding_description ( binding, ident,
916- flags. contains ( Flags :: MISC_FROM_PRELUDE ) ) ;
917- let note_msg = format ! ( "this import refers to {what}" , what = what) ;
918- if binding. span . is_dummy ( ) {
919- err. note ( & note_msg) ;
920- } else {
921- err. span_note ( binding. span , & note_msg) ;
922- err. span_label ( binding. span , "not an extern crate passed with `--extern`" ) ;
931+ // We get to here only if there's no ambiguity, in ambiguous cases an error will
932+ // be reported anyway, so there's no reason to report an additional feature error.
933+ // The `binding` can actually be introduced by something other than `--extern`,
934+ // but its `Def` should coincide with a crate passed with `--extern`
935+ // (otherwise there would be ambiguity) and we can skip feature error in this case.
936+ ' ok: {
937+ if !is_import || self . session . features_untracked ( ) . uniform_paths {
938+ break ' ok;
939+ }
940+ if ns == TypeNS && use_prelude && self . extern_prelude_get ( ident, true ) . is_some ( ) {
941+ break ' ok;
942+ }
943+ if rust_2015 {
944+ let root_ident = Ident :: new ( keywords:: CrateRoot . name ( ) , orig_ident. span ) ;
945+ let root_module = self . resolve_crate_root ( root_ident) ;
946+ if self . resolve_ident_in_module_ext ( ModuleOrUniformRoot :: Module ( root_module) ,
947+ orig_ident, ns, None , false , path_span)
948+ . is_ok ( ) {
949+ break ' ok;
923950 }
924- err. emit ( ) ;
925951 }
952+
953+ let msg = "imports can only refer to extern crate names \
954+ passed with `--extern` on stable channel";
955+ let mut err = feature_err ( & self . session . parse_sess , "uniform_paths" ,
956+ ident. span , GateIssue :: Language , msg) ;
957+
958+ let what = self . binding_description ( binding, ident,
959+ flags. contains ( Flags :: MISC_FROM_PRELUDE ) ) ;
960+ let note_msg = format ! ( "this import refers to {what}" , what = what) ;
961+ if binding. span . is_dummy ( ) {
962+ err. note ( & note_msg) ;
963+ } else {
964+ err. span_note ( binding. span , & note_msg) ;
965+ err. span_label ( binding. span , "not an extern crate passed with `--extern`" ) ;
966+ }
967+ err. emit ( ) ;
926968 }
927969
928970 return Ok ( binding) ;
0 commit comments