@@ -526,7 +526,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
526
526
// `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
527
527
crate fn early_resolve_ident_in_lexical_scope (
528
528
& mut self ,
529
- mut ident : Ident ,
529
+ orig_ident : Ident ,
530
530
ns : Namespace ,
531
531
macro_kind : Option < MacroKind > ,
532
532
is_import : bool ,
@@ -582,6 +582,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
582
582
enum WhereToResolve < ' a > {
583
583
DeriveHelpers ,
584
584
MacroRules ( LegacyScope < ' a > ) ,
585
+ CrateRoot ,
585
586
Module ( Module < ' a > ) ,
586
587
MacroUsePrelude ,
587
588
BuiltinMacros ,
@@ -605,8 +606,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
605
606
606
607
assert ! ( force || !record_used) ; // `record_used` implies `force`
607
608
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 ( ) ;
610
611
611
612
// Make sure `self`, `super` etc produce an error when passed to here.
612
613
if ident. is_path_segment_keyword ( ) {
@@ -627,10 +628,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
627
628
let mut innermost_result: Option < ( & NameBinding , Flags ) > = None ;
628
629
629
630
// 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 ,
634
635
} ;
635
636
let mut use_prelude = !parent_scope. module . no_implicit_prelude ;
636
637
let mut determinacy = Determinacy :: Determined ;
@@ -668,6 +669,26 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
668
669
Err ( Determinacy :: Undetermined ) ,
669
670
_ => Err ( Determinacy :: Determined ) ,
670
671
}
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
+ }
671
692
WhereToResolve :: Module ( module) => {
672
693
let orig_current_module = mem:: replace ( & mut self . current_module , module) ;
673
694
let binding = self . resolve_ident_in_module_unadjusted_ext (
@@ -816,7 +837,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
816
837
} else if innermost_flags. contains ( Flags :: MACRO_RULES ) &&
817
838
flags. contains ( Flags :: MODULE ) &&
818
839
!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) {
820
845
Some ( AmbiguityKind :: LegacyVsModern )
821
846
} else if innermost_binding. is_glob_import ( ) {
822
847
Some ( AmbiguityKind :: GlobVsOuter )
@@ -867,6 +892,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
867
892
LegacyScope :: Empty => WhereToResolve :: Module ( parent_scope. module ) ,
868
893
LegacyScope :: Uninitialized => unreachable ! ( ) ,
869
894
}
895
+ WhereToResolve :: CrateRoot => match ns {
896
+ TypeNS | ValueNS => WhereToResolve :: Module ( parent_scope. module ) ,
897
+ MacroNS => WhereToResolve :: DeriveHelpers ,
898
+ }
870
899
WhereToResolve :: Module ( module) => {
871
900
match self . hygienic_lexical_parent ( module, & mut ident. span ) {
872
901
Some ( parent_module) => WhereToResolve :: Module ( parent_module) ,
@@ -899,30 +928,43 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
899
928
900
929
// The first found solution was the only one, return it.
901
930
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;
923
950
}
924
- err. emit ( ) ;
925
951
}
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 ( ) ;
926
968
}
927
969
928
970
return Ok ( binding) ;
0 commit comments