@@ -37,6 +37,24 @@ enum AnnotationKind {
3737 Container ,
3838}
3939
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+
4058// A private tree-walker for producing an Index.
4159struct Annotator < ' a , ' tcx > {
4260 tcx : TyCtxt < ' tcx > ,
@@ -56,14 +74,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
5674 attrs : & [ Attribute ] ,
5775 item_sp : Span ,
5876 kind : AnnotationKind ,
77+ inherit_deprecation : InheritDeprecation ,
5978 visit_children : F ,
6079 ) where
6180 F : FnOnce ( & mut Self ) ,
6281 {
6382 debug ! ( "annotate(id = {:?}, attrs = {:?})" , hir_id, attrs) ;
6483 let mut did_error = false ;
6584 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 ( ) ) ;
6786 }
6887
6988 let depr =
@@ -80,9 +99,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
8099 let depr_entry = DeprecationEntry :: local ( depr. clone ( ) , hir_id) ;
81100 self . index . depr_map . insert ( hir_id, depr_entry) ;
82101 } 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+ }
86107 }
87108
88109 if self . tcx . features ( ) . staged_api {
@@ -186,7 +207,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
186207 if stab. is_none ( ) {
187208 debug ! ( "annotate: stab not found, parent = {:?}" , self . parent_stab) ;
188209 if let Some ( stab) = self . parent_stab {
189- if stab. level . is_unstable ( ) {
210+ if inherit_deprecation . yes ( ) && stab. level . is_unstable ( ) {
190211 self . index . stab_map . insert ( hir_id, stab) ;
191212 }
192213 }
@@ -237,7 +258,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
237258 }
238259
239260 // 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 {
241267 // Emit errors for non-staged-api crates.
242268 let unstable_attrs = [
243269 sym:: unstable,
@@ -265,7 +291,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
265291 // Propagate unstability. This can happen even for non-staged-api crates in case
266292 // -Zforce-unstable-if-unmarked is set.
267293 if let Some ( stab) = self . parent_stab {
268- if stab. level . is_unstable ( ) {
294+ if inherit_deprecation . yes ( ) && stab. level . is_unstable ( ) {
269295 self . index . stab_map . insert ( hir_id, stab) ;
270296 }
271297 }
@@ -301,54 +327,119 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
301327 }
302328 hir:: ItemKind :: Struct ( ref sd, _) => {
303329 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+ )
305338 }
306339 }
307340 _ => { }
308341 }
309342
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+ } ) ;
311346 self . in_trait_impl = orig_in_trait_impl;
312347 }
313348
314349 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+ ) ;
318360 }
319361
320362 fn visit_impl_item ( & mut self , ii : & ' tcx hir:: ImplItem < ' tcx > ) {
321363 let kind =
322364 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| {
324366 intravisit:: walk_impl_item ( v, ii) ;
325367 } ) ;
326368 }
327369
328370 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+ }
333388
334- intravisit:: walk_variant ( v, var, g, item_id)
335- } )
389+ intravisit:: walk_variant ( v, var, g, item_id)
390+ } ,
391+ )
336392 }
337393
338394 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+ ) ;
342405 }
343406
344407 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+ ) ;
348418 }
349419
350420 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+ } ) ;
352443 }
353444}
354445
@@ -422,6 +513,10 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
422513 fn visit_macro_def ( & mut self , md : & ' tcx hir:: MacroDef < ' tcx > ) {
423514 self . check_missing_stability ( md. hir_id , md. span ) ;
424515 }
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).
425520}
426521
427522fn new_index ( tcx : TyCtxt < ' tcx > ) -> Index < ' tcx > {
@@ -484,6 +579,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
484579 & krate. item . attrs ,
485580 krate. item . span ,
486581 AnnotationKind :: Required ,
582+ InheritDeprecation :: Yes ,
487583 |v| intravisit:: walk_crate ( v, krate) ,
488584 ) ;
489585 }
0 commit comments