@@ -42,8 +42,9 @@ use rustc::lint;
42
42
use rustc:: hir:: def:: * ;
43
43
use rustc:: hir:: def:: Namespace :: * ;
44
44
use rustc:: hir:: def_id:: { CRATE_DEF_INDEX , LOCAL_CRATE , DefId } ;
45
- use rustc:: ty;
46
45
use rustc:: hir:: { Freevar , FreevarMap , TraitCandidate , TraitMap , GlobMap } ;
46
+ use rustc:: session:: config:: nightly_options;
47
+ use rustc:: ty;
47
48
use rustc:: util:: nodemap:: { NodeMap , NodeSet , FxHashMap , FxHashSet , DefIdMap } ;
48
49
49
50
use rustc_metadata:: creader:: CrateLoader ;
@@ -1381,6 +1382,9 @@ pub struct Resolver<'a, 'b: 'a> {
1381
1382
/// The current self type if inside an impl (used for better errors).
1382
1383
current_self_type : Option < Ty > ,
1383
1384
1385
+ /// The current self item if inside an ADT (used for better errors).
1386
+ current_self_item : Option < NodeId > ,
1387
+
1384
1388
/// The idents for the primitive types.
1385
1389
primitive_type_table : PrimitiveTypeTable ,
1386
1390
@@ -1710,6 +1714,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1710
1714
1711
1715
current_trait_ref : None ,
1712
1716
current_self_type : None ,
1717
+ current_self_item : None ,
1713
1718
1714
1719
primitive_type_table : PrimitiveTypeTable :: new ( ) ,
1715
1720
@@ -2186,15 +2191,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
2186
2191
}
2187
2192
2188
2193
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 {
2193
2202
visit:: walk_item ( this, item) ;
2194
- } ) ;
2195
- } else {
2196
- visit:: walk_item ( this, item) ;
2197
- }
2203
+ }
2204
+ } ) ;
2198
2205
} ) ;
2199
2206
}
2200
2207
@@ -2435,6 +2442,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
2435
2442
result
2436
2443
}
2437
2444
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
+
2438
2454
/// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`)
2439
2455
fn with_optional_trait_ref < T , F > ( & mut self , opt_trait_ref : Option < & TraitRef > , f : F ) -> T
2440
2456
where F : FnOnce ( & mut Resolver , Option < DefId > ) -> T
@@ -3004,6 +3020,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3004
3020
"traits and impls"
3005
3021
} ;
3006
3022
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
+ }
3007
3027
return ( err, Vec :: new ( ) ) ;
3008
3028
}
3009
3029
if is_self_value ( path, ns) {
0 commit comments