@@ -15,14 +15,14 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
1515use rustc_errors:: Applicability ;
1616use rustc_hir as hir;
1717use 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 } ;
1919use rustc_hir:: hir_id:: CRATE_HIR_ID ;
2020use rustc_hir:: intravisit:: { self , Visitor } ;
2121use rustc_hir:: { FieldDef , Item , ItemKind , TraitRef , Ty , TyKind , Variant } ;
2222use rustc_middle:: hir:: nested_filter;
2323use rustc_middle:: middle:: privacy:: EffectiveVisibilities ;
2424use rustc_middle:: middle:: stability:: { AllowUnstable , DeprecationEntry , Index } ;
25- use rustc_middle:: ty:: { query:: Providers , TyCtxt } ;
25+ use rustc_middle:: ty:: { query:: Providers , DefIdTree , TyCtxt } ;
2626use rustc_session:: lint;
2727use rustc_session:: lint:: builtin:: { INEFFECTIVE_UNSTABLE_TRAIT_IMPL , USELESS_DEPRECATED } ;
2828use rustc_span:: symbol:: { sym, Symbol } ;
@@ -90,13 +90,84 @@ impl InheritStability {
9090 }
9191}
9292
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+
93165/// A private tree-walker for producing an `Index`.
94166struct Annotator < ' a , ' tcx > {
95167 tcx : TyCtxt < ' tcx > ,
96168 index : & ' a mut Index ,
97169 parent_stab : Option < Stability > ,
98170 parent_const_stab : Option < ConstStability > ,
99- parent_depr : Option < DeprecationEntry > ,
100171 in_trait_impl : bool ,
101172}
102173
@@ -117,34 +188,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
117188 ) where
118189 F : FnOnce ( & mut Self ) ,
119190 {
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 ( ) ;
148193
149194 if !self . tcx . features ( ) . staged_api {
150195 // Propagate unstability. This can happen even for non-staged-api crates in case
@@ -155,15 +200,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
155200 }
156201 }
157202
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) ;
164204 return ;
165205 }
166206
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) ;
167209 let ( stab, const_stab, body_stab) = attr:: find_stability ( & self . tcx . sess , attrs, item_sp) ;
168210 let mut const_span = None ;
169211
@@ -201,9 +243,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
201243 }
202244 }
203245
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 } ) ;
207249 }
208250 }
209251
@@ -227,7 +269,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
227269 // Check if deprecated_since < stable_since. If it is,
228270 // this is *almost surely* an accident.
229271 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 )
231273 {
232274 // Explicit version of iter::order::lt to handle parse errors properly
233275 for ( dep_v, stab_v) in
@@ -282,7 +324,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
282324 }
283325
284326 self . recurse_with_stability_attrs (
285- depr. map ( |( d, _) | DeprecationEntry :: local ( d, def_id) ) ,
286327 stab,
287328 if inherit_const_stability. yes ( ) { const_stab } else { None } ,
288329 visit_children,
@@ -291,19 +332,14 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
291332
292333 fn recurse_with_stability_attrs (
293334 & mut self ,
294- depr : Option < DeprecationEntry > ,
295335 stab : Option < Stability > ,
296336 const_stab : Option < ConstStability > ,
297337 f : impl FnOnce ( & mut Self ) ,
298338 ) {
299339 // These will be `Some` if this item changes the corresponding stability attribute.
300- let mut replaced_parent_depr = None ;
301340 let mut replaced_parent_stab = None ;
302341 let mut replaced_parent_const_stab = None ;
303342
304- if let Some ( depr) = depr {
305- replaced_parent_depr = Some ( replace ( & mut self . parent_depr , Some ( depr) ) ) ;
306- }
307343 if let Some ( stab) = stab {
308344 replaced_parent_stab = Some ( replace ( & mut self . parent_stab , Some ( stab) ) ) ;
309345 }
@@ -314,9 +350,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
314350
315351 f ( self ) ;
316352
317- if let Some ( orig_parent_depr) = replaced_parent_depr {
318- self . parent_depr = orig_parent_depr;
319- }
320353 if let Some ( orig_parent_stab) = replaced_parent_stab {
321354 self . parent_stab = orig_parent_stab;
322355 }
@@ -627,7 +660,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
627660 stab_map : Default :: default ( ) ,
628661 const_stab_map : Default :: default ( ) ,
629662 default_body_stab_map : Default :: default ( ) ,
630- depr_map : Default :: default ( ) ,
631663 implications : Default :: default ( ) ,
632664 } ;
633665
@@ -637,7 +669,6 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
637669 index : & mut index,
638670 parent_stab : None ,
639671 parent_const_stab : None ,
640- parent_depr : None ,
641672 in_trait_impl : false ,
642673 } ;
643674
@@ -690,9 +721,7 @@ pub(crate) fn provide(providers: &mut Providers) {
690721 lookup_default_body_stability : |tcx, id| {
691722 tcx. stability ( ) . local_default_body_stability ( id. expect_local ( ) )
692723 } ,
693- lookup_deprecation_entry : |tcx, id| {
694- tcx. stability ( ) . local_deprecation_entry ( id. expect_local ( ) )
695- } ,
724+ lookup_deprecation_entry,
696725 ..* providers
697726 } ;
698727}
0 commit comments