@@ -15,14 +15,14 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
15
15
use rustc_errors:: Applicability ;
16
16
use rustc_hir as hir;
17
17
use rustc_hir:: def:: { DefKind , Res } ;
18
- use rustc_hir:: def_id:: { LocalDefId , CRATE_DEF_ID } ;
18
+ use rustc_hir:: def_id:: { DefId , LocalDefId , CRATE_DEF_ID } ;
19
19
use rustc_hir:: hir_id:: CRATE_HIR_ID ;
20
20
use rustc_hir:: intravisit:: { self , Visitor } ;
21
21
use rustc_hir:: { FieldDef , Item , ItemKind , TraitRef , Ty , TyKind , Variant } ;
22
22
use rustc_middle:: hir:: nested_filter;
23
23
use rustc_middle:: middle:: privacy:: EffectiveVisibilities ;
24
24
use rustc_middle:: middle:: stability:: { AllowUnstable , DeprecationEntry , Index } ;
25
- use rustc_middle:: ty:: { query:: Providers , TyCtxt } ;
25
+ use rustc_middle:: ty:: { query:: Providers , DefIdTree , TyCtxt } ;
26
26
use rustc_session:: lint;
27
27
use rustc_session:: lint:: builtin:: { INEFFECTIVE_UNSTABLE_TRAIT_IMPL , USELESS_DEPRECATED } ;
28
28
use rustc_span:: symbol:: { sym, Symbol } ;
@@ -90,13 +90,84 @@ impl InheritStability {
90
90
}
91
91
}
92
92
93
+ fn inherit_deprecation ( def_kind : DefKind ) -> InheritDeprecation {
94
+ match def_kind {
95
+ DefKind :: LifetimeParam | DefKind :: TyParam | DefKind :: ConstParam => InheritDeprecation :: No ,
96
+ _ => InheritDeprecation :: Yes ,
97
+ }
98
+ }
99
+
100
+ fn annotation_kind ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> AnnotationKind {
101
+ match tcx. hir ( ) . get_by_def_id ( def_id) {
102
+ hir:: Node :: Item ( i) => match i. kind {
103
+ // Inherent impls and foreign modules serve only as containers for other items,
104
+ // they don't have their own stability. They still can be annotated as unstable
105
+ // and propagate this unstability to children, but this annotation is completely
106
+ // optional. They inherit stability from their parents when unannotated.
107
+ hir:: ItemKind :: Impl ( hir:: Impl { of_trait : None , .. } )
108
+ | hir:: ItemKind :: ForeignMod { .. } => AnnotationKind :: Container ,
109
+ hir:: ItemKind :: Impl ( hir:: Impl { of_trait : Some ( _) , .. } ) => {
110
+ AnnotationKind :: DeprecationProhibited
111
+ }
112
+ _ => AnnotationKind :: Required ,
113
+ } ,
114
+ hir:: Node :: ImplItem ( ii) => {
115
+ let item = tcx. hir ( ) . expect_item ( tcx. hir ( ) . get_parent_item ( ii. hir_id ( ) ) . def_id ) ;
116
+ match item. kind {
117
+ hir:: ItemKind :: Impl ( hir:: Impl { of_trait : Some ( _) , .. } ) => {
118
+ AnnotationKind :: Prohibited
119
+ }
120
+ _ => AnnotationKind :: Required ,
121
+ }
122
+ }
123
+ hir:: Node :: GenericParam ( p) => match & p. kind {
124
+ // Allow stability attributes on default generic arguments.
125
+ hir:: GenericParamKind :: Type { default : Some ( _) , .. }
126
+ | hir:: GenericParamKind :: Const { default : Some ( _) , .. } => AnnotationKind :: Container ,
127
+ _ => AnnotationKind :: Prohibited ,
128
+ } ,
129
+
130
+ _ => AnnotationKind :: Required ,
131
+ }
132
+ }
133
+
134
+ fn lookup_deprecation_entry ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Option < DeprecationEntry > {
135
+ let def_id = def_id. expect_local ( ) ;
136
+ let attrs = tcx. get_attrs ( def_id. to_def_id ( ) , sym:: deprecated) ;
137
+
138
+ let depr = attr:: find_deprecation ( & tcx. sess , attrs) ;
139
+ let Some ( ( depr, span) ) = & depr else {
140
+ if inherit_deprecation ( tcx. def_kind ( def_id) ) . yes ( ) {
141
+ let parent_id = tcx. opt_local_parent ( def_id) ?;
142
+ let parent_depr = tcx. lookup_deprecation_entry ( parent_id) ?;
143
+ info ! ( "tagging child {:?} as deprecated from parent" , def_id) ;
144
+ return Some ( parent_depr) ;
145
+ }
146
+
147
+ return None ;
148
+ } ;
149
+
150
+ let kind = annotation_kind ( tcx, def_id) ;
151
+ if matches ! ( kind, AnnotationKind :: Prohibited | AnnotationKind :: DeprecationProhibited ) {
152
+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
153
+ tcx. emit_spanned_lint (
154
+ USELESS_DEPRECATED ,
155
+ hir_id,
156
+ * span,
157
+ errors:: DeprecatedAnnotationHasNoEffect { span : * span } ,
158
+ ) ;
159
+ }
160
+
161
+ // `Deprecation` is just two pointers, no need to intern it
162
+ Some ( DeprecationEntry :: local ( * depr, def_id) )
163
+ }
164
+
93
165
/// A private tree-walker for producing an `Index`.
94
166
struct Annotator < ' a , ' tcx > {
95
167
tcx : TyCtxt < ' tcx > ,
96
168
index : & ' a mut Index ,
97
169
parent_stab : Option < Stability > ,
98
170
parent_const_stab : Option < ConstStability > ,
99
- parent_depr : Option < DeprecationEntry > ,
100
171
in_trait_impl : bool ,
101
172
}
102
173
@@ -117,34 +188,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
117
188
) where
118
189
F : FnOnce ( & mut Self ) ,
119
190
{
120
- let attrs = self . tcx . hir ( ) . attrs ( self . tcx . hir ( ) . local_def_id_to_hir_id ( def_id) ) ;
121
- debug ! ( "annotate(id = {:?}, attrs = {:?})" , def_id, attrs) ;
122
-
123
- let depr = attr:: find_deprecation ( & self . tcx . sess , attrs) ;
124
- let mut is_deprecated = false ;
125
- if let Some ( ( depr, span) ) = & depr {
126
- is_deprecated = true ;
127
-
128
- if matches ! ( kind, AnnotationKind :: Prohibited | AnnotationKind :: DeprecationProhibited ) {
129
- let hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( def_id) ;
130
- self . tcx . emit_spanned_lint (
131
- USELESS_DEPRECATED ,
132
- hir_id,
133
- * span,
134
- errors:: DeprecatedAnnotationHasNoEffect { span : * span } ,
135
- ) ;
136
- }
137
-
138
- // `Deprecation` is just two pointers, no need to intern it
139
- let depr_entry = DeprecationEntry :: local ( * depr, def_id) ;
140
- self . index . depr_map . insert ( def_id, depr_entry) ;
141
- } else if let Some ( parent_depr) = self . parent_depr {
142
- if inherit_deprecation. yes ( ) {
143
- is_deprecated = true ;
144
- info ! ( "tagging child {:?} as deprecated from parent" , def_id) ;
145
- self . index . depr_map . insert ( def_id, parent_depr) ;
146
- }
147
- }
191
+ let depr = self . tcx . lookup_deprecation_entry ( def_id) ;
192
+ let is_deprecated = depr. is_some ( ) ;
148
193
149
194
if !self . tcx . features ( ) . staged_api {
150
195
// Propagate unstability. This can happen even for non-staged-api crates in case
@@ -155,15 +200,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
155
200
}
156
201
}
157
202
158
- self . recurse_with_stability_attrs (
159
- depr. map ( |( d, _) | DeprecationEntry :: local ( d, def_id) ) ,
160
- None ,
161
- None ,
162
- visit_children,
163
- ) ;
203
+ self . recurse_with_stability_attrs ( None , None , visit_children) ;
164
204
return ;
165
205
}
166
206
207
+ let attrs = self . tcx . hir ( ) . attrs ( self . tcx . hir ( ) . local_def_id_to_hir_id ( def_id) ) ;
208
+ debug ! ( "annotate(id = {:?}, attrs = {:?})" , def_id, attrs) ;
167
209
let ( stab, const_stab, body_stab) = attr:: find_stability ( & self . tcx . sess , attrs, item_sp) ;
168
210
let mut const_span = None ;
169
211
@@ -201,9 +243,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
201
243
}
202
244
}
203
245
204
- if let Some ( ( rustc_attr :: Deprecation { is_since_rustc_version : true , .. } , span ) ) = & depr {
205
- if stab . is_none ( ) {
206
- self . tcx . sess . emit_err ( DeprecatedAttribute { span : * span } ) ;
246
+ if stab . is_none ( ) && depr . map_or ( false , |d| d . attr . is_since_rustc_version ) {
247
+ if let Some ( attr ) = attrs . iter ( ) . find ( |attr| attr . has_name ( sym :: deprecated ) ) {
248
+ self . tcx . sess . emit_err ( DeprecatedAttribute { span : attr . span } ) ;
207
249
}
208
250
}
209
251
@@ -227,7 +269,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
227
269
// Check if deprecated_since < stable_since. If it is,
228
270
// this is *almost surely* an accident.
229
271
if let ( & Some ( dep_since) , & attr:: Stable { since : stab_since, .. } ) =
230
- ( & depr. as_ref ( ) . and_then ( |( d , _ ) | d. since ) , & stab. level )
272
+ ( & depr. as_ref ( ) . and_then ( |d | d. attr . since ) , & stab. level )
231
273
{
232
274
// Explicit version of iter::order::lt to handle parse errors properly
233
275
for ( dep_v, stab_v) in
@@ -282,7 +324,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
282
324
}
283
325
284
326
self . recurse_with_stability_attrs (
285
- depr. map ( |( d, _) | DeprecationEntry :: local ( d, def_id) ) ,
286
327
stab,
287
328
if inherit_const_stability. yes ( ) { const_stab } else { None } ,
288
329
visit_children,
@@ -291,19 +332,14 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
291
332
292
333
fn recurse_with_stability_attrs (
293
334
& mut self ,
294
- depr : Option < DeprecationEntry > ,
295
335
stab : Option < Stability > ,
296
336
const_stab : Option < ConstStability > ,
297
337
f : impl FnOnce ( & mut Self ) ,
298
338
) {
299
339
// These will be `Some` if this item changes the corresponding stability attribute.
300
- let mut replaced_parent_depr = None ;
301
340
let mut replaced_parent_stab = None ;
302
341
let mut replaced_parent_const_stab = None ;
303
342
304
- if let Some ( depr) = depr {
305
- replaced_parent_depr = Some ( replace ( & mut self . parent_depr , Some ( depr) ) ) ;
306
- }
307
343
if let Some ( stab) = stab {
308
344
replaced_parent_stab = Some ( replace ( & mut self . parent_stab , Some ( stab) ) ) ;
309
345
}
@@ -314,9 +350,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
314
350
315
351
f ( self ) ;
316
352
317
- if let Some ( orig_parent_depr) = replaced_parent_depr {
318
- self . parent_depr = orig_parent_depr;
319
- }
320
353
if let Some ( orig_parent_stab) = replaced_parent_stab {
321
354
self . parent_stab = orig_parent_stab;
322
355
}
@@ -627,7 +660,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
627
660
stab_map : Default :: default ( ) ,
628
661
const_stab_map : Default :: default ( ) ,
629
662
default_body_stab_map : Default :: default ( ) ,
630
- depr_map : Default :: default ( ) ,
631
663
implications : Default :: default ( ) ,
632
664
} ;
633
665
@@ -637,7 +669,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
637
669
index : & mut index,
638
670
parent_stab : None ,
639
671
parent_const_stab : None ,
640
- parent_depr : None ,
641
672
in_trait_impl : false ,
642
673
} ;
643
674
@@ -690,9 +721,7 @@ pub(crate) fn provide(providers: &mut Providers) {
690
721
lookup_default_body_stability : |tcx, id| {
691
722
tcx. stability ( ) . local_default_body_stability ( id. expect_local ( ) )
692
723
} ,
693
- lookup_deprecation_entry : |tcx, id| {
694
- tcx. stability ( ) . local_deprecation_entry ( id. expect_local ( ) )
695
- } ,
724
+ lookup_deprecation_entry,
696
725
..* providers
697
726
} ;
698
727
}
0 commit comments