@@ -630,15 +630,16 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
630
630
self . finalize_resolutions_in ( module) ;
631
631
}
632
632
633
- # [ derive ( Default ) ]
634
- struct UniformPathsCanaryResult < ' a > {
633
+ struct UniformPathsCanaryResults < ' a > {
634
+ name : Name ,
635
635
module_scope : Option < & ' a NameBinding < ' a > > ,
636
636
block_scopes : Vec < & ' a NameBinding < ' a > > ,
637
637
}
638
+
638
639
// Collect all tripped `uniform_paths` canaries separately.
639
640
let mut uniform_paths_canaries: BTreeMap <
640
- ( Span , NodeId ) ,
641
- ( Name , PerNS < UniformPathsCanaryResult > ) ,
641
+ ( Span , NodeId , Namespace ) ,
642
+ UniformPathsCanaryResults ,
642
643
> = BTreeMap :: new ( ) ;
643
644
644
645
let mut errors = false ;
@@ -665,21 +666,25 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
665
666
import. module_path . len ( ) > 0 &&
666
667
import. module_path [ 0 ] . name == keywords:: SelfValue . name ( ) ;
667
668
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
-
675
669
self . per_ns ( |_, ns| {
676
670
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
+
677
682
if has_explicit_self {
678
683
// 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) ;
681
686
} else {
682
- canary_results[ ns ] . block_scopes . push ( result) ;
687
+ canary_results. block_scopes . push ( result) ;
683
688
}
684
689
}
685
690
} ) ;
@@ -720,77 +725,76 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
720
725
}
721
726
722
727
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 ;
740
745
}
741
746
}
747
+ }
742
748
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
+ } ;
749
755
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
+ }
758
763
759
- errors = true ;
764
+ errors = true ;
760
765
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 " ) ;
785
777
}
786
- err . help ( & format ! ( "write {} explicitly instead ", suggestion_choices ) ) ;
778
+ write ! ( suggestion_choices , "`self::{}` ", name ) ;
787
779
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) ) ;
789
782
} 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) ) ;
791
785
}
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 ( ) ;
794
798
}
795
799
796
800
if !error_vec. is_empty ( ) {
0 commit comments