@@ -70,6 +70,17 @@ impl InheritConstStability {
7070 }
7171}
7272
73+ enum InheritStability {
74+ Yes ,
75+ No ,
76+ }
77+
78+ impl InheritStability {
79+ fn yes ( & self ) -> bool {
80+ matches ! ( self , InheritStability :: Yes )
81+ }
82+ }
83+
7384// A private tree-walker for producing an Index.
7485struct Annotator < ' a , ' tcx > {
7586 tcx : TyCtxt < ' tcx > ,
@@ -91,6 +102,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
91102 kind : AnnotationKind ,
92103 inherit_deprecation : InheritDeprecation ,
93104 inherit_const_stability : InheritConstStability ,
105+ inherit_from_parent : InheritStability ,
94106 visit_children : F ,
95107 ) where
96108 F : FnOnce ( & mut Self ) ,
@@ -131,12 +143,13 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
131143 }
132144
133145 if self . tcx . features ( ) . staged_api {
134- if let Some ( ..) = attrs. iter ( ) . find ( |a| self . tcx . sess . check_name ( a, sym:: deprecated) ) {
135- self . tcx . sess . span_err (
136- item_sp,
137- "`#[deprecated]` cannot be used in staged API; \
138- use `#[rustc_deprecated]` instead",
139- ) ;
146+ if let Some ( a) = attrs. iter ( ) . find ( |a| self . tcx . sess . check_name ( a, sym:: deprecated) ) {
147+ self . tcx
148+ . sess
149+ . struct_span_err ( a. span , "`#[deprecated]` cannot be used in staged API" )
150+ . span_label ( a. span , "use `#[rustc_deprecated]` instead" )
151+ . span_label ( item_sp, "" )
152+ . emit ( ) ;
140153 }
141154 } else {
142155 self . recurse_with_stability_attrs (
@@ -150,7 +163,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
150163
151164 let ( stab, const_stab) = attr:: find_stability ( & self . tcx . sess , attrs, item_sp) ;
152165
153- let const_stab = const_stab. map ( |const_stab| {
166+ let const_stab = const_stab. map ( |( const_stab, _ ) | {
154167 let const_stab = self . tcx . intern_const_stability ( const_stab) ;
155168 self . index . const_stab_map . insert ( hir_id, const_stab) ;
156169 const_stab
@@ -180,12 +193,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
180193 }
181194 }
182195
183- let stab = stab. map ( |stab| {
196+ let stab = stab. map ( |( stab, span ) | {
184197 // Error if prohibited, or can't inherit anything from a container.
185198 if kind == AnnotationKind :: Prohibited
186199 || ( kind == AnnotationKind :: Container && stab. level . is_stable ( ) && is_deprecated)
187200 {
188- self . tcx . sess . span_err ( item_sp, "This stability annotation is useless" ) ;
201+ self . tcx . sess . struct_span_err ( span, "this stability annotation is useless" )
202+ . span_label ( span, "useless stability annotation" )
203+ . span_label ( item_sp, "the stability attribute annotates this item" )
204+ . emit ( ) ;
189205 }
190206
191207 debug ! ( "annotate: found {:?}" , stab) ;
@@ -202,26 +218,30 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
202218 {
203219 match stab_v. parse :: < u64 > ( ) {
204220 Err ( _) => {
205- self . tcx . sess . span_err ( item_sp, "Invalid stability version found" ) ;
221+ self . tcx . sess . struct_span_err ( span, "invalid stability version found" )
222+ . span_label ( span, "invalid stability version" )
223+ . span_label ( item_sp, "the stability attribute annotates this item" )
224+ . emit ( ) ;
206225 break ;
207226 }
208227 Ok ( stab_vp) => match dep_v. parse :: < u64 > ( ) {
209228 Ok ( dep_vp) => match dep_vp. cmp ( & stab_vp) {
210229 Ordering :: Less => {
211- self . tcx . sess . span_err (
212- item_sp ,
213- "An API can't be stabilized after it is deprecated" ,
214- ) ;
230+ self . tcx . sess . struct_span_err ( span , "an API can't be stabilized after it is deprecated" )
231+ . span_label ( span , "invalid version" )
232+ . span_label ( item_sp , "the stability attribute annotates this item" )
233+ . emit ( ) ;
215234 break ;
216235 }
217236 Ordering :: Equal => continue ,
218237 Ordering :: Greater => break ,
219238 } ,
220239 Err ( _) => {
221240 if dep_v != "TBD" {
222- self . tcx
223- . sess
224- . span_err ( item_sp, "Invalid deprecation version found" ) ;
241+ self . tcx . sess . struct_span_err ( span, "invalid deprecation version found" )
242+ . span_label ( span, "invalid deprecation version" )
243+ . span_label ( item_sp, "the stability attribute annotates this item" )
244+ . emit ( ) ;
225245 }
226246 break ;
227247 }
@@ -237,7 +257,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
237257 if stab. is_none ( ) {
238258 debug ! ( "annotate: stab not found, parent = {:?}" , self . parent_stab) ;
239259 if let Some ( stab) = self . parent_stab {
240- if inherit_deprecation. yes ( ) && stab. level . is_unstable ( ) {
260+ if inherit_deprecation. yes ( ) && stab. level . is_unstable ( )
261+ || inherit_from_parent. yes ( )
262+ {
241263 self . index . stab_map . insert ( hir_id, stab) ;
242264 }
243265 }
@@ -368,6 +390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
368390 AnnotationKind :: Required ,
369391 InheritDeprecation :: Yes ,
370392 InheritConstStability :: No ,
393+ InheritStability :: Yes ,
371394 |_| { } ,
372395 )
373396 }
@@ -382,6 +405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
382405 kind,
383406 InheritDeprecation :: Yes ,
384407 const_stab_inherit,
408+ InheritStability :: No ,
385409 |v| intravisit:: walk_item ( v, i) ,
386410 ) ;
387411 self . in_trait_impl = orig_in_trait_impl;
@@ -395,6 +419,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
395419 AnnotationKind :: Required ,
396420 InheritDeprecation :: Yes ,
397421 InheritConstStability :: No ,
422+ InheritStability :: No ,
398423 |v| {
399424 intravisit:: walk_trait_item ( v, ti) ;
400425 } ,
@@ -411,6 +436,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
411436 kind,
412437 InheritDeprecation :: Yes ,
413438 InheritConstStability :: No ,
439+ InheritStability :: No ,
414440 |v| {
415441 intravisit:: walk_impl_item ( v, ii) ;
416442 } ,
@@ -425,6 +451,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
425451 AnnotationKind :: Required ,
426452 InheritDeprecation :: Yes ,
427453 InheritConstStability :: No ,
454+ InheritStability :: Yes ,
428455 |v| {
429456 if let Some ( ctor_hir_id) = var. data . ctor_hir_id ( ) {
430457 v. annotate (
@@ -434,6 +461,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
434461 AnnotationKind :: Required ,
435462 InheritDeprecation :: Yes ,
436463 InheritConstStability :: No ,
464+ InheritStability :: No ,
437465 |_| { } ,
438466 ) ;
439467 }
@@ -451,6 +479,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
451479 AnnotationKind :: Required ,
452480 InheritDeprecation :: Yes ,
453481 InheritConstStability :: No ,
482+ InheritStability :: Yes ,
454483 |v| {
455484 intravisit:: walk_struct_field ( v, s) ;
456485 } ,
@@ -465,6 +494,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
465494 AnnotationKind :: Required ,
466495 InheritDeprecation :: Yes ,
467496 InheritConstStability :: No ,
497+ InheritStability :: No ,
468498 |v| {
469499 intravisit:: walk_foreign_item ( v, i) ;
470500 } ,
@@ -479,6 +509,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
479509 AnnotationKind :: Required ,
480510 InheritDeprecation :: Yes ,
481511 InheritConstStability :: No ,
512+ InheritStability :: No ,
482513 |_| { } ,
483514 ) ;
484515 }
@@ -499,6 +530,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
499530 kind,
500531 InheritDeprecation :: No ,
501532 InheritConstStability :: No ,
533+ InheritStability :: No ,
502534 |v| {
503535 intravisit:: walk_generic_param ( v, p) ;
504536 } ,
@@ -669,6 +701,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
669701 AnnotationKind :: Required ,
670702 InheritDeprecation :: Yes ,
671703 InheritConstStability :: No ,
704+ InheritStability :: No ,
672705 |v| intravisit:: walk_crate ( v, krate) ,
673706 ) ;
674707 }
@@ -729,18 +762,13 @@ impl Visitor<'tcx> for Checker<'tcx> {
729762 // error if all involved types and traits are stable, because
730763 // it will have no effect.
731764 // See: https://github.com/rust-lang/rust/issues/55436
732- if let ( Some ( Stability { level : attr:: Unstable { .. } , .. } ) , _) =
765+ if let ( Some ( ( Stability { level : attr:: Unstable { .. } , .. } , span ) ) , _) =
733766 attr:: find_stability ( & self . tcx . sess , & item. attrs , item. span )
734767 {
735768 let mut c = CheckTraitImplStable { tcx : self . tcx , fully_stable : true } ;
736769 c. visit_ty ( self_ty) ;
737770 c. visit_trait_ref ( t) ;
738771 if c. fully_stable {
739- let span = item
740- . attrs
741- . iter ( )
742- . find ( |a| a. has_name ( sym:: unstable) )
743- . map_or ( item. span , |a| a. span ) ;
744772 self . tcx . struct_span_lint_hir (
745773 INEFFECTIVE_UNSTABLE_TRAIT_IMPL ,
746774 item. hir_id ( ) ,
0 commit comments