@@ -70,6 +70,17 @@ impl InheritConstStability {
70
70
}
71
71
}
72
72
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
+
73
84
// A private tree-walker for producing an Index.
74
85
struct Annotator < ' a , ' tcx > {
75
86
tcx : TyCtxt < ' tcx > ,
@@ -91,6 +102,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
91
102
kind : AnnotationKind ,
92
103
inherit_deprecation : InheritDeprecation ,
93
104
inherit_const_stability : InheritConstStability ,
105
+ inherit_from_parent : InheritStability ,
94
106
visit_children : F ,
95
107
) where
96
108
F : FnOnce ( & mut Self ) ,
@@ -131,12 +143,13 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
131
143
}
132
144
133
145
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 ( ) ;
140
153
}
141
154
} else {
142
155
self . recurse_with_stability_attrs (
@@ -150,7 +163,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
150
163
151
164
let ( stab, const_stab) = attr:: find_stability ( & self . tcx . sess , attrs, item_sp) ;
152
165
153
- let const_stab = const_stab. map ( |const_stab| {
166
+ let const_stab = const_stab. map ( |( const_stab, _ ) | {
154
167
let const_stab = self . tcx . intern_const_stability ( const_stab) ;
155
168
self . index . const_stab_map . insert ( hir_id, const_stab) ;
156
169
const_stab
@@ -180,12 +193,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
180
193
}
181
194
}
182
195
183
- let stab = stab. map ( |stab| {
196
+ let stab = stab. map ( |( stab, span ) | {
184
197
// Error if prohibited, or can't inherit anything from a container.
185
198
if kind == AnnotationKind :: Prohibited
186
199
|| ( kind == AnnotationKind :: Container && stab. level . is_stable ( ) && is_deprecated)
187
200
{
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 ( ) ;
189
205
}
190
206
191
207
debug ! ( "annotate: found {:?}" , stab) ;
@@ -202,26 +218,30 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
202
218
{
203
219
match stab_v. parse :: < u64 > ( ) {
204
220
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 ( ) ;
206
225
break ;
207
226
}
208
227
Ok ( stab_vp) => match dep_v. parse :: < u64 > ( ) {
209
228
Ok ( dep_vp) => match dep_vp. cmp ( & stab_vp) {
210
229
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 ( ) ;
215
234
break ;
216
235
}
217
236
Ordering :: Equal => continue ,
218
237
Ordering :: Greater => break ,
219
238
} ,
220
239
Err ( _) => {
221
240
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 ( ) ;
225
245
}
226
246
break ;
227
247
}
@@ -237,7 +257,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
237
257
if stab. is_none ( ) {
238
258
debug ! ( "annotate: stab not found, parent = {:?}" , self . parent_stab) ;
239
259
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
+ {
241
263
self . index . stab_map . insert ( hir_id, stab) ;
242
264
}
243
265
}
@@ -368,6 +390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
368
390
AnnotationKind :: Required ,
369
391
InheritDeprecation :: Yes ,
370
392
InheritConstStability :: No ,
393
+ InheritStability :: Yes ,
371
394
|_| { } ,
372
395
)
373
396
}
@@ -382,6 +405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
382
405
kind,
383
406
InheritDeprecation :: Yes ,
384
407
const_stab_inherit,
408
+ InheritStability :: No ,
385
409
|v| intravisit:: walk_item ( v, i) ,
386
410
) ;
387
411
self . in_trait_impl = orig_in_trait_impl;
@@ -395,6 +419,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
395
419
AnnotationKind :: Required ,
396
420
InheritDeprecation :: Yes ,
397
421
InheritConstStability :: No ,
422
+ InheritStability :: No ,
398
423
|v| {
399
424
intravisit:: walk_trait_item ( v, ti) ;
400
425
} ,
@@ -411,6 +436,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
411
436
kind,
412
437
InheritDeprecation :: Yes ,
413
438
InheritConstStability :: No ,
439
+ InheritStability :: No ,
414
440
|v| {
415
441
intravisit:: walk_impl_item ( v, ii) ;
416
442
} ,
@@ -425,6 +451,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
425
451
AnnotationKind :: Required ,
426
452
InheritDeprecation :: Yes ,
427
453
InheritConstStability :: No ,
454
+ InheritStability :: Yes ,
428
455
|v| {
429
456
if let Some ( ctor_hir_id) = var. data . ctor_hir_id ( ) {
430
457
v. annotate (
@@ -434,6 +461,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
434
461
AnnotationKind :: Required ,
435
462
InheritDeprecation :: Yes ,
436
463
InheritConstStability :: No ,
464
+ InheritStability :: No ,
437
465
|_| { } ,
438
466
) ;
439
467
}
@@ -451,6 +479,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
451
479
AnnotationKind :: Required ,
452
480
InheritDeprecation :: Yes ,
453
481
InheritConstStability :: No ,
482
+ InheritStability :: Yes ,
454
483
|v| {
455
484
intravisit:: walk_struct_field ( v, s) ;
456
485
} ,
@@ -465,6 +494,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
465
494
AnnotationKind :: Required ,
466
495
InheritDeprecation :: Yes ,
467
496
InheritConstStability :: No ,
497
+ InheritStability :: No ,
468
498
|v| {
469
499
intravisit:: walk_foreign_item ( v, i) ;
470
500
} ,
@@ -479,6 +509,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
479
509
AnnotationKind :: Required ,
480
510
InheritDeprecation :: Yes ,
481
511
InheritConstStability :: No ,
512
+ InheritStability :: No ,
482
513
|_| { } ,
483
514
) ;
484
515
}
@@ -499,6 +530,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
499
530
kind,
500
531
InheritDeprecation :: No ,
501
532
InheritConstStability :: No ,
533
+ InheritStability :: No ,
502
534
|v| {
503
535
intravisit:: walk_generic_param ( v, p) ;
504
536
} ,
@@ -669,6 +701,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
669
701
AnnotationKind :: Required ,
670
702
InheritDeprecation :: Yes ,
671
703
InheritConstStability :: No ,
704
+ InheritStability :: No ,
672
705
|v| intravisit:: walk_crate ( v, krate) ,
673
706
) ;
674
707
}
@@ -729,18 +762,13 @@ impl Visitor<'tcx> for Checker<'tcx> {
729
762
// error if all involved types and traits are stable, because
730
763
// it will have no effect.
731
764
// 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 ) ) , _) =
733
766
attr:: find_stability ( & self . tcx . sess , & item. attrs , item. span )
734
767
{
735
768
let mut c = CheckTraitImplStable { tcx : self . tcx , fully_stable : true } ;
736
769
c. visit_ty ( self_ty) ;
737
770
c. visit_trait_ref ( t) ;
738
771
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 ) ;
744
772
self . tcx . struct_span_lint_hir (
745
773
INEFFECTIVE_UNSTABLE_TRAIT_IMPL ,
746
774
item. hir_id ( ) ,
0 commit comments