@@ -52,7 +52,7 @@ use syntax::ast::{CRATE_NODE_ID, Arm, IsAsync, BindingMode, Block, Crate, Expr,
52
52
use syntax:: ast:: { FnDecl , ForeignItem , ForeignItemKind , GenericParamKind , Generics } ;
53
53
use syntax:: ast:: { Item , ItemKind , ImplItem , ImplItemKind } ;
54
54
use syntax:: ast:: { Label , Local , Mutability , Pat , PatKind , Path } ;
55
- use syntax:: ast:: { QSelf , TraitItemKind , TraitRef , Ty , TyKind } ;
55
+ use syntax:: ast:: { QSelf , TraitItem , TraitItemKind , TraitRef , Ty , TyKind } ;
56
56
use syntax:: ptr:: P ;
57
57
use syntax:: { span_err, struct_span_err, unwrap_or, walk_list} ;
58
58
@@ -1053,6 +1053,7 @@ impl<'a, R> Rib<'a, R> {
1053
1053
/// This refers to the thing referred by a name. The difference between `Res` and `Item` is that
1054
1054
/// items are visible in their whole block, while `Res`es only from the place they are defined
1055
1055
/// forward.
1056
+ #[ derive( Debug ) ]
1056
1057
enum LexicalScopeBinding < ' a > {
1057
1058
Item ( & ' a NameBinding < ' a > ) ,
1058
1059
Res ( Res ) ,
@@ -1601,6 +1602,9 @@ pub struct Resolver<'a> {
1601
1602
/// The trait that the current context can refer to.
1602
1603
current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
1603
1604
1605
+ /// The current trait's associated types' ident, used for diagnostic suggestions.
1606
+ current_trait_assoc_types : Vec < Ident > ,
1607
+
1604
1608
/// The current self type if inside an impl (used for better errors).
1605
1609
current_self_type : Option < Ty > ,
1606
1610
@@ -1971,6 +1975,7 @@ impl<'a> Resolver<'a> {
1971
1975
label_ribs : Vec :: new ( ) ,
1972
1976
1973
1977
current_trait_ref : None ,
1978
+ current_trait_assoc_types : Vec :: new ( ) ,
1974
1979
current_self_type : None ,
1975
1980
current_self_item : None ,
1976
1981
last_import_segment : false ,
@@ -2579,32 +2584,36 @@ impl<'a> Resolver<'a> {
2579
2584
walk_list ! ( this, visit_param_bound, bounds) ;
2580
2585
2581
2586
for trait_item in trait_items {
2582
- let generic_params = HasGenericParams ( & trait_item. generics ,
2583
- AssocItemRibKind ) ;
2584
- this. with_generic_param_rib ( generic_params, |this| {
2585
- match trait_item. node {
2586
- TraitItemKind :: Const ( ref ty, ref default) => {
2587
- this. visit_ty ( ty) ;
2588
-
2589
- // Only impose the restrictions of
2590
- // ConstRibKind for an actual constant
2591
- // expression in a provided default.
2592
- if let Some ( ref expr) = * default{
2593
- this. with_constant_rib ( |this| {
2594
- this. visit_expr ( expr) ;
2595
- } ) ;
2587
+ this. with_trait_items ( trait_items, |this| {
2588
+ let generic_params = HasGenericParams (
2589
+ & trait_item. generics ,
2590
+ AssocItemRibKind ,
2591
+ ) ;
2592
+ this. with_generic_param_rib ( generic_params, |this| {
2593
+ match trait_item. node {
2594
+ TraitItemKind :: Const ( ref ty, ref default) => {
2595
+ this. visit_ty ( ty) ;
2596
+
2597
+ // Only impose the restrictions of
2598
+ // ConstRibKind for an actual constant
2599
+ // expression in a provided default.
2600
+ if let Some ( ref expr) = * default{
2601
+ this. with_constant_rib ( |this| {
2602
+ this. visit_expr ( expr) ;
2603
+ } ) ;
2604
+ }
2596
2605
}
2597
- }
2598
- TraitItemKind :: Method ( _ , _ ) => {
2599
- visit :: walk_trait_item ( this , trait_item )
2600
- }
2601
- TraitItemKind :: Type ( .. ) => {
2602
- visit :: walk_trait_item ( this , trait_item )
2603
- }
2604
- TraitItemKind :: Macro ( _ ) => {
2605
- panic ! ( "unexpanded macro in resolve!" )
2606
- }
2607
- } ;
2606
+ TraitItemKind :: Method ( _ , _ ) => {
2607
+ visit :: walk_trait_item ( this , trait_item )
2608
+ }
2609
+ TraitItemKind :: Type ( .. ) => {
2610
+ visit :: walk_trait_item ( this , trait_item )
2611
+ }
2612
+ TraitItemKind :: Macro ( _ ) => {
2613
+ panic ! ( "unexpanded macro in resolve!" )
2614
+ }
2615
+ } ;
2616
+ } ) ;
2608
2617
} ) ;
2609
2618
}
2610
2619
} ) ;
@@ -2774,6 +2783,22 @@ impl<'a> Resolver<'a> {
2774
2783
result
2775
2784
}
2776
2785
2786
+ /// When evaluating a `trait` use its associated types' idents for suggestionsa in E0412.
2787
+ fn with_trait_items < T , F > ( & mut self , trait_items : & Vec < TraitItem > , f : F ) -> T
2788
+ where F : FnOnce ( & mut Resolver < ' _ > ) -> T
2789
+ {
2790
+ let trait_assoc_types = replace (
2791
+ & mut self . current_trait_assoc_types ,
2792
+ trait_items. iter ( ) . filter_map ( |item| match & item. node {
2793
+ TraitItemKind :: Type ( bounds, _) if bounds. len ( ) == 0 => Some ( item. ident ) ,
2794
+ _ => None ,
2795
+ } ) . collect ( ) ,
2796
+ ) ;
2797
+ let result = f ( self ) ;
2798
+ self . current_trait_assoc_types = trait_assoc_types;
2799
+ result
2800
+ }
2801
+
2777
2802
/// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`).
2778
2803
fn with_optional_trait_ref < T , F > ( & mut self , opt_trait_ref : Option < & TraitRef > , f : F ) -> T
2779
2804
where F : FnOnce ( & mut Resolver < ' _ > , Option < DefId > ) -> T
@@ -3464,8 +3489,12 @@ impl<'a> Resolver<'a> {
3464
3489
}
3465
3490
3466
3491
fn self_type_is_available ( & mut self , span : Span ) -> bool {
3467
- let binding = self . resolve_ident_in_lexical_scope ( Ident :: with_empty_ctxt ( kw:: SelfUpper ) ,
3468
- TypeNS , None , span) ;
3492
+ let binding = self . resolve_ident_in_lexical_scope (
3493
+ Ident :: with_empty_ctxt ( kw:: SelfUpper ) ,
3494
+ TypeNS ,
3495
+ None ,
3496
+ span,
3497
+ ) ;
3469
3498
if let Some ( LexicalScopeBinding :: Res ( res) ) = binding { res != Res :: Err } else { false }
3470
3499
}
3471
3500
@@ -4095,13 +4124,12 @@ impl<'a> Resolver<'a> {
4095
4124
res
4096
4125
}
4097
4126
4098
- fn lookup_assoc_candidate < FilterFn > ( & mut self ,
4099
- ident : Ident ,
4100
- ns : Namespace ,
4101
- filter_fn : FilterFn )
4102
- -> Option < AssocSuggestion >
4103
- where FilterFn : Fn ( Res ) -> bool
4104
- {
4127
+ fn lookup_assoc_candidate < FilterFn : Fn ( Res ) -> bool > (
4128
+ & mut self ,
4129
+ ident : Ident ,
4130
+ ns : Namespace ,
4131
+ filter_fn : FilterFn ,
4132
+ ) -> Option < AssocSuggestion > {
4105
4133
fn extract_node_id ( t : & Ty ) -> Option < NodeId > {
4106
4134
match t. node {
4107
4135
TyKind :: Path ( None , _) => Some ( t. id ) ,
@@ -4133,6 +4161,12 @@ impl<'a> Resolver<'a> {
4133
4161
}
4134
4162
}
4135
4163
4164
+ for assoc_type_ident in & self . current_trait_assoc_types {
4165
+ if * assoc_type_ident == ident {
4166
+ return Some ( AssocSuggestion :: AssocItem ) ;
4167
+ }
4168
+ }
4169
+
4136
4170
// Look for associated items in the current trait.
4137
4171
if let Some ( ( module, _) ) = self . current_trait_ref {
4138
4172
if let Ok ( binding) = self . resolve_ident_in_module (
@@ -4145,6 +4179,7 @@ impl<'a> Resolver<'a> {
4145
4179
) {
4146
4180
let res = binding. res ( ) ;
4147
4181
if filter_fn ( res) {
4182
+ debug ! ( "extract_node_id res not filtered" ) ;
4148
4183
return Some ( if self . has_self . contains ( & res. def_id ( ) ) {
4149
4184
AssocSuggestion :: MethodWithSelf
4150
4185
} else {
0 commit comments