Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b23f28d

Browse files
committed
Add sanity checks for reason and soft on unstable attributes
`reason` must appear at most once: it's the reason for the item being unstable, rather than a particular feature. This simplifies diagnostic formatting. `soft` must either be on all or no unstable attributes: it doesn't make sense for something to be partially soft, and allowing inconsistent softness markers would risk an item accidentally becoming properly unstable as its features stabilize.
1 parent edf10f8 commit b23f28d

File tree

6 files changed

+93
-5
lines changed

6 files changed

+93
-5
lines changed

‎compiler/rustc_attr/messages.ftl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ attr_multiple_item =
8585
attr_multiple_stability_levels =
8686
multiple stability levels for feature `{$feature}`
8787
88+
attr_multiple_unstable_reasons =
89+
multiple reasons provided for unstability
90+
8891
attr_non_ident_feature =
8992
'feature' is not an identifier
9093
@@ -97,6 +100,9 @@ attr_rustc_const_stable_indirect_pairing =
97100
attr_rustc_promotable_pairing =
98101
`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute
99102
103+
attr_soft_inconsistent =
104+
`soft` must be present on either none or all of an item's `unstable` attributes
105+
100106
attr_soft_no_args =
101107
`soft` should not have any arguments
102108

‎compiler/rustc_attr/src/builtin.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,11 +416,21 @@ fn add_level(
416416
(_, UnstableReason::None) => {}
417417
(reason @ UnstableReason::None, _) => *reason = new_reason,
418418
_ => {
419-
// TODO: sanity check for only one reason
419+
sess.dcx()
420+
.emit_err(session_diagnostics::MultipleUnstableReasons { span: attr.span });
420421
}
421422
}
422-
// TODO: sanity check for is_soft consistency
423-
*is_soft |= new_soft;
423+
// If any unstable attributes are marked 'soft', all should be. This keeps soft-unstable
424+
// items from accidentally being made properly unstable as attributes are removed.
425+
if *is_soft != new_soft {
426+
let spans = stab_spans
427+
.iter()
428+
.filter(|(stab, _)| stab.is_unstable())
429+
.map(|&(_, sp)| sp)
430+
.chain([attr.span])
431+
.collect();
432+
sess.dcx().emit_err(session_diagnostics::SoftInconsistent { spans });
433+
}
424434
}
425435
// an item with some stable and some unstable features is unstable
426436
(Some(Unstable { .. }), Stable { .. }) => {}

‎compiler/rustc_attr/src/session_diagnostics.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ pub(crate) struct MultipleStabilityLevels {
8383
pub feature: Symbol,
8484
}
8585

86+
#[derive(Diagnostic)]
87+
#[diag(attr_multiple_unstable_reasons)]
88+
pub(crate) struct MultipleUnstableReasons {
89+
#[primary_span]
90+
pub span: Span,
91+
}
92+
8693
#[derive(Diagnostic)]
8794
#[diag(attr_invalid_issue_string, code = E0545)]
8895
pub(crate) struct InvalidIssueString {
@@ -400,6 +407,13 @@ pub(crate) struct SoftNoArgs {
400407
pub span: Span,
401408
}
402409

410+
#[derive(Diagnostic)]
411+
#[diag(attr_soft_inconsistent)]
412+
pub(crate) struct SoftInconsistent {
413+
#[primary_span]
414+
pub spans: Vec<Span>,
415+
}
416+
403417
#[derive(Diagnostic)]
404418
#[diag(attr_unknown_version_literal)]
405419
pub(crate) struct UnknownVersionLiteral {

‎tests/ui/stability-attribute/mixed-levels.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ error: `const_unstable_fn` is not yet stable as a const fn
1313
LL | const USE_UNSTABLE: () = mixed_levels::const_unstable_fn();
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1515
|
16-
= note: use of unstable library feature `unstable_c`
1716
= help: add `#![feature(unstable_c)]` to the crate attributes to enable
18-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1917

2018
error: aborting due to 2 previous errors
2119

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! Checks that multiple stability attributes are used correctly together
2+
3+
#![feature(staged_api)]
4+
5+
#![stable(feature = "stable_test_feature", since = "1.0.0")]
6+
7+
#[unstable(feature = "a", issue = "none", reason = "reason 1")]
8+
#[unstable(feature = "b", issue = "none", reason = "reason 2")] //~ ERROR multiple reasons provided for unstability
9+
fn f1() { }
10+
11+
#[unstable(feature = "a", issue = "none", reason = "reason 1")]
12+
#[unstable(feature = "b", issue = "none", reason = "reason 2")] //~ ERROR multiple reasons provided for unstability
13+
#[unstable(feature = "c", issue = "none", reason = "reason 3")] //~ ERROR multiple reasons provided for unstability
14+
fn f2() { }
15+
16+
#[unstable(feature = "a", issue = "none")] //~ ERROR `soft` must be present on either none or all of an item's `unstable` attributes
17+
#[unstable(feature = "b", issue = "none", soft)]
18+
fn f3() { }
19+
20+
#[unstable(feature = "a", issue = "none", soft)] //~ ERROR `soft` must be present on either none or all of an item's `unstable` attributes
21+
#[unstable(feature = "b", issue = "none")]
22+
fn f4() { }
23+
24+
fn main() { }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error: multiple reasons provided for unstability
2+
--> $DIR/multiple-stability-attribute-sanity.rs:8:1
3+
|
4+
LL | #[unstable(feature = "b", issue = "none", reason = "reason 2")]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: multiple reasons provided for unstability
8+
--> $DIR/multiple-stability-attribute-sanity.rs:12:1
9+
|
10+
LL | #[unstable(feature = "b", issue = "none", reason = "reason 2")]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: multiple reasons provided for unstability
14+
--> $DIR/multiple-stability-attribute-sanity.rs:13:1
15+
|
16+
LL | #[unstable(feature = "c", issue = "none", reason = "reason 3")]
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
19+
error: `soft` must be present on either none or all of an item's `unstable` attributes
20+
--> $DIR/multiple-stability-attribute-sanity.rs:16:1
21+
|
22+
LL | #[unstable(feature = "a", issue = "none")]
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
LL | #[unstable(feature = "b", issue = "none", soft)]
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
27+
error: `soft` must be present on either none or all of an item's `unstable` attributes
28+
--> $DIR/multiple-stability-attribute-sanity.rs:20:1
29+
|
30+
LL | #[unstable(feature = "a", issue = "none", soft)]
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32+
LL | #[unstable(feature = "b", issue = "none")]
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
35+
error: aborting due to 5 previous errors
36+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /