@@ -630,15 +630,16 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
630630 self . finalize_resolutions_in ( module) ;
631631 }
632632
633- # [ derive ( Default ) ]
634- struct UniformPathsCanaryResult < ' a > {
633+ struct UniformPathsCanaryResults < ' a > {
634+ name : Name ,
635635 module_scope : Option < & ' a NameBinding < ' a > > ,
636636 block_scopes : Vec < & ' a NameBinding < ' a > > ,
637637 }
638+
638639 // Collect all tripped `uniform_paths` canaries separately.
639640 let mut uniform_paths_canaries: BTreeMap <
640- ( Span , NodeId ) ,
641- ( Name , PerNS < UniformPathsCanaryResult > ) ,
641+ ( Span , NodeId , Namespace ) ,
642+ UniformPathsCanaryResults ,
642643 > = BTreeMap :: new ( ) ;
643644
644645 let mut errors = false ;
@@ -665,21 +666,25 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
665666 import. module_path . len ( ) > 0 &&
666667 import. module_path [ 0 ] . name == keywords:: SelfValue . name ( ) ;
667668
668- let ( prev_name, canary_results) =
669- uniform_paths_canaries. entry ( ( import. span , import. id ) )
670- . or_insert ( ( name, PerNS :: default ( ) ) ) ;
671-
672- // All the canaries with the same `id` should have the same `name`.
673- assert_eq ! ( * prev_name, name) ;
674-
675669 self . per_ns ( |_, ns| {
676670 if let Some ( result) = result[ ns] . get ( ) . ok ( ) {
671+ let canary_results =
672+ uniform_paths_canaries. entry ( ( import. span , import. id , ns) )
673+ . or_insert ( UniformPathsCanaryResults {
674+ name,
675+ module_scope : None ,
676+ block_scopes : vec ! [ ] ,
677+ } ) ;
678+
679+ // All the canaries with the same `id` should have the same `name`.
680+ assert_eq ! ( canary_results. name, name) ;
681+
677682 if has_explicit_self {
678683 // There should only be one `self::x` (module-scoped) canary.
679- assert ! ( canary_results[ ns ] . module_scope. is_none( ) ) ;
680- canary_results[ ns ] . module_scope = Some ( result) ;
684+ assert ! ( canary_results. module_scope. is_none( ) ) ;
685+ canary_results. module_scope = Some ( result) ;
681686 } else {
682- canary_results[ ns ] . block_scopes . push ( result) ;
687+ canary_results. block_scopes . push ( result) ;
683688 }
684689 }
685690 } ) ;
@@ -720,77 +725,76 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
720725 }
721726
722727 let uniform_paths_feature = self . session . features_untracked ( ) . uniform_paths ;
723- for ( ( span, _) , ( name , results) ) in uniform_paths_canaries {
724- self . per_ns ( |this , ns| {
725- let external_crate = if ns == TypeNS && this . extern_prelude . contains ( & name) {
726- let crate_id =
727- this . crate_loader . process_path_extern ( name, span) ;
728- Some ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } )
729- } else {
730- None
731- } ;
732- let result_filter = | result : & & NameBinding | {
733- // Ignore canaries that resolve to an import of the same crate.
734- // That is, we allow `use crate_name; use crate_name::foo;` .
735- if let Some ( def_id ) = external_crate {
736- if let Some ( module ) = result . module ( ) {
737- if module. normal_ancestor_id == def_id {
738- return false ;
739- }
728+ for ( ( span, _, ns ) , results) in uniform_paths_canaries {
729+ let name = results . name ;
730+ let external_crate = if ns == TypeNS && self . extern_prelude . contains ( & name) {
731+ let crate_id =
732+ self . crate_loader . process_path_extern ( name, span) ;
733+ Some ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } )
734+ } else {
735+ None
736+ } ;
737+
738+ let result_filter = | result : & & NameBinding | {
739+ // Ignore canaries that resolve to an import of the same crate .
740+ // That is, we allow `use crate_name; use crate_name::foo;`.
741+ if let Some ( def_id ) = external_crate {
742+ if let Some ( module) = result . module ( ) {
743+ if module . normal_ancestor_id == def_id {
744+ return false ;
740745 }
741746 }
747+ }
742748
743- true
744- } ;
745- let module_scope = results[ ns ] . module_scope . filter ( result_filter) ;
746- let block_scopes = || {
747- results[ ns ] . block_scopes . iter ( ) . cloned ( ) . filter ( result_filter)
748- } ;
749+ true
750+ } ;
751+ let module_scope = results. module_scope . filter ( result_filter) ;
752+ let block_scopes = || {
753+ results. block_scopes . iter ( ) . cloned ( ) . filter ( result_filter)
754+ } ;
749755
750- // An ambiguity requires more than one possible resolution.
751- let possible_resultions =
752- ( external_crate. is_some ( ) as usize ) +
753- ( module_scope. is_some ( ) as usize ) +
754- ( block_scopes ( ) . next ( ) . is_some ( ) as usize ) ;
755- if possible_resultions <= 1 {
756- return ;
757- }
756+ // An ambiguity requires more than one possible resolution.
757+ let possible_resultions =
758+ ( external_crate. is_some ( ) as usize ) +
759+ module_scope. into_iter ( ) . chain ( block_scopes ( ) ) . count ( ) ;
760+ if possible_resultions <= 1 {
761+ return ;
762+ }
758763
759- errors = true ;
764+ errors = true ;
760765
761- let msg = format ! ( "`{}` import is ambiguous" , name) ;
762- let mut err = this. session . struct_span_err ( span, & msg) ;
763- let mut suggestion_choices = String :: new ( ) ;
764- if external_crate. is_some ( ) {
765- write ! ( suggestion_choices, "`::{}`" , name) ;
766- err. span_label ( span,
767- format ! ( "can refer to external crate `::{}`" , name) ) ;
768- }
769- if let Some ( result) = module_scope {
770- if !suggestion_choices. is_empty ( ) {
771- suggestion_choices. push_str ( " or " ) ;
772- }
773- write ! ( suggestion_choices, "`self::{}`" , name) ;
774- if uniform_paths_feature {
775- err. span_label ( result. span ,
776- format ! ( "can refer to `self::{}`" , name) ) ;
777- } else {
778- err. span_label ( result. span ,
779- format ! ( "may refer to `self::{}` in the future" , name) ) ;
780- }
781- }
782- for result in block_scopes ( ) {
783- err. span_label ( result. span ,
784- format ! ( "shadowed by block-scoped `{}`" , name) ) ;
766+ let msg = format ! ( "`{}` import is ambiguous" , name) ;
767+ let mut err = self . session . struct_span_err ( span, & msg) ;
768+ let mut suggestion_choices = String :: new ( ) ;
769+ if external_crate. is_some ( ) {
770+ write ! ( suggestion_choices, "`::{}`" , name) ;
771+ err. span_label ( span,
772+ format ! ( "can refer to external crate `::{}`" , name) ) ;
773+ }
774+ if let Some ( result) = module_scope {
775+ if !suggestion_choices. is_empty ( ) {
776+ suggestion_choices. push_str ( " or " ) ;
785777 }
786- err . help ( & format ! ( "write {} explicitly instead ", suggestion_choices ) ) ;
778+ write ! ( suggestion_choices , "`self::{}` ", name ) ;
787779 if uniform_paths_feature {
788- err. note ( "relative `use` paths enabled by `#![feature(uniform_paths)]`" ) ;
780+ err. span_label ( result. span ,
781+ format ! ( "can refer to `self::{}`" , name) ) ;
789782 } else {
790- err. note ( "in the future, `#![feature(uniform_paths)]` may become the default" ) ;
783+ err. span_label ( result. span ,
784+ format ! ( "may refer to `self::{}` in the future" , name) ) ;
791785 }
792- err. emit ( ) ;
793- } ) ;
786+ }
787+ for result in block_scopes ( ) {
788+ err. span_label ( result. span ,
789+ format ! ( "shadowed by block-scoped `{}`" , name) ) ;
790+ }
791+ err. help ( & format ! ( "write {} explicitly instead" , suggestion_choices) ) ;
792+ if uniform_paths_feature {
793+ err. note ( "relative `use` paths enabled by `#![feature(uniform_paths)]`" ) ;
794+ } else {
795+ err. note ( "in the future, `#![feature(uniform_paths)]` may become the default" ) ;
796+ }
797+ err. emit ( ) ;
794798 }
795799
796800 if !error_vec. is_empty ( ) {
0 commit comments