@@ -43,7 +43,8 @@ struct Annotator {
43
43
impl Annotator {
44
44
// Determine the stability for a node based on its attributes and inherited
45
45
// stability. The stability is recorded in the index and used as the parent.
46
- fn annotate < F > ( & mut self , id : NodeId , attrs : & Vec < Attribute > , f : F ) where
46
+ fn annotate < F > ( & mut self , id : NodeId , use_parent : bool ,
47
+ attrs : & Vec < Attribute > , f : F ) where
47
48
F : FnOnce ( & mut Annotator ) ,
48
49
{
49
50
match attr:: find_stability ( attrs. as_slice ( ) ) {
@@ -60,7 +61,9 @@ impl Annotator {
60
61
}
61
62
}
62
63
None => {
63
- self . parent . clone ( ) . map ( |stab| self . index . local . insert ( id, stab) ) ;
64
+ if use_parent {
65
+ self . parent . clone ( ) . map ( |stab| self . index . local . insert ( id, stab) ) ;
66
+ }
64
67
f ( self ) ;
65
68
}
66
69
}
@@ -69,11 +72,24 @@ impl Annotator {
69
72
70
73
impl < ' v > Visitor < ' v > for Annotator {
71
74
fn visit_item ( & mut self , i : & Item ) {
72
- self . annotate ( i. id , & i. attrs , |v| visit:: walk_item ( v, i) ) ;
75
+ // FIXME (#18969): the following is a hack around the fact
76
+ // that we cannot currently annotate the stability of
77
+ // `deriving`. Basically, we do *not* allow stability
78
+ // inheritance on trait implementations, so that derived
79
+ // implementations appear to be unannotated. This then allows
80
+ // derived implementations to be automatically tagged with the
81
+ // stability of the trait. This is WRONG, but expedient to get
82
+ // libstd stabilized for the 1.0 release.
83
+ let use_parent = match i. node {
84
+ ast:: ItemImpl ( _, _, Some ( _) , _, _) => false ,
85
+ _ => true ,
86
+ } ;
87
+
88
+ self . annotate ( i. id , use_parent, & i. attrs , |v| visit:: walk_item ( v, i) ) ;
73
89
74
90
if let ast:: ItemStruct ( ref sd, _) = i. node {
75
91
sd. ctor_id . map ( |id| {
76
- self . annotate ( id, & i. attrs , |_| { } )
92
+ self . annotate ( id, true , & i. attrs , |_| { } )
77
93
} ) ;
78
94
}
79
95
}
@@ -82,7 +98,7 @@ impl<'v> Visitor<'v> for Annotator {
82
98
_: & ' v Block , _: Span , _: NodeId ) {
83
99
if let FkMethod ( _, _, meth) = fk {
84
100
// Methods are not already annotated, so we annotate it
85
- self . annotate ( meth. id , & meth. attrs , |_| { } ) ;
101
+ self . annotate ( meth. id , true , & meth. attrs , |_| { } ) ;
86
102
}
87
103
// Items defined in a function body have no reason to have
88
104
// a stability attribute, so we don't recurse.
@@ -101,15 +117,17 @@ impl<'v> Visitor<'v> for Annotator {
101
117
102
118
TypeTraitItem ( ref typedef) => ( typedef. ty_param . id , & typedef. attrs ) ,
103
119
} ;
104
- self . annotate ( id, attrs, |v| visit:: walk_trait_item ( v, t) ) ;
120
+ self . annotate ( id, true , attrs, |v| visit:: walk_trait_item ( v, t) ) ;
105
121
}
106
122
107
123
fn visit_variant ( & mut self , var : & Variant , g : & ' v Generics ) {
108
- self . annotate ( var. node . id , & var. node . attrs , |v| visit:: walk_variant ( v, var, g) )
124
+ self . annotate ( var. node . id , true , & var. node . attrs ,
125
+ |v| visit:: walk_variant ( v, var, g) )
109
126
}
110
127
111
128
fn visit_struct_field ( & mut self , s : & StructField ) {
112
- self . annotate ( s. node . id , & s. node . attrs , |v| visit:: walk_struct_field ( v, s) ) ;
129
+ self . annotate ( s. node . id , true , & s. node . attrs ,
130
+ |v| visit:: walk_struct_field ( v, s) ) ;
113
131
}
114
132
}
115
133
@@ -123,7 +141,8 @@ impl Index {
123
141
} ,
124
142
parent : None
125
143
} ;
126
- annotator. annotate ( ast:: CRATE_NODE_ID , & krate. attrs , |v| visit:: walk_crate ( v, krate) ) ;
144
+ annotator. annotate ( ast:: CRATE_NODE_ID , true , & krate. attrs ,
145
+ |v| visit:: walk_crate ( v, krate) ) ;
127
146
annotator. index
128
147
}
129
148
}
@@ -135,16 +154,29 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
135
154
match ty:: trait_item_of_item ( tcx, id) {
136
155
Some ( ty:: MethodTraitItemId ( trait_method_id) )
137
156
if trait_method_id != id => {
138
- lookup ( tcx, trait_method_id)
139
- }
140
- _ if is_local ( id) => {
141
- tcx. stability . borrow ( ) . local . get ( & id. node ) . cloned ( )
142
- }
143
- _ => {
144
- let stab = csearch:: get_stability ( & tcx. sess . cstore , id) ;
145
- let mut index = tcx. stability . borrow_mut ( ) ;
146
- ( * index) . extern_cache . insert ( id, stab. clone ( ) ) ;
147
- stab
157
+ return lookup ( tcx, trait_method_id)
148
158
}
159
+ _ => { }
149
160
}
161
+
162
+ let item_stab = if is_local ( id) {
163
+ tcx. stability . borrow ( ) . local . get ( & id. node ) . cloned ( )
164
+ } else {
165
+ let stab = csearch:: get_stability ( & tcx. sess . cstore , id) ;
166
+ let mut index = tcx. stability . borrow_mut ( ) ;
167
+ ( * index) . extern_cache . insert ( id, stab. clone ( ) ) ;
168
+ stab
169
+ } ;
170
+
171
+ item_stab. or_else ( || {
172
+ if let Some ( trait_id) = ty:: trait_id_of_impl ( tcx, id) {
173
+ // FIXME (#18969): for the time being, simply use the
174
+ // stability of the trait to determine the stability of any
175
+ // unmarked impls for it. See FIXME above for more details.
176
+
177
+ lookup ( tcx, trait_id)
178
+ } else {
179
+ None
180
+ }
181
+ } )
150
182
}
0 commit comments