Skip to content

Commit 56befcd

Browse files
committed
Gate stability attrs with other attributes.
1 parent 7fcf0e2 commit 56befcd

14 files changed

+209
-163
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,31 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
420420
}
421421
}
422422
}
423+
424+
// Emit errors for non-staged-api crates.
425+
if !self.features.staged_api {
426+
if attr.has_name(sym::rustc_deprecated)
427+
|| attr.has_name(sym::unstable)
428+
|| attr.has_name(sym::stable)
429+
|| attr.has_name(sym::rustc_const_unstable)
430+
|| attr.has_name(sym::rustc_const_stable)
431+
{
432+
struct_span_err!(
433+
self.sess,
434+
attr.span,
435+
E0734,
436+
"stability attributes may not be used outside of the standard library",
437+
)
438+
.emit();
439+
}
440+
} else {
441+
if attr.has_name(sym::deprecated) {
442+
self.sess
443+
.struct_span_err(attr.span, "`#[deprecated]` cannot be used in staged API")
444+
.span_label(attr.span, "use `#[rustc_deprecated]` instead")
445+
.emit();
446+
}
447+
}
423448
}
424449

425450
fn visit_item(&mut self, i: &'a ast::Item) {

compiler/rustc_passes/src/stability.rs

Lines changed: 9 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! A pass that annotates every item and method with its stability level,
22
//! propagating default levels lexically from parent to children ast nodes.
33
4-
use rustc_ast::Attribute;
54
use rustc_attr::{self as attr, ConstStability, Stability};
65
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
76
use rustc_errors::struct_span_err;
@@ -113,12 +112,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
113112
{
114113
let attrs = self.tcx.get_attrs(def_id.to_def_id());
115114
debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
116-
let mut did_error = false;
117-
if !self.tcx.features().staged_api {
118-
did_error = self.forbid_staged_api_attrs(def_id, attrs, inherit_deprecation.clone());
119-
}
120115

121-
let depr = if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs) };
116+
let depr = attr::find_deprecation(&self.tcx.sess, attrs);
122117
let mut is_deprecated = false;
123118
if let Some((depr, span)) = &depr {
124119
is_deprecated = true;
@@ -148,16 +143,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
148143
}
149144
}
150145

