@@ -42,8 +42,9 @@ use rustc::lint;
4242use rustc:: hir:: def:: * ;
4343use rustc:: hir:: def:: Namespace :: * ;
4444use rustc:: hir:: def_id:: { CRATE_DEF_INDEX , LOCAL_CRATE , DefId } ;
45- use rustc:: ty;
4645use rustc:: hir:: { Freevar , FreevarMap , TraitCandidate , TraitMap , GlobMap } ;
46+ use rustc:: session:: config:: nightly_options;
47+ use rustc:: ty;
4748use rustc:: util:: nodemap:: { NodeMap , NodeSet , FxHashMap , FxHashSet , DefIdMap } ;
4849
4950use rustc_metadata:: creader:: CrateLoader ;
@@ -1381,6 +1382,9 @@ pub struct Resolver<'a, 'b: 'a> {
13811382 /// The current self type if inside an impl (used for better errors).
13821383 current_self_type : Option < Ty > ,
13831384
1385+ /// The current self item if inside an ADT (used for better errors).
1386+ current_self_item : Option < NodeId > ,
1387+
13841388 /// The idents for the primitive types.
13851389 primitive_type_table : PrimitiveTypeTable ,
13861390
@@ -1710,6 +1714,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
17101714
17111715 current_trait_ref : None ,
17121716 current_self_type : None ,
1717+ current_self_item : None ,
17131718
17141719 primitive_type_table : PrimitiveTypeTable :: new ( ) ,
17151720
@@ -2186,15 +2191,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
21862191 }
21872192
21882193 fn resolve_adt ( & mut self , item : & Item , generics : & Generics ) {
2189- self . with_type_parameter_rib ( HasTypeParameters ( generics, ItemRibKind ) , |this| {
2190- let item_def_id = this. definitions . local_def_id ( item. id ) ;
2191- if this. session . features_untracked ( ) . self_in_typedefs {
2192- this. with_self_rib ( Def :: SelfTy ( None , Some ( item_def_id) ) , |this| {
2194+ self . with_current_self_item ( item, |this| {
2195+ this. with_type_parameter_rib ( HasTypeParameters ( generics, ItemRibKind ) , |this| {
2196+ let item_def_id = this. definitions . local_def_id ( item. id ) ;
2197+ if this. session . features_untracked ( ) . self_in_typedefs {
2198+ this. with_self_rib ( Def :: SelfTy ( None , Some ( item_def_id) ) , |this| {
2199+ visit:: walk_item ( this, item) ;
2200+ } ) ;
2201+ } else {
21932202 visit:: walk_item ( this, item) ;
2194- } ) ;
2195- } else {
2196- visit:: walk_item ( this, item) ;
2197- }
2203+ }
2204+ } ) ;
21982205 } ) ;
21992206 }
22002207
@@ -2435,6 +2442,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
24352442 result
24362443 }
24372444
2445+ fn with_current_self_item < T , F > ( & mut self , self_item : & Item , f : F ) -> T
2446+ where F : FnOnce ( & mut Resolver ) -> T
2447+ {
2448+ let previous_value = replace ( & mut self . current_self_item , Some ( self_item. id ) ) ;
2449+ let result = f ( self ) ;
2450+ self . current_self_item = previous_value;
2451+ result
2452+ }
2453+
24382454 /// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`)
24392455 fn with_optional_trait_ref < T , F > ( & mut self , opt_trait_ref : Option < & TraitRef > , f : F ) -> T
24402456 where F : FnOnce ( & mut Resolver , Option < DefId > ) -> T
@@ -3004,6 +3020,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
30043020 "traits and impls"
30053021 } ;
30063022 err. span_label ( span, format ! ( "`Self` is only available in {}" , available_in) ) ;
3023+ if this. current_self_item . is_some ( ) && nightly_options:: is_nightly_build ( ) {
3024+ err. help ( "add #![feature(self_in_typedefs)] to the crate attributes \
3025+ to enable") ;
3026+ }
30073027 return ( err, Vec :: new ( ) ) ;
30083028 }
30093029 if is_self_value ( path, ns) {
0 commit comments