@@ -52,7 +52,7 @@ use syntax::ast::{CRATE_NODE_ID, Arm, IsAsync, BindingMode, Block, Crate, Expr,
5252use syntax:: ast:: { FnDecl , ForeignItem , ForeignItemKind , GenericParamKind , Generics } ;
5353use syntax:: ast:: { Item , ItemKind , ImplItem , ImplItemKind } ;
5454use 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 } ;
5656use syntax:: ptr:: P ;
5757use syntax:: { span_err, struct_span_err, unwrap_or, walk_list} ;
5858
@@ -1053,6 +1053,7 @@ impl<'a, R> Rib<'a, R> {
10531053/// This refers to the thing referred by a name. The difference between `Res` and `Item` is that
10541054/// items are visible in their whole block, while `Res`es only from the place they are defined
10551055/// forward.
1056+ #[ derive( Debug ) ]
10561057enum LexicalScopeBinding < ' a > {
10571058 Item ( & ' a NameBinding < ' a > ) ,
10581059 Res ( Res ) ,
@@ -1601,6 +1602,9 @@ pub struct Resolver<'a> {
16011602 /// The trait that the current context can refer to.
16021603 current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
16031604
1605+ /// The current trait's associated types' ident, used for diagnostic suggestions.
1606+ current_trait_assoc_types : Vec < Ident > ,
1607+
16041608 /// The current self type if inside an impl (used for better errors).
16051609 current_self_type : Option < Ty > ,
16061610
@@ -1971,6 +1975,7 @@ impl<'a> Resolver<'a> {
19711975 label_ribs : Vec :: new ( ) ,
19721976
19731977 current_trait_ref : None ,
1978+ current_trait_assoc_types : Vec :: new ( ) ,
19741979 current_self_type : None ,
19751980 current_self_item : None ,
19761981 last_import_segment : false ,
@@ -2579,32 +2584,36 @@ impl<'a> Resolver<'a> {
25792584 walk_list ! ( this, visit_param_bound, bounds) ;
25802585
25812586 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+ }
25962605 }
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+ } ) ;
26082617 } ) ;
26092618 }
26102619 } ) ;
@@ -2774,6 +2783,22 @@ impl<'a> Resolver<'a> {
27742783 result
27752784 }
27762785
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+
27772802 /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`).
27782803 fn with_optional_trait_ref < T , F > ( & mut self , opt_trait_ref : Option < & TraitRef > , f : F ) -> T
27792804 where F : FnOnce ( & mut Resolver < ' _ > , Option < DefId > ) -> T
@@ -3464,8 +3489,12 @@ impl<'a> Resolver<'a> {
34643489 }
34653490
34663491 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+ ) ;
34693498 if let Some ( LexicalScopeBinding :: Res ( res) ) = binding { res != Res :: Err } else { false }
34703499 }
34713500
@@ -4095,13 +4124,12 @@ impl<'a> Resolver<'a> {
40954124 res
40964125 }
40974126
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 > {
41054133 fn extract_node_id ( t : & Ty ) -> Option < NodeId > {
41064134 match t. node {
41074135 TyKind :: Path ( None , _) => Some ( t. id ) ,
@@ -4133,6 +4161,12 @@ impl<'a> Resolver<'a> {
41334161 }
41344162 }
41354163
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+
41364170 // Look for associated items in the current trait.
41374171 if let Some ( ( module, _) ) = self . current_trait_ref {
41384172 if let Ok ( binding) = self . resolve_ident_in_module (
@@ -4145,6 +4179,7 @@ impl<'a> Resolver<'a> {
41454179 ) {
41464180 let res = binding. res ( ) ;
41474181 if filter_fn ( res) {
4182+ debug ! ( "extract_node_id res not filtered" ) ;
41484183 return Some ( if self . has_self . contains ( & res. def_id ( ) ) {
41494184 AssocSuggestion :: MethodWithSelf
41504185 } else {
0 commit comments