@@ -1111,7 +1111,8 @@ pub struct Resolver<'a> {
1111
1111
1112
1112
prelude : Option < Module < ' a > > ,
1113
1113
1114
- trait_item_map : FxHashMap < ( DefId , Name , Namespace ) , ( Def , bool /* has self */ ) > ,
1114
+ // n.b. This is used only for better diagnostics, not name resolution itself.
1115
+ has_self : FxHashSet < DefId > ,
1115
1116
1116
1117
// Names of fields of an item `DefId` accessible with dot syntax.
1117
1118
// Used for hints during error reporting.
@@ -1134,7 +1135,7 @@ pub struct Resolver<'a> {
1134
1135
label_ribs : Vec < Rib < ' a > > ,
1135
1136
1136
1137
// The trait that the current context can refer to.
1137
- current_trait_ref : Option < ( DefId , TraitRef ) > ,
1138
+ current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
1138
1139
1139
1140
// The current self type if inside an impl (used for better errors).
1140
1141
current_self_type : Option < Ty > ,
@@ -1337,7 +1338,7 @@ impl<'a> Resolver<'a> {
1337
1338
graph_root : graph_root,
1338
1339
prelude : None ,
1339
1340
1340
- trait_item_map : FxHashMap ( ) ,
1341
+ has_self : FxHashSet ( ) ,
1341
1342
field_names : FxHashMap ( ) ,
1342
1343
1343
1344
determined_imports : Vec :: new ( ) ,
@@ -1750,22 +1751,21 @@ impl<'a> Resolver<'a> {
1750
1751
let mut function_type_rib = Rib :: new ( rib_kind) ;
1751
1752
let mut seen_bindings = FxHashMap ( ) ;
1752
1753
for type_parameter in & generics. ty_params {
1753
- let name = type_parameter. ident . name ;
1754
+ let ident = type_parameter. ident . unhygienize ( ) ;
1754
1755
debug ! ( "with_type_parameter_rib: {}" , type_parameter. id) ;
1755
1756
1756
- if seen_bindings. contains_key ( & name) {
1757
- let span = seen_bindings. get ( & name) . unwrap ( ) ;
1758
- resolve_error ( self ,
1759
- type_parameter. span ,
1760
- ResolutionError :: NameAlreadyUsedInTypeParameterList ( name,
1761
- span) ) ;
1757
+ if seen_bindings. contains_key ( & ident) {
1758
+ let span = seen_bindings. get ( & ident) . unwrap ( ) ;
1759
+ let err =
1760
+ ResolutionError :: NameAlreadyUsedInTypeParameterList ( ident. name , span) ;
1761
+ resolve_error ( self , type_parameter. span , err) ;
1762
1762
}
1763
- seen_bindings. entry ( name ) . or_insert ( type_parameter. span ) ;
1763
+ seen_bindings. entry ( ident ) . or_insert ( type_parameter. span ) ;
1764
1764
1765
1765
// plain insert (no renaming)
1766
1766
let def_id = self . definitions . local_def_id ( type_parameter. id ) ;
1767
1767
let def = Def :: TyParam ( def_id) ;
1768
- function_type_rib. bindings . insert ( Ident :: with_empty_ctxt ( name ) , def) ;
1768
+ function_type_rib. bindings . insert ( ident , def) ;
1769
1769
self . record_def ( type_parameter. id , PathResolution :: new ( def) ) ;
1770
1770
}
1771
1771
self . ribs [ TypeNS ] . push ( function_type_rib) ;
@@ -1825,11 +1825,20 @@ impl<'a> Resolver<'a> {
1825
1825
let mut new_val = None ;
1826
1826
let mut new_id = None ;
1827
1827
if let Some ( trait_ref) = opt_trait_ref {
1828
- let def = self . smart_resolve_path ( trait_ref. ref_id , None ,
1829
- & trait_ref. path , PathSource :: Trait ) . base_def ( ) ;
1828
+ let path: Vec < _ > = trait_ref. path . segments . iter ( ) . map ( |seg| seg. identifier ) . collect ( ) ;
1829
+ let def = self . smart_resolve_path_fragment ( trait_ref. ref_id ,
1830
+ None ,
1831
+ & path,
1832
+ trait_ref. path . span ,
1833
+ trait_ref. path . segments . last ( ) . unwrap ( ) . span ,
1834
+ PathSource :: Trait )
1835
+ . base_def ( ) ;
1830
1836
if def != Def :: Err {
1831
- new_val = Some ( ( def. def_id ( ) , trait_ref. clone ( ) ) ) ;
1832
1837
new_id = Some ( def. def_id ( ) ) ;
1838
+ let span = trait_ref. path . span ;
1839
+ if let PathResult :: Module ( module) = self . resolve_path ( & path, None , false , span) {
1840
+ new_val = Some ( ( module, trait_ref. clone ( ) ) ) ;
1841
+ }
1833
1842
}
1834
1843
}
1835
1844
let original_trait_ref = replace ( & mut self . current_trait_ref , new_val) ;
@@ -1880,7 +1889,7 @@ impl<'a> Resolver<'a> {
1880
1889
ImplItemKind :: Const ( ..) => {
1881
1890
// If this is a trait impl, ensure the const
1882
1891
// exists in trait
1883
- this. check_trait_item ( impl_item. ident . name ,
1892
+ this. check_trait_item ( impl_item. ident ,
1884
1893
ValueNS ,
1885
1894
impl_item. span ,
1886
1895
|n, s| ResolutionError :: ConstNotMemberOfTrait ( n, s) ) ;
@@ -1889,7 +1898,7 @@ impl<'a> Resolver<'a> {
1889
1898
ImplItemKind :: Method ( ref sig, _) => {
1890
1899
// If this is a trait impl, ensure the method
1891
1900
// exists in trait
1892
- this. check_trait_item ( impl_item. ident . name ,
1901
+ this. check_trait_item ( impl_item. ident ,
1893
1902
ValueNS ,
1894
1903
impl_item. span ,
1895
1904
|n, s| ResolutionError :: MethodNotMemberOfTrait ( n, s) ) ;
@@ -1906,7 +1915,7 @@ impl<'a> Resolver<'a> {
1906
1915
ImplItemKind :: Type ( ref ty) => {
1907
1916
// If this is a trait impl, ensure the type
1908
1917
// exists in trait
1909
- this. check_trait_item ( impl_item. ident . name ,
1918
+ this. check_trait_item ( impl_item. ident ,
1910
1919
TypeNS ,
1911
1920
impl_item. span ,
1912
1921
|n, s| ResolutionError :: TypeNotMemberOfTrait ( n, s) ) ;
@@ -1924,15 +1933,15 @@ impl<'a> Resolver<'a> {
1924
1933
} ) ;
1925
1934
}
1926
1935
1927
- fn check_trait_item < F > ( & self , name : Name , ns : Namespace , span : Span , err : F )
1936
+ fn check_trait_item < F > ( & mut self , ident : Ident , ns : Namespace , span : Span , err : F )
1928
1937
where F : FnOnce ( Name , & str ) -> ResolutionError
1929
1938
{
1930
1939
// If there is a TraitRef in scope for an impl, then the method must be in the
1931
1940
// trait.
1932
- if let Some ( ( did , ref trait_ref ) ) = self . current_trait_ref {
1933
- if ! self . trait_item_map . contains_key ( & ( did , name , ns) ) {
1934
- let path_str = path_names_to_string ( & trait_ref . path ) ;
1935
- resolve_error ( self , span, err ( name, & path_str ) ) ;
1941
+ if let Some ( ( module , _ ) ) = self . current_trait_ref {
1942
+ if self . resolve_ident_in_module ( module , ident , ns, false , false , span ) . is_err ( ) {
1943
+ let path = & self . current_trait_ref . as_ref ( ) . unwrap ( ) . 1 . path ;
1944
+ resolve_error ( self , span, err ( ident . name , & path_names_to_string ( path ) ) ) ;
1936
1945
}
1937
1946
}
1938
1947
}
@@ -2302,15 +2311,16 @@ impl<'a> Resolver<'a> {
2302
2311
}
2303
2312
2304
2313
// Try to lookup the name in more relaxed fashion for better error reporting.
2305
- let name = path. last ( ) . unwrap ( ) . name ;
2306
- let candidates = this. lookup_import_candidates ( name, ns, is_expected) ;
2314
+ let ident = * path. last ( ) . unwrap ( ) ;
2315
+ let candidates = this. lookup_import_candidates ( ident . name , ns, is_expected) ;
2307
2316
if !candidates. is_empty ( ) {
2308
2317
let mut module_span = this. current_module . span ;
2309
2318
module_span. hi = module_span. lo ;
2310
2319
// Report import candidates as help and proceed searching for labels.
2311
2320
show_candidates ( & mut err, module_span, & candidates, def. is_some ( ) ) ;
2312
2321
} else if is_expected ( Def :: Enum ( DefId :: local ( CRATE_DEF_INDEX ) ) ) {
2313
- let enum_candidates = this. lookup_import_candidates ( name, ns, is_enum_variant) ;
2322
+ let enum_candidates =
2323
+ this. lookup_import_candidates ( ident. name , ns, is_enum_variant) ;
2314
2324
let mut enum_candidates = enum_candidates. iter ( )
2315
2325
. map ( |suggestion| import_candidate_to_paths ( & suggestion) ) . collect :: < Vec < _ > > ( ) ;
2316
2326
enum_candidates. sort ( ) ;
@@ -2326,7 +2336,7 @@ impl<'a> Resolver<'a> {
2326
2336
}
2327
2337
}
2328
2338
if path. len ( ) == 1 && this. self_type_is_available ( span) {
2329
- if let Some ( candidate) = this. lookup_assoc_candidate ( name , ns, is_expected) {
2339
+ if let Some ( candidate) = this. lookup_assoc_candidate ( ident , ns, is_expected) {
2330
2340
let self_is_available = this. self_value_is_available ( path[ 0 ] . ctxt , span) ;
2331
2341
match candidate {
2332
2342
AssocSuggestion :: Field => {
@@ -2440,7 +2450,7 @@ impl<'a> Resolver<'a> {
2440
2450
// or `<T>::A::B`. If `B` should be resolved in value namespace then
2441
2451
// it needs to be added to the trait map.
2442
2452
if ns == ValueNS {
2443
- let item_name = path. last ( ) . unwrap ( ) . name ;
2453
+ let item_name = * path. last ( ) . unwrap ( ) ;
2444
2454
let traits = self . get_traits_containing_item ( item_name, ns) ;
2445
2455
self . trait_map . insert ( id, traits) ;
2446
2456
}
@@ -2819,7 +2829,7 @@ impl<'a> Resolver<'a> {
2819
2829
}
2820
2830
2821
2831
fn lookup_assoc_candidate < FilterFn > ( & mut self ,
2822
- name : Name ,
2832
+ ident : Ident ,
2823
2833
ns : Namespace ,
2824
2834
filter_fn : FilterFn )
2825
2835
-> Option < AssocSuggestion >
@@ -2845,7 +2855,7 @@ impl<'a> Resolver<'a> {
2845
2855
Def :: Struct ( did) | Def :: Union ( did)
2846
2856
if resolution. unresolved_segments ( ) == 0 => {
2847
2857
if let Some ( field_names) = self . field_names . get ( & did) {
2848
- if field_names. iter ( ) . any ( |& field_name| name == field_name) {
2858
+ if field_names. iter ( ) . any ( |& field_name| ident . name == field_name) {
2849
2859
return Some ( AssocSuggestion :: Field ) ;
2850
2860
}
2851
2861
}
@@ -2857,10 +2867,12 @@ impl<'a> Resolver<'a> {
2857
2867
}
2858
2868
2859
2869
// Look for associated items in the current trait.
2860
- if let Some ( ( trait_did, _) ) = self . current_trait_ref {
2861
- if let Some ( & ( def, has_self) ) = self . trait_item_map . get ( & ( trait_did, name, ns) ) {
2870
+ if let Some ( ( module, _) ) = self . current_trait_ref {
2871
+ if let Ok ( binding) =
2872
+ self . resolve_ident_in_module ( module, ident, ns, false , false , module. span ) {
2873
+ let def = binding. def ( ) ;
2862
2874
if filter_fn ( def) {
2863
- return Some ( if has_self {
2875
+ return Some ( if self . has_self . contains ( & def . def_id ( ) ) {
2864
2876
AssocSuggestion :: MethodWithSelf
2865
2877
} else {
2866
2878
AssocSuggestion :: AssocItem
@@ -3081,13 +3093,13 @@ impl<'a> Resolver<'a> {
3081
3093
// field, we need to add any trait methods we find that match
3082
3094
// the field name so that we can do some nice error reporting
3083
3095
// later on in typeck.
3084
- let traits = self . get_traits_containing_item ( name. node . name , ValueNS ) ;
3096
+ let traits = self . get_traits_containing_item ( name. node , ValueNS ) ;
3085
3097
self . trait_map . insert ( expr. id , traits) ;
3086
3098
}
3087
3099
ExprKind :: MethodCall ( name, ..) => {
3088
3100
debug ! ( "(recording candidate traits for expr) recording traits for {}" ,
3089
3101
expr. id) ;
3090
- let traits = self . get_traits_containing_item ( name. node . name , ValueNS ) ;
3102
+ let traits = self . get_traits_containing_item ( name. node , ValueNS ) ;
3091
3103
self . trait_map . insert ( expr. id , traits) ;
3092
3104
}
3093
3105
_ => {
@@ -3096,20 +3108,21 @@ impl<'a> Resolver<'a> {
3096
3108
}
3097
3109
}
3098
3110
3099
- fn get_traits_containing_item ( & mut self , name : Name , ns : Namespace ) -> Vec < TraitCandidate > {
3100
- debug ! ( "(getting traits containing item) looking for '{}'" , name) ;
3111
+ fn get_traits_containing_item ( & mut self , ident : Ident , ns : Namespace ) -> Vec < TraitCandidate > {
3112
+ debug ! ( "(getting traits containing item) looking for '{}'" , ident . name) ;
3101
3113
3102
3114
let mut found_traits = Vec :: new ( ) ;
3103
3115
// Look for the current trait.
3104
- if let Some ( ( trait_def_id, _) ) = self . current_trait_ref {
3105
- if self . trait_item_map . contains_key ( & ( trait_def_id, name, ns) ) {
3106
- found_traits. push ( TraitCandidate { def_id : trait_def_id, import_id : None } ) ;
3116
+ if let Some ( ( module, _) ) = self . current_trait_ref {
3117
+ if self . resolve_ident_in_module ( module, ident, ns, false , false , module. span ) . is_ok ( ) {
3118
+ let def_id = module. def_id ( ) . unwrap ( ) ;
3119
+ found_traits. push ( TraitCandidate { def_id : def_id, import_id : None } ) ;
3107
3120
}
3108
3121
}
3109
3122
3110
3123
let mut search_module = self . current_module ;
3111
3124
loop {
3112
- self . get_traits_in_module_containing_item ( name , ns, search_module, & mut found_traits) ;
3125
+ self . get_traits_in_module_containing_item ( ident , ns, search_module, & mut found_traits) ;
3113
3126
match search_module. kind {
3114
3127
ModuleKind :: Block ( ..) => search_module = search_module. parent . unwrap ( ) ,
3115
3128
_ => break ,
@@ -3118,17 +3131,17 @@ impl<'a> Resolver<'a> {
3118
3131
3119
3132
if let Some ( prelude) = self . prelude {
3120
3133
if !search_module. no_implicit_prelude {
3121
- self . get_traits_in_module_containing_item ( name , ns, prelude, & mut found_traits) ;
3134
+ self . get_traits_in_module_containing_item ( ident , ns, prelude, & mut found_traits) ;
3122
3135
}
3123
3136
}
3124
3137
3125
3138
found_traits
3126
3139
}
3127
3140
3128
3141
fn get_traits_in_module_containing_item ( & mut self ,
3129
- name : Name ,
3142
+ ident : Ident ,
3130
3143
ns : Namespace ,
3131
- module : Module ,
3144
+ module : Module < ' a > ,
3132
3145
found_traits : & mut Vec < TraitCandidate > ) {
3133
3146
let mut traits = module. traits . borrow_mut ( ) ;
3134
3147
if traits. is_none ( ) {
@@ -3143,8 +3156,8 @@ impl<'a> Resolver<'a> {
3143
3156
}
3144
3157
3145
3158
for & ( trait_name, binding) in traits. as_ref ( ) . unwrap ( ) . iter ( ) {
3146
- let trait_def_id = binding. def ( ) . def_id ( ) ;
3147
- if self . trait_item_map . contains_key ( & ( trait_def_id , name , ns) ) {
3159
+ let module = binding. module ( ) . unwrap ( ) ;
3160
+ if self . resolve_ident_in_module ( module , ident , ns, false , false , module . span ) . is_ok ( ) {
3148
3161
let import_id = match binding. kind {
3149
3162
NameBindingKind :: Import { directive, .. } => {
3150
3163
self . maybe_unused_trait_imports . insert ( directive. id ) ;
@@ -3153,6 +3166,7 @@ impl<'a> Resolver<'a> {
3153
3166
}
3154
3167
_ => None ,
3155
3168
} ;
3169
+ let trait_def_id = module. def_id ( ) . unwrap ( ) ;
3156
3170
found_traits. push ( TraitCandidate { def_id : trait_def_id, import_id : import_id } ) ;
3157
3171
}
3158
3172
}
0 commit comments