@@ -620,9 +620,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
620620 }
621621
622622 #[ derive( Default ) ]
623- struct UniformPathsCanaryResult {
624- module_scope : Option < Span > ,
625- block_scopes : Vec < Span > ,
623+ struct UniformPathsCanaryResult < ' a > {
624+ module_scope : Option < & ' a NameBinding < ' a > > ,
625+ block_scopes : Vec < & ' a NameBinding < ' a > > ,
626626 }
627627 // Collect all tripped `uniform_paths` canaries separately.
628628 let mut uniform_paths_canaries: BTreeMap <
@@ -661,20 +661,12 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
661661
662662 self . per_ns ( |_, ns| {
663663 if let Some ( result) = result[ ns] . get ( ) . ok ( ) {
664- if let NameBindingKind :: Import { directive, .. } = result. kind {
665- // Skip canaries that resolve to the import itself.
666- // These come from `use crate_name;`, which isn't really
667- // ambiguous, as the import can't actually shadow itself.
668- if directive. id == import. id {
669- return ;
670- }
671- }
672664 if has_explicit_self {
673665 // There should only be one `self::x` (module-scoped) canary.
674- assert_eq ! ( canary_results[ ns] . module_scope, None ) ;
675- canary_results[ ns] . module_scope = Some ( result. span ) ;
666+ assert ! ( canary_results[ ns] . module_scope. is_none ( ) ) ;
667+ canary_results[ ns] . module_scope = Some ( result) ;
676668 } else {
677- canary_results[ ns] . block_scopes . push ( result. span ) ;
669+ canary_results[ ns] . block_scopes . push ( result) ;
678670 }
679671 }
680672 } ) ;
@@ -708,16 +700,36 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
708700 let uniform_paths_feature = self . session . features_untracked ( ) . uniform_paths ;
709701 for ( ( span, _) , ( name, results) ) in uniform_paths_canaries {
710702 self . per_ns ( |this, ns| {
711- let results = & results[ ns] ;
703+ let external_crate = if ns == TypeNS && this. extern_prelude . contains ( & name) {
704+ let crate_id =
705+ this. crate_loader . process_path_extern ( name, span) ;
706+ Some ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } )
707+ } else {
708+ None
709+ } ;
710+ let result_filter = |result : & & NameBinding | {
711+ // Ignore canaries that resolve to an import of the same crate.
712+ // That is, we allow `use crate_name; use crate_name::foo;`.
713+ if let Some ( def_id) = external_crate {
714+ if let Some ( module) = result. module ( ) {
715+ if module. normal_ancestor_id == def_id {
716+ return false ;
717+ }
718+ }
719+ }
712720
713- let has_external_crate =
714- ns == TypeNS && this. extern_prelude . contains ( & name) ;
721+ true
722+ } ;
723+ let module_scope = results[ ns] . module_scope . filter ( result_filter) ;
724+ let block_scopes = || {
725+ results[ ns] . block_scopes . iter ( ) . cloned ( ) . filter ( result_filter)
726+ } ;
715727
716728 // An ambiguity requires more than one possible resolution.
717729 let possible_resultions =
718- ( has_external_crate as usize ) +
719- ( results . module_scope . is_some ( ) as usize ) +
720- ( !results . block_scopes . is_empty ( ) as usize ) ;
730+ ( external_crate . is_some ( ) as usize ) +
731+ ( module_scope. is_some ( ) as usize ) +
732+ ( block_scopes ( ) . next ( ) . is_some ( ) as usize ) ;
721733 if possible_resultions <= 1 {
722734 return ;
723735 }
@@ -727,26 +739,26 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
727739 let msg = format ! ( "`{}` import is ambiguous" , name) ;
728740 let mut err = this. session . struct_span_err ( span, & msg) ;
729741 let mut suggestion_choices = String :: new ( ) ;
730- if has_external_crate {
742+ if external_crate . is_some ( ) {
731743 write ! ( suggestion_choices, "`::{}`" , name) ;
732744 err. span_label ( span,
733745 format ! ( "can refer to external crate `::{}`" , name) ) ;
734746 }
735- if let Some ( span ) = results . module_scope {
747+ if let Some ( result ) = module_scope {
736748 if !suggestion_choices. is_empty ( ) {
737749 suggestion_choices. push_str ( " or " ) ;
738750 }
739751 write ! ( suggestion_choices, "`self::{}`" , name) ;
740752 if uniform_paths_feature {
741- err. span_label ( span,
753+ err. span_label ( result . span ,
742754 format ! ( "can refer to `self::{}`" , name) ) ;
743755 } else {
744- err. span_label ( span,
756+ err. span_label ( result . span ,
745757 format ! ( "may refer to `self::{}` in the future" , name) ) ;
746758 }
747759 }
748- for & span in & results . block_scopes {
749- err. span_label ( span,
760+ for result in block_scopes ( ) {
761+ err. span_label ( result . span ,
750762 format ! ( "shadowed by block-scoped `{}`" , name) ) ;
751763 }
752764 err. help ( & format ! ( "write {} explicitly instead" , suggestion_choices) ) ;
0 commit comments