@@ -37,6 +37,24 @@ enum AnnotationKind {
37
37
Container ,
38
38
}
39
39
40
+ /// Whether to inherit deprecation flags for nested items. In most cases, we do want to inherit
41
+ /// deprecation, because nested items rarely have individual deprecation attributes, and so
42
+ /// should be treated as deprecated if their parent is. However, default generic parameters
43
+ /// have separate deprecation attributes from their parents, so we do not wish to inherit
44
+ /// deprecation in this case. For example, inheriting deprecation for `T` in `Foo<T>`
45
+ /// would cause a duplicate warning arising from both `Foo` and `T` being deprecated.
46
+ #[ derive( Clone ) ]
47
+ enum InheritDeprecation {
48
+ Yes ,
49
+ No ,
50
+ }
51
+
52
+ impl InheritDeprecation {
53
+ fn yes ( & self ) -> bool {
54
+ matches ! ( self , InheritDeprecation :: Yes )
55
+ }
56
+ }
57
+
40
58
// A private tree-walker for producing an Index.
41
59
struct Annotator < ' a , ' tcx > {
42
60
tcx : TyCtxt < ' tcx > ,
@@ -56,14 +74,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
56
74
attrs : & [ Attribute ] ,
57
75
item_sp : Span ,
58
76
kind : AnnotationKind ,
77
+ inherit_deprecation : InheritDeprecation ,
59
78
visit_children : F ,
60
79
) where
61
80
F : FnOnce ( & mut Self ) ,
62
81
{
63
82
debug ! ( "annotate(id = {:?}, attrs = {:?})" , hir_id, attrs) ;
64
83
let mut did_error = false ;
65
84
if !self . tcx . features ( ) . staged_api {
66
- did_error = self . forbid_staged_api_attrs ( hir_id, attrs) ;
85
+ did_error = self . forbid_staged_api_attrs ( hir_id, attrs, inherit_deprecation . clone ( ) ) ;
67
86
}
68
87
69
88
let depr =
@@ -80,9 +99,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
80
99
let depr_entry = DeprecationEntry :: local ( depr. clone ( ) , hir_id) ;
81
100
self . index . depr_map . insert ( hir_id, depr_entry) ;
82
101
} else if let Some ( parent_depr) = self . parent_depr . clone ( ) {
83
- is_deprecated = true ;
84
- info ! ( "tagging child {:?} as deprecated from parent" , hir_id) ;
85
- self . index . depr_map . insert ( hir_id, parent_depr) ;
102
+ if inherit_deprecation. yes ( ) {
103
+ is_deprecated = true ;
104
+ info ! ( "tagging child {:?} as deprecated from parent" , hir_id) ;
105
+ self . index . depr_map . insert ( hir_id, parent_depr) ;
106
+ }
86
107
}
87
108
88
109
if self . tcx . features ( ) . staged_api {
@@ -186,7 +207,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
186
207
if stab. is_none ( ) {
187
208
debug ! ( "annotate: stab not found, parent = {:?}" , self . parent_stab) ;
188
209
if let Some ( stab) = self . parent_stab {
189
- if stab. level . is_unstable ( ) {
210
+ if inherit_deprecation . yes ( ) && stab. level . is_unstable ( ) {
190
211
self . index . stab_map . insert ( hir_id, stab) ;
191
212
}
192
213
}
@@ -237,7 +258,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
237
258
}
238
259
239
260
// returns true if an error occurred, used to suppress some spurious errors
240
- fn forbid_staged_api_attrs ( & mut self , hir_id : HirId , attrs : & [ Attribute ] ) -> bool {
261
+ fn forbid_staged_api_attrs (
262
+ & mut self ,
263
+ hir_id : HirId ,
264
+ attrs : & [ Attribute ] ,
265
+ inherit_deprecation : InheritDeprecation ,
266
+ ) -> bool {
241
267
// Emit errors for non-staged-api crates.
242
268
let unstable_attrs = [
243
269
sym:: unstable,
@@ -265,7 +291,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
265
291
// Propagate unstability. This can happen even for non-staged-api crates in case
266
292
// -Zforce-unstable-if-unmarked is set.
267
293
if let Some ( stab) = self . parent_stab {
268
- if stab. level . is_unstable ( ) {
294
+ if inherit_deprecation . yes ( ) && stab. level . is_unstable ( ) {
269
295
self . index . stab_map . insert ( hir_id, stab) ;
270
296
}
271
297
}
@@ -301,54 +327,119 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
301
327
}
302
328
hir:: ItemKind :: Struct ( ref sd, _) => {
303
329
if let Some ( ctor_hir_id) = sd. ctor_hir_id ( ) {
304
- self . annotate ( ctor_hir_id, & i. attrs , i. span , AnnotationKind :: Required , |_| { } )
330
+ self . annotate (
331
+ ctor_hir_id,
332
+ & i. attrs ,
333
+ i. span ,
334
+ AnnotationKind :: Required ,
335
+ InheritDeprecation :: Yes ,
336
+ |_| { } ,
337
+ )
305
338
}
306
339
}
307
340
_ => { }
308
341
}
309
342
310
- self . annotate ( i. hir_id , & i. attrs , i. span , kind, |v| intravisit:: walk_item ( v, i) ) ;
343
+ self . annotate ( i. hir_id , & i. attrs , i. span , kind, InheritDeprecation :: Yes , |v| {
344
+ intravisit:: walk_item ( v, i)
345
+ } ) ;
311
346
self . in_trait_impl = orig_in_trait_impl;
312
347
}
313
348
314
349
fn visit_trait_item ( & mut self , ti : & ' tcx hir:: TraitItem < ' tcx > ) {
315
- self . annotate ( ti. hir_id , & ti. attrs , ti. span , AnnotationKind :: Required , |v| {
316
- intravisit:: walk_trait_item ( v, ti) ;
317
- } ) ;
350
+ self . annotate (
351
+ ti. hir_id ,
352
+ & ti. attrs ,
353
+ ti. span ,
354
+ AnnotationKind :: Required ,
355
+ InheritDeprecation :: Yes ,
356
+ |v| {
357
+ intravisit:: walk_trait_item ( v, ti) ;
358
+ } ,
359
+ ) ;
318
360
}
319
361
320
362
fn visit_impl_item ( & mut self , ii : & ' tcx hir:: ImplItem < ' tcx > ) {
321
363
let kind =
322
364
if self . in_trait_impl { AnnotationKind :: Prohibited } else { AnnotationKind :: Required } ;
323
- self . annotate ( ii. hir_id , & ii. attrs , ii. span , kind, |v| {
365
+ self . annotate ( ii. hir_id , & ii. attrs , ii. span , kind, InheritDeprecation :: Yes , |v| {
324
366
intravisit:: walk_impl_item ( v, ii) ;
325
367
} ) ;
326
368
}
327
369
328
370
fn visit_variant ( & mut self , var : & ' tcx Variant < ' tcx > , g : & ' tcx Generics < ' tcx > , item_id : HirId ) {
329
- self . annotate ( var. id , & var. attrs , var. span , AnnotationKind :: Required , |v| {
330
- if let Some ( ctor_hir_id) = var. data . ctor_hir_id ( ) {
331
- v. annotate ( ctor_hir_id, & var. attrs , var. span , AnnotationKind :: Required , |_| { } ) ;
332
- }
371
+ self . annotate (
372
+ var. id ,
373
+ & var. attrs ,
374
+ var. span ,
375
+ AnnotationKind :: Required ,
376
+ InheritDeprecation :: Yes ,
377
+ |v| {
378
+ if let Some ( ctor_hir_id) = var. data . ctor_hir_id ( ) {
379
+ v. annotate (
380
+ ctor_hir_id,
381
+ & var. attrs ,
382
+ var. span ,
383
+ AnnotationKind :: Required ,
384
+ InheritDeprecation :: Yes ,
385
+ |_| { } ,
386
+ ) ;
387
+ }
333
388
334
- intravisit:: walk_variant ( v, var, g, item_id)
335
- } )
389
+ intravisit:: walk_variant ( v, var, g, item_id)
390
+ } ,
391
+ )
336
392
}
337
393
338
394
fn visit_struct_field ( & mut self , s : & ' tcx StructField < ' tcx > ) {
339
- self . annotate ( s. hir_id , & s. attrs , s. span , AnnotationKind :: Required , |v| {
340
- intravisit:: walk_struct_field ( v, s) ;
341
- } ) ;
395
+ self . annotate (
396
+ s. hir_id ,
397
+ & s. attrs ,
398
+ s. span ,
399
+ AnnotationKind :: Required ,
400
+ InheritDeprecation :: Yes ,
401
+ |v| {
402
+ intravisit:: walk_struct_field ( v, s) ;
403
+ } ,
404
+ ) ;
342
405
}
343
406
344
407
fn visit_foreign_item ( & mut self , i : & ' tcx hir:: ForeignItem < ' tcx > ) {
345
- self . annotate ( i. hir_id , & i. attrs , i. span , AnnotationKind :: Required , |v| {
346
- intravisit:: walk_foreign_item ( v, i) ;
347
- } ) ;
408
+ self . annotate (
409
+ i. hir_id ,
410
+ & i. attrs ,
411
+ i. span ,
412
+ AnnotationKind :: Required ,
413
+ InheritDeprecation :: Yes ,
414
+ |v| {
415
+ intravisit:: walk_foreign_item ( v, i) ;
416
+ } ,
417
+ ) ;
348
418
}
349
419
350
420
fn visit_macro_def ( & mut self , md : & ' tcx hir:: MacroDef < ' tcx > ) {
351
- self . annotate ( md. hir_id , & md. attrs , md. span , AnnotationKind :: Required , |_| { } ) ;
421
+ self . annotate (
422
+ md. hir_id ,
423
+ & md. attrs ,
424
+ md. span ,
425
+ AnnotationKind :: Required ,
426
+ InheritDeprecation :: Yes ,
427
+ |_| { } ,
428
+ ) ;
429
+ }
430
+
431
+ fn visit_generic_param ( & mut self , p : & ' tcx hir:: GenericParam < ' tcx > ) {
432
+ let kind = match & p. kind {
433
+ // FIXME(const_generics:defaults)
434
+ hir:: GenericParamKind :: Type { default, .. } if default. is_some ( ) => {
435
+ AnnotationKind :: Container
436
+ }
437
+ _ => AnnotationKind :: Prohibited ,
438
+ } ;
439
+
440
+ self . annotate ( p. hir_id , & p. attrs , p. span , kind, InheritDeprecation :: No , |v| {
441
+ intravisit:: walk_generic_param ( v, p) ;
442
+ } ) ;
352
443
}
353
444
}
354
445
@@ -422,6 +513,10 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
422
513
fn visit_macro_def ( & mut self , md : & ' tcx hir:: MacroDef < ' tcx > ) {
423
514
self . check_missing_stability ( md. hir_id , md. span ) ;
424
515
}
516
+
517
+ // Note that we don't need to `check_missing_stability` for default generic parameters,
518
+ // as we assume that any default generic parameters without attributes are automatically
519
+ // stable (assuming they have not inherited instability from their parent).
425
520
}
426
521
427
522
fn new_index ( tcx : TyCtxt < ' tcx > ) -> Index < ' tcx > {
@@ -484,6 +579,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
484
579
& krate. item . attrs ,
485
580
krate. item . span ,
486
581
AnnotationKind :: Required ,
582
+ InheritDeprecation :: Yes ,
487
583
|v| intravisit:: walk_crate ( v, krate) ,
488
584
) ;
489
585
}
0 commit comments