151-
if self.tcx.features().staged_api {
152-
if let Some(a) = attrs.iter().find(|a| a.has_name(sym::deprecated)) {
153-
self.tcx
154-
.sess
155-
.struct_span_err(a.span, "`#[deprecated]` cannot be used in staged API")
156-
.span_label(a.span, "use `#[rustc_deprecated]` instead")
157-
.span_label(item_sp, "")
158-
.emit();
146+
if !self.tcx.features().staged_api {
147+
// Propagate unstability. This can happen even for non-staged-api crates in case
148+
// -Zforce-unstable-if-unmarked is set.
149+
if let Some(stab) = self.parent_stab {
150+
if inherit_deprecation.yes() && stab.level.is_unstable() {
151+
self.index.stab_map.insert(def_id, stab);
152+
}
159153
}
160-
} else {
154+
161155
self.recurse_with_stability_attrs(
162156
depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
163157
None,
@@ -329,47 +323,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
329323
self.parent_const_stab = orig_parent_const_stab;
330324
}
331325
}
332-
333-
// returns true if an error occurred, used to suppress some spurious errors
334-
fn forbid_staged_api_attrs(
335-
&mut self,
336-
def_id: LocalDefId,
337-
attrs: &[Attribute],
338-
inherit_deprecation: InheritDeprecation,
339-
) -> bool {
340-
// Emit errors for non-staged-api crates.
341-
let unstable_attrs = [
342-
sym::unstable,
343-
sym::stable,
344-
sym::rustc_deprecated,
345-
sym::rustc_const_unstable,
346-
sym::rustc_const_stable,
347-
];
348-
let mut has_error = false;
349-
for attr in attrs {
350-
let name = attr.name_or_empty();
351-
if unstable_attrs.contains(&name) {
352-
struct_span_err!(
353-
self.tcx.sess,
354-
attr.span,
355-
E0734,
356-
"stability attributes may not be used outside of the standard library",
357-
)
358-
.emit();
359-
has_error = true;
360-
}
361-
}
362-
363-
// Propagate unstability. This can happen even for non-staged-api crates in case
364-
// -Zforce-unstable-if-unmarked is set.
365-
if let Some(stab) = self.parent_stab {
366-
if inherit_deprecation.yes() && stab.level.is_unstable() {
367-
self.index.stab_map.insert(def_id, stab);
368-
}
369-
}
370-
371-
has_error
372-
}
373326
}
374327

375328
impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {

src/test/ui/deprecation/deprecation-in-staged-api.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ error: `#[deprecated]` cannot be used in staged API
33
|
44
LL | #[deprecated]
55
| ^^^^^^^^^^^^^ use `#[rustc_deprecated]` instead
6-
LL | fn main() {}
7-
| ------------
86

97
error: aborting due to previous error
108

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
error[E0734]: stability attributes may not be used outside of the standard library
2-
--> $DIR/feature-gate-staged_api.rs:1:1
3-
|
4-
LL | #![stable(feature = "a", since = "b")]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
71
error[E0734]: stability attributes may not be used outside of the standard library
82
--> $DIR/feature-gate-staged_api.rs:8:1
93
|
104
LL | #[stable(feature = "a", since = "b")]
115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
126

7+
error[E0734]: stability attributes may not be used outside of the standard library
8+
--> $DIR/feature-gate-staged_api.rs:1:1
9+
|
10+
LL | #![stable(feature = "a", since = "b")]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
1313
error: aborting due to 2 previous errors
1414

1515
For more information about this error, try `rustc --explain E0734`.

src/test/ui/feature-gates/issue-43106-gating-of-rustc_deprecated.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,38 @@
66

77
#![rustc_deprecated()]
88
//~^ ERROR stability attributes may not be used outside of the standard library
9+
//~| ERROR missing 'since' [E0542]
910

1011
#[rustc_deprecated()]
1112
//~^ ERROR stability attributes may not be used outside of the standard library
13+
//~| ERROR missing 'since' [E0542]
1214
mod rustc_deprecated {
13-
mod inner { #![rustc_deprecated()] }
14-
//~^ ERROR stability attributes may not be used outside of the standard library
15+
mod inner {
16+
#![rustc_deprecated()]
17+
//~^ ERROR stability attributes may not be used outside of the standard library
18+
//~| ERROR missing 'since' [E0542]
19+
}
1520

16-
#[rustc_deprecated()] fn f() { }
21+
#[rustc_deprecated()]
1722
//~^ ERROR stability attributes may not be used outside of the standard library
23+
//~| ERROR missing 'since' [E0542]
24+
fn f() {}
1825

19-
#[rustc_deprecated()] struct S;
26+
#[rustc_deprecated()]
2027
//~^ ERROR stability attributes may not be used outside of the standard library
21-
//~| ERROR stability attributes may not be used outside of the standard library
28+
//~| ERROR missing 'since' [E0542]
29+
//~| ERROR missing 'since' [E0542]
30+
struct S;
2231

23-
#[rustc_deprecated()] type T = S;
32+
#[rustc_deprecated()]
2433
//~^ ERROR stability attributes may not be used outside of the standard library
34+
//~| ERROR missing 'since' [E0542]
35+
type T = S;
2536

26-
#[rustc_deprecated()] impl S { }
37+
#[rustc_deprecated()]
2738
//~^ ERROR stability attributes may not be used outside of the standard library
39+
//~| ERROR missing 'since' [E0542]
40+
impl S {}
2841
}
2942

3043
fn main() {}
Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,94 @@
11
error[E0734]: stability attributes may not be used outside of the standard library
2-
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:7:1
2+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:16:9
33
|
4-
LL | #![rustc_deprecated()]
5-
| ^^^^^^^^^^^^^^^^^^^^^^
4+
LL | #![rustc_deprecated()]
5+
| ^^^^^^^^^^^^^^^^^^^^^^
66

77
error[E0734]: stability attributes may not be used outside of the standard library
8-
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:10:1
8+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:21:5
99
|
10-
LL | #[rustc_deprecated()]
11-
| ^^^^^^^^^^^^^^^^^^^^^
10+
LL | #[rustc_deprecated()]
11+
| ^^^^^^^^^^^^^^^^^^^^^
1212

1313
error[E0734]: stability attributes may not be used outside of the standard library
14-
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:13:17
14+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:26:5
1515
|
16-
LL | mod inner { #![rustc_deprecated()] }
17-
| ^^^^^^^^^^^^^^^^^^^^^^
16+
LL | #[rustc_deprecated()]
17+
| ^^^^^^^^^^^^^^^^^^^^^
1818

1919
error[E0734]: stability attributes may not be used outside of the standard library
20-
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:16:5
20+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:32:5
2121
|
22-
LL | #[rustc_deprecated()] fn f() { }
22+
LL | #[rustc_deprecated()]
2323
| ^^^^^^^^^^^^^^^^^^^^^
2424

2525
error[E0734]: stability attributes may not be used outside of the standard library
26-
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:19:5
26+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:37:5
2727
|
28-
LL | #[rustc_deprecated()] struct S;
28+
LL | #[rustc_deprecated()]
2929
| ^^^^^^^^^^^^^^^^^^^^^
3030

3131
error[E0734]: stability attributes may not be used outside of the standard library
32-
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:19:5
32+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:11:1
3333
|
34-
LL | #[rustc_deprecated()] struct S;
35-
| ^^^^^^^^^^^^^^^^^^^^^
34+
LL | #[rustc_deprecated()]
35+
| ^^^^^^^^^^^^^^^^^^^^^
3636

3737
error[E0734]: stability attributes may not be used outside of the standard library
38-
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:23:5
38+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:7:1
39+
|
40+
LL | #![rustc_deprecated()]
41+
| ^^^^^^^^^^^^^^^^^^^^^^
42+
43+
error[E0542]: missing 'since'
44+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:7:1
45+
|
46+
LL | #![rustc_deprecated()]
47+
| ^^^^^^^^^^^^^^^^^^^^^^
48+
49+
error[E0542]: missing 'since'
50+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:11:1
51+
|
52+
LL | #[rustc_deprecated()]
53+
| ^^^^^^^^^^^^^^^^^^^^^
54+
55+
error[E0542]: missing 'since'
56+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:16:9
57+
|
58+
LL | #![rustc_deprecated()]
59+
| ^^^^^^^^^^^^^^^^^^^^^^
60+
61+
error[E0542]: missing 'since'
62+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:21:5
3963
|
40-
LL | #[rustc_deprecated()] type T = S;
64+
LL | #[rustc_deprecated()]
4165
| ^^^^^^^^^^^^^^^^^^^^^
4266

43-
error[E0734]: stability attributes may not be used outside of the standard library
67+
error[E0542]: missing 'since'
4468
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:26:5
4569
|
46-
LL | #[rustc_deprecated()] impl S { }
70+
LL | #[rustc_deprecated()]
71+
| ^^^^^^^^^^^^^^^^^^^^^
72+
73+
error[E0542]: missing 'since'
74+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:26:5
75+
|
76+
LL | #[rustc_deprecated()]
77+
| ^^^^^^^^^^^^^^^^^^^^^
78+
79+
error[E0542]: missing 'since'
80+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:32:5
81+
|
82+
LL | #[rustc_deprecated()]
83+
| ^^^^^^^^^^^^^^^^^^^^^
84+
85+
error[E0542]: missing 'since'
86+
--> $DIR/issue-43106-gating-of-rustc_deprecated.rs:37:5
87+
|
88+
LL | #[rustc_deprecated()]
4789
| ^^^^^^^^^^^^^^^^^^^^^
4890

49-
error: aborting due to 8 previous errors
91+
error: aborting due to 15 previous errors
5092

51-
For more information about this error, try `rustc --explain E0734`.
93+
Some errors have detailed explanations: E0542, E0734.
94+
For more information about an error, try `rustc --explain E0542`.

src/test/ui/feature-gates/issue-43106-gating-of-stable.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,26 @@
1010
#[stable()]
1111
//~^ ERROR stability attributes may not be used outside of the standard library
1212
mod stable {
13-
mod inner { #![stable()] }
14-
//~^ ERROR stability attributes may not be used outside of the standard library
13+
mod inner {
14+
#![stable()]
15+
//~^ ERROR stability attributes may not be used outside of the standard library
16+
}
1517

16-
#[stable()] fn f() { }
18+
#[stable()]
1719
//~^ ERROR stability attributes may not be used outside of the standard library
20+
fn f() {}
1821

19-
#[stable()] struct S;
22+
#[stable()]
2023
//~^ ERROR stability attributes may not be used outside of the standard library
21-
//~| ERROR stability attributes may not be used outside of the standard library
24+
struct S;
2225

23-
#[stable()] type T = S;
26+
#[stable()]
2427
//~^ ERROR stability attributes may not be used outside of the standard library
28+
type T = S;
2529

26-
#[stable()] impl S { }
30+
#[stable()]
2731
//~^ ERROR stability attributes may not be used outside of the standard library
32+
impl S {}
2833
}
2934

3035
fn main() {}

0 commit comments

Comments
 (0)