Auto merge of #116773 - dtolnay:validatestable, r=compiler-errors
Validate `feature` and `since` values inside `#[stable(…)]` Previously the string passed to `#[unstable(feature = "...")]` would be validated as an identifier, but not `#[stable(feature = "...")]`. In the standard library there were `stable` attributes containing the empty string, and kebab-case string, neither of which should be allowed. Pre-existing validation of `unstable`: ```rust // src/lib.rs #![allow(internal_features)] #![feature(staged_api)] #![unstable(feature = "kebab-case", issue = "none")] #[unstable(feature = "kebab-case", issue = "none")] pub struct Struct; ``` ```console error[E0546]: 'feature' is not an identifier --> src/lib.rs:5:1 | 5 | #![unstable(feature = "kebab-case", issue = "none")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` For an `unstable` attribute, the need for an identifier is obvious because the downstream code needs to write a `#![feature(...)]` attribute containing that identifier. `#![feature(kebab-case)]` is not valid syntax and `#![feature(kebab_case)]` would not work if that is not the name of the feature. Having a valid identifier even in `stable` is less essential but still useful because it allows for informative diagnostic about the stabilization of a feature. Compare: ```rust // src/lib.rs #![allow(internal_features)] #![feature(staged_api)] #![stable(feature = "kebab-case", since = "1.0.0")] #[stable(feature = "kebab-case", since = "1.0.0")] pub struct Struct; ``` ```rust // src/main.rs #![feature(kebab_case)] use repro::Struct; fn main() {} ``` ```console error[E0635]: unknown feature `kebab_case` --> src/main.rs:3:12 | 3 | #![feature(kebab_case)] | ^^^^^^^^^^ ``` vs the situation if we correctly use `feature = "snake_case"` and `#![feature(snake_case)]`, as enforced by this PR: ```console warning: the feature `snake_case` has been stable since 1.0.0 and no longer requires an attribute to enable --> src/main.rs:3:12 | 3 | #![feature(snake_case)] | ^^^^^^^^^^ | = note: `#[warn(stable_features)]` on by default ```
This commit is contained in:
commit
07a4b7e2a9
23 changed files with 138 additions and 110 deletions
|
@ -58,6 +58,9 @@ attr_invalid_repr_hint_no_paren =
|
|||
attr_invalid_repr_hint_no_value =
|
||||
invalid representation hint: `{$name}` does not take a value
|
||||
|
||||
attr_invalid_since =
|
||||
'since' must be a Rust version number, such as "1.31.0"
|
||||
|
||||
attr_missing_feature =
|
||||
missing 'feature'
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use rustc_ast::{self as ast, attr};
|
||||
use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_session::config::ExpectedValues;
|
||||
|
@ -361,25 +362,32 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(s) = since
|
||||
&& s.as_str() == VERSION_PLACEHOLDER
|
||||
{
|
||||
since = Some(rust_version_symbol());
|
||||
}
|
||||
let feature = match feature {
|
||||
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
|
||||
Some(_bad_feature) => {
|
||||
Err(sess.emit_err(session_diagnostics::NonIdentFeature { span: attr.span }))
|
||||
}
|
||||
None => Err(sess.emit_err(session_diagnostics::MissingFeature { span: attr.span })),
|
||||
};
|
||||
|
||||
let since = if let Some(since) = since {
|
||||
if since.as_str() == VERSION_PLACEHOLDER {
|
||||
Ok(rust_version_symbol())
|
||||
} else if parse_version(since.as_str(), false).is_some() {
|
||||
Ok(since)
|
||||
} else {
|
||||
Err(sess.emit_err(session_diagnostics::InvalidSince { span: attr.span }))
|
||||
}
|
||||
} else {
|
||||
Err(sess.emit_err(session_diagnostics::MissingSince { span: attr.span }))
|
||||
};
|
||||
|
||||
match (feature, since) {
|
||||
(Some(feature), Some(since)) => {
|
||||
(Ok(feature), Ok(since)) => {
|
||||
let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false };
|
||||
Some((feature, level))
|
||||
}
|
||||
(None, _) => {
|
||||
sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
|
||||
None
|
||||
}
|
||||
_ => {
|
||||
sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
|
||||
None
|
||||
}
|
||||
(Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,12 +459,19 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
|
|||
}
|
||||
}
|
||||
|
||||
match (feature, reason, issue) {
|
||||
(Some(feature), reason, Some(_)) => {
|
||||
if !rustc_lexer::is_ident(feature.as_str()) {
|
||||
sess.emit_err(session_diagnostics::NonIdentFeature { span: attr.span });
|
||||
return None;
|
||||
}
|
||||
let feature = match feature {
|
||||
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
|
||||
Some(_bad_feature) => {
|
||||
Err(sess.emit_err(session_diagnostics::NonIdentFeature { span: attr.span }))
|
||||
}
|
||||
None => Err(sess.emit_err(session_diagnostics::MissingFeature { span: attr.span })),
|
||||
};
|
||||
|
||||
let issue =
|
||||
issue.ok_or_else(|| sess.emit_err(session_diagnostics::MissingIssue { span: attr.span }));
|
||||
|
||||
match (feature, issue) {
|
||||
(Ok(feature), Ok(_)) => {
|
||||
let level = StabilityLevel::Unstable {
|
||||
reason: UnstableReason::from_opt_reason(reason),
|
||||
issue: issue_num,
|
||||
|
@ -465,14 +480,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
|
|||
};
|
||||
Some((feature, level))
|
||||
}
|
||||
(None, _, _) => {
|
||||
sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
|
||||
return None;
|
||||
}
|
||||
_ => {
|
||||
sess.emit_err(session_diagnostics::MissingIssue { span: attr.span });
|
||||
return None;
|
||||
}
|
||||
(Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -370,6 +370,13 @@ pub(crate) struct ExpectsFeatures {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_invalid_since)]
|
||||
pub(crate) struct InvalidSince {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_soft_no_args)]
|
||||
pub(crate) struct SoftNoArgs {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
//! match those defined by C, so that code that interacts with C will
|
||||
//! refer to the correct types.
|
||||
|
||||
#![stable(feature = "", since = "1.30.0")]
|
||||
#![stable(feature = "core_ffi", since = "1.30.0")]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use crate::fmt;
|
||||
|
|
|
@ -1140,10 +1140,10 @@ pub fn read_to_string<R: Read>(mut reader: R) -> Result<String> {
|
|||
#[repr(transparent)]
|
||||
pub struct IoSliceMut<'a>(sys::io::IoSliceMut<'a>);
|
||||
|
||||
#[stable(feature = "iovec-send-sync", since = "1.44.0")]
|
||||
#[stable(feature = "iovec_send_sync", since = "1.44.0")]
|
||||
unsafe impl<'a> Send for IoSliceMut<'a> {}
|
||||
|
||||
#[stable(feature = "iovec-send-sync", since = "1.44.0")]
|
||||
#[stable(feature = "iovec_send_sync", since = "1.44.0")]
|
||||
unsafe impl<'a> Sync for IoSliceMut<'a> {}
|
||||
|
||||
#[stable(feature = "iovec", since = "1.36.0")]
|
||||
|
@ -1283,10 +1283,10 @@ impl<'a> DerefMut for IoSliceMut<'a> {
|
|||
#[repr(transparent)]
|
||||
pub struct IoSlice<'a>(sys::io::IoSlice<'a>);
|
||||
|
||||
#[stable(feature = "iovec-send-sync", since = "1.44.0")]
|
||||
#[stable(feature = "iovec_send_sync", since = "1.44.0")]
|
||||
unsafe impl<'a> Send for IoSlice<'a> {}
|
||||
|
||||
#[stable(feature = "iovec-send-sync", since = "1.44.0")]
|
||||
#[stable(feature = "iovec_send_sync", since = "1.44.0")]
|
||||
unsafe impl<'a> Sync for IoSlice<'a> {}
|
||||
|
||||
#[stable(feature = "iovec", since = "1.36.0")]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// This file provides a const function that is unstably const forever.
|
||||
|
||||
#![feature(staged_api)]
|
||||
#![stable(feature = "1", since = "1.0.0")]
|
||||
#![stable(feature = "clippytest", since = "1.0.0")]
|
||||
|
||||
#[stable(feature = "1", since = "1.0.0")]
|
||||
#[stable(feature = "clippytest", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "foo", issue = "none")]
|
||||
pub const fn unstably_const_fn() {}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#![feature(staged_api)]
|
||||
#![stable(feature = "deprecated-future-staged-api", since = "1.0.0")]
|
||||
#![stable(feature = "deprecated_future_staged_api", since = "1.0.0")]
|
||||
|
||||
// @has deprecated_future_staged_api/index.html '//*[@class="stab deprecated"]' \
|
||||
// 'Deprecation planned'
|
||||
// @has deprecated_future_staged_api/struct.S1.html '//*[@class="stab deprecated"]' \
|
||||
// 'Deprecating in 99.99.99: effectively never'
|
||||
#[deprecated(since = "99.99.99", note = "effectively never")]
|
||||
#[stable(feature = "deprecated-future-staged-api", since = "1.0.0")]
|
||||
#[stable(feature = "deprecated_future_staged_api", since = "1.0.0")]
|
||||
pub struct S1;
|
||||
|
||||
// @has deprecated_future_staged_api/index.html '//*[@class="stab deprecated"]' \
|
||||
|
@ -14,5 +14,5 @@ pub struct S1;
|
|||
// @has deprecated_future_staged_api/struct.S2.html '//*[@class="stab deprecated"]' \
|
||||
// 'Deprecating in a future Rust version: literally never'
|
||||
#[deprecated(since = "TBD", note = "literally never")]
|
||||
#[stable(feature = "deprecated-future-staged-api", since = "1.0.0")]
|
||||
#[stable(feature = "deprecated_future_staged_api", since = "1.0.0")]
|
||||
pub struct S2;
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
#![stable(feature = "bar", since = "OLD 1.0")]
|
||||
#![stable(feature = "bar", since = "3.3.3")]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
#![feature(staged_api)]
|
||||
|
||||
#[stable(feature = "bar", since = "OLD 1.0")]
|
||||
#[stable(feature = "bar", since = "3.3.3")]
|
||||
pub trait Bar {}
|
||||
|
||||
#[stable(feature = "baz", since = "OLD 1.0")]
|
||||
#[stable(feature = "baz", since = "3.3.3")]
|
||||
pub trait Baz {}
|
||||
|
||||
#[stable(feature = "baz", since = "OLD 1.0")]
|
||||
#[stable(feature = "baz", since = "3.3.3")]
|
||||
pub struct Foo;
|
||||
|
||||
// @has foo/trait.Bar.html '//div[@id="implementors-list"]//span[@class="since"]' 'NEW 2.0'
|
||||
#[stable(feature = "foobar", since = "NEW 2.0")]
|
||||
// @has foo/trait.Bar.html '//div[@id="implementors-list"]//span[@class="since"]' '4.4.4'
|
||||
#[stable(feature = "foobar", since = "4.4.4")]
|
||||
impl Bar for Foo {}
|
||||
|
||||
// @!has foo/trait.Baz.html '//div[@id="implementors-list"]//span[@class="since"]' 'OLD 1.0'
|
||||
#[stable(feature = "foobaz", since = "OLD 1.0")]
|
||||
// @!has foo/trait.Baz.html '//div[@id="implementors-list"]//span[@class="since"]' '3.3.3'
|
||||
#[stable(feature = "foobaz", since = "3.3.3")]
|
||||
impl Baz for Foo {}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![feature(staged_api)]
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
#[rustc_const_stable(feature = "foo", since = "0")]
|
||||
#[rustc_const_stable(feature = "foo", since = "3.3.3")]
|
||||
//~^ ERROR macros cannot have const stability attributes
|
||||
macro_rules! foo {
|
||||
() => {};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error: macros cannot have const stability attributes
|
||||
--> $DIR/const-stability-on-macro.rs:4:1
|
||||
|
|
||||
LL | #[rustc_const_stable(feature = "foo", since = "0")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
|
||||
LL | #[rustc_const_stable(feature = "foo", since = "3.3.3")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
|
||||
LL |
|
||||
LL | macro_rules! foo {
|
||||
| ---------------- const stability attribute affects this macro
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
// FIXME(const_generics_defaults): It seems like we aren't testing the right thing here,
|
||||
// I would assume that we want the attributes to apply to the const parameter defaults
|
||||
// themselves.
|
||||
#![stable(feature = "const_default_test", since="none")]
|
||||
#![stable(feature = "const_default_test", since = "3.3.3")]
|
||||
|
||||
#[unstable(feature = "const_default_stable", issue="none")]
|
||||
#[unstable(feature = "const_default_stable", issue = "none")]
|
||||
pub struct ConstDefaultUnstable<const N: usize = 3>;
|
||||
|
||||
#[stable(feature = "const_default_unstable", since="none")]
|
||||
#[stable(feature = "const_default_unstable", since = "3.3.3")]
|
||||
pub struct ConstDefaultStable<const N: usize = {
|
||||
3
|
||||
}>;
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
#![feature(staged_api)]
|
||||
|
||||
#![stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
|
||||
#![stable(feature = "rustc_deprecation_in_future_test", since = "1.0.0")]
|
||||
|
||||
#[deprecated(since = "99.99.99", note = "effectively never")]
|
||||
#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
|
||||
#[stable(feature = "rustc_deprecation_in_future_test", since = "1.0.0")]
|
||||
pub struct S1;
|
||||
|
||||
#[deprecated(since = "TBD", note = "literally never")]
|
||||
#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
|
||||
#[stable(feature = "rustc_deprecation_in_future_test", since = "1.0.0")]
|
||||
pub struct S2;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#![stable(feature = "a", since = "b")]
|
||||
#![stable(feature = "a", since = "3.3.3")]
|
||||
//~^ ERROR stability attributes may not be used outside of the standard library
|
||||
mod inner_private_module {
|
||||
// UnnameableTypeAlias isn't marked as reachable, so no stability annotation is required here
|
||||
pub type UnnameableTypeAlias = u8;
|
||||
}
|
||||
|
||||
#[stable(feature = "a", since = "b")]
|
||||
#[stable(feature = "a", since = "3.3.3")]
|
||||
//~^ ERROR stability attributes may not be used outside of the standard library
|
||||
pub fn f() -> inner_private_module::UnnameableTypeAlias {
|
||||
0
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
error[E0734]: stability attributes may not be used outside of the standard library
|
||||
--> $DIR/feature-gate-staged_api.rs:8:1
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "b")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[stable(feature = "a", since = "3.3.3")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0734]: stability attributes may not be used outside of the standard library
|
||||
--> $DIR/feature-gate-staged_api.rs:1:1
|
||||
|
|
||||
LL | #![stable(feature = "a", since = "b")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #![stable(feature = "a", since = "3.3.3")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// run-pass
|
||||
|
||||
#![feature(staged_api)]
|
||||
#![stable(feature = "a", since = "b")]
|
||||
#![stable(feature = "a", since = "3.3.3")]
|
||||
|
||||
mod inner_private_module {
|
||||
// UnnameableTypeAlias isn't marked as reachable, so no stability annotation is required here
|
||||
pub type UnnameableTypeAlias = u8;
|
||||
}
|
||||
|
||||
#[stable(feature = "a", since = "b")]
|
||||
#[stable(feature = "a", since = "3.3.3")]
|
||||
pub fn f() -> inner_private_module::UnnameableTypeAlias {
|
||||
0
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)]
|
||||
#![no_core]
|
||||
#![crate_type = "lib"]
|
||||
#![stable(feature = "", since = "")]
|
||||
#![stable(feature = "intrinsics_for_test", since = "3.3.3")]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Test that the repr(C) attribute doesn't break compilation
|
||||
|
@ -22,8 +22,8 @@ enum Foo {
|
|||
}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
#[stable(feature = "", since = "")]
|
||||
#[rustc_const_stable(feature = "", since = "")]
|
||||
#[stable(feature = "intrinsics_for_test", since = "3.3.3")]
|
||||
#[rustc_const_stable(feature = "intrinsics_for_test", since = "3.3.3")]
|
||||
#[rustc_safe_intrinsic]
|
||||
fn size_of<T>() -> usize;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#![feature(staged_api)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![stable(since = "1", feature = "foo")]
|
||||
#![stable(feature = "foo", since = "3.3.3")]
|
||||
|
||||
#[const_trait]
|
||||
trait Tr {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// check-pass
|
||||
#![feature(staged_api)]
|
||||
#![stable(feature = "test", since = "0")]
|
||||
#![stable(feature = "test", since = "3.3.3")]
|
||||
|
||||
#[stable(feature = "test", since = "0")]
|
||||
#[stable(feature = "test", since = "3.3.3")]
|
||||
pub struct A<T>(pub T);
|
||||
|
||||
#[stable(feature = "test", since = "0")]
|
||||
pub struct B<T>(#[stable(feature = "test", since = "0")] pub T);
|
||||
#[stable(feature = "test", since = "3.3.3")]
|
||||
pub struct B<T>(#[stable(feature = "test", since = "3.3.3")] pub T);
|
||||
|
||||
fn main() {
|
||||
// Make sure the field is used to fill the stability cache
|
||||
|
|
|
@ -17,11 +17,11 @@ mod bogus_attribute_types_2 {
|
|||
#[stable = "a"] //~ ERROR malformed `stable` attribute
|
||||
fn f4() { }
|
||||
|
||||
#[stable(feature = "a", since = "b")]
|
||||
#[stable(feature = "a", since = "3.3.3")]
|
||||
#[deprecated] //~ ERROR missing 'since'
|
||||
fn f5() { }
|
||||
|
||||
#[stable(feature = "a", since = "b")]
|
||||
#[stable(feature = "a", since = "3.3.3")]
|
||||
#[deprecated = "a"] //~ ERROR missing 'since'
|
||||
fn f6() { }
|
||||
}
|
||||
|
|
|
@ -5,19 +5,19 @@
|
|||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
mod bogus_attribute_types_1 {
|
||||
#[stable(feature = "a", since = "b", reason)] //~ ERROR unknown meta item 'reason' [E0541]
|
||||
#[stable(feature = "a", since = "4.4.4", reason)] //~ ERROR unknown meta item 'reason' [E0541]
|
||||
fn f1() { }
|
||||
|
||||
#[stable(feature = "a", since)] //~ ERROR incorrect meta item [E0539]
|
||||
fn f2() { }
|
||||
|
||||
#[stable(feature, since = "a")] //~ ERROR incorrect meta item [E0539]
|
||||
#[stable(feature, since = "3.3.3")] //~ ERROR incorrect meta item [E0539]
|
||||
fn f3() { }
|
||||
|
||||
#[stable(feature = "a", since(b))] //~ ERROR incorrect meta item [E0539]
|
||||
fn f5() { }
|
||||
|
||||
#[stable(feature(b), since = "a")] //~ ERROR incorrect meta item [E0539]
|
||||
#[stable(feature(b), since = "3.3.3")] //~ ERROR incorrect meta item [E0539]
|
||||
fn f6() { }
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ mod missing_feature_names {
|
|||
#[unstable(feature = "b")] //~ ERROR missing 'issue' [E0547]
|
||||
fn f2() { }
|
||||
|
||||
#[stable(since = "a")] //~ ERROR missing 'feature' [E0546]
|
||||
#[stable(since = "3.3.3")] //~ ERROR missing 'feature' [E0546]
|
||||
fn f3() { }
|
||||
}
|
||||
|
||||
|
@ -36,33 +36,34 @@ mod missing_version {
|
|||
#[stable(feature = "a")] //~ ERROR missing 'since' [E0542]
|
||||
fn f1() { }
|
||||
|
||||
#[stable(feature = "a", since = "b")]
|
||||
#[stable(feature = "a", since = "4.4.4")]
|
||||
#[deprecated(note = "a")] //~ ERROR missing 'since' [E0542]
|
||||
fn f2() { }
|
||||
|
||||
#[stable(feature = "a", since = "b")]
|
||||
#[stable(feature = "a", since = "4.4.4")]
|
||||
#[deprecated(since = "a")] //~ ERROR missing 'note' [E0543]
|
||||
fn f3() { }
|
||||
}
|
||||
|
||||
#[unstable(feature = "b", issue = "none")]
|
||||
#[stable(feature = "a", since = "b")] //~ ERROR multiple stability levels [E0544]
|
||||
#[stable(feature = "a", since = "4.4.4")] //~ ERROR multiple stability levels [E0544]
|
||||
fn multiple1() { }
|
||||
|
||||
#[unstable(feature = "b", issue = "none")]
|
||||
#[unstable(feature = "b", issue = "none")] //~ ERROR multiple stability levels [E0544]
|
||||
fn multiple2() { }
|
||||
|
||||
#[stable(feature = "a", since = "b")]
|
||||
#[stable(feature = "a", since = "b")] //~ ERROR multiple stability levels [E0544]
|
||||
#[stable(feature = "a", since = "4.4.4")]
|
||||
#[stable(feature = "a", since = "4.4.4")] //~ ERROR multiple stability levels [E0544]
|
||||
fn multiple3() { }
|
||||
|
||||
#[stable(feature = "a", since = "b")] //~ ERROR invalid stability version found
|
||||
#[stable(feature = "e", since = "b")] //~ ERROR 'since' must be a Rust version number, such as "1.31.0"
|
||||
#[deprecated(since = "b", note = "text")]
|
||||
#[deprecated(since = "b", note = "text")] //~ ERROR multiple `deprecated` attributes
|
||||
//~^ ERROR deprecated attribute must be paired with either stable or unstable attribute
|
||||
#[rustc_const_unstable(feature = "c", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
|
||||
pub const fn multiple4() { }
|
||||
pub const fn multiple4() { } //~ ERROR function has missing stability attribute
|
||||
|
||||
#[stable(feature = "a", since = "1.0.0")] //~ ERROR invalid deprecation version found
|
||||
//~^ ERROR feature `a` is declared stable since 1.0.0
|
||||
|
|
|
@ -11,10 +11,10 @@ LL | #[deprecated(since = "b", note = "text")]
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0541]: unknown meta item 'reason'
|
||||
--> $DIR/stability-attribute-sanity.rs:8:42
|
||||
--> $DIR/stability-attribute-sanity.rs:8:46
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "b", reason)]
|
||||
| ^^^^^^ expected one of `feature`, `since`
|
||||
LL | #[stable(feature = "a", since = "4.4.4", reason)]
|
||||
| ^^^^^^ expected one of `feature`, `since`
|
||||
|
||||
error[E0539]: incorrect meta item
|
||||
--> $DIR/stability-attribute-sanity.rs:11:29
|
||||
|
@ -25,7 +25,7 @@ LL | #[stable(feature = "a", since)]
|
|||
error[E0539]: incorrect meta item
|
||||
--> $DIR/stability-attribute-sanity.rs:14:14
|
||||
|
|
||||
LL | #[stable(feature, since = "a")]
|
||||
LL | #[stable(feature, since = "3.3.3")]
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0539]: incorrect meta item
|
||||
|
@ -37,7 +37,7 @@ LL | #[stable(feature = "a", since(b))]
|
|||
error[E0539]: incorrect meta item
|
||||
--> $DIR/stability-attribute-sanity.rs:20:14
|
||||
|
|
||||
LL | #[stable(feature(b), since = "a")]
|
||||
LL | #[stable(feature(b), since = "3.3.3")]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0546]: missing 'feature'
|
||||
|
@ -55,8 +55,8 @@ LL | #[unstable(feature = "b")]
|
|||
error[E0546]: missing 'feature'
|
||||
--> $DIR/stability-attribute-sanity.rs:31:5
|
||||
|
|
||||
LL | #[stable(since = "a")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[stable(since = "3.3.3")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0542]: missing 'since'
|
||||
--> $DIR/stability-attribute-sanity.rs:36:5
|
||||
|
@ -79,8 +79,8 @@ LL | #[deprecated(since = "a")]
|
|||
error[E0544]: multiple stability levels
|
||||
--> $DIR/stability-attribute-sanity.rs:49:1
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "b")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[stable(feature = "a", since = "4.4.4")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0544]: multiple stability levels
|
||||
--> $DIR/stability-attribute-sanity.rs:53:1
|
||||
|
@ -91,26 +91,29 @@ LL | #[unstable(feature = "b", issue = "none")]
|
|||
error[E0544]: multiple stability levels
|
||||
--> $DIR/stability-attribute-sanity.rs:57:1
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "b")]
|
||||
LL | #[stable(feature = "a", since = "4.4.4")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: 'since' must be a Rust version number, such as "1.31.0"
|
||||
--> $DIR/stability-attribute-sanity.rs:60:1
|
||||
|
|
||||
LL | #[stable(feature = "e", since = "b")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0544]: multiple stability levels
|
||||
--> $DIR/stability-attribute-sanity.rs:64:1
|
||||
--> $DIR/stability-attribute-sanity.rs:65:1
|
||||
|
|
||||
LL | #[rustc_const_unstable(feature = "d", issue = "none")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid stability version found
|
||||
--> $DIR/stability-attribute-sanity.rs:60:1
|
||||
error[E0549]: deprecated attribute must be paired with either stable or unstable attribute
|
||||
--> $DIR/stability-attribute-sanity.rs:62:1
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "b")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid stability version
|
||||
...
|
||||
LL | pub const fn multiple4() { }
|
||||
| ---------------------------- the stability attribute annotates this item
|
||||
LL | #[deprecated(since = "b", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid deprecation version found
|
||||
--> $DIR/stability-attribute-sanity.rs:67:1
|
||||
--> $DIR/stability-attribute-sanity.rs:68:1
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "1.0.0")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid deprecation version
|
||||
|
@ -119,18 +122,24 @@ LL | fn invalid_deprecation_version() {}
|
|||
| ----------------------------------- the stability attribute annotates this item
|
||||
|
||||
error[E0549]: deprecated attribute must be paired with either stable or unstable attribute
|
||||
--> $DIR/stability-attribute-sanity.rs:72:1
|
||||
--> $DIR/stability-attribute-sanity.rs:73:1
|
||||
|
|
||||
LL | #[deprecated(since = "a", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0711]: feature `a` is declared stable since 1.0.0, but was previously declared stable since b
|
||||
--> $DIR/stability-attribute-sanity.rs:67:1
|
||||
error: function has missing stability attribute
|
||||
--> $DIR/stability-attribute-sanity.rs:66:1
|
||||
|
|
||||
LL | pub const fn multiple4() { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0711]: feature `a` is declared stable since 1.0.0, but was previously declared stable since 4.4.4
|
||||
--> $DIR/stability-attribute-sanity.rs:68:1
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "1.0.0")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 20 previous errors
|
||||
error: aborting due to 22 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0539, E0541, E0542, E0543, E0544, E0546, E0547, E0549, E0711.
|
||||
For more information about an error, try `rustc --explain E0539`.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#![feature(staged_api, never_type, rust_cold_cc)]
|
||||
//~^ ERROR module has missing stability attribute
|
||||
|
||||
#[stable(feature = "a", since = "1")]
|
||||
#[stable(feature = "a", since = "3.3.3")]
|
||||
struct StableType;
|
||||
|
||||
#[unstable(feature = "b", issue = "none")]
|
||||
struct UnstableType;
|
||||
|
||||
#[stable(feature = "c", since = "1")]
|
||||
#[stable(feature = "c", since = "3.3.3")]
|
||||
trait StableTrait {}
|
||||
|
||||
#[unstable(feature = "d", issue = "none")]
|
||||
|
|
|
@ -21,7 +21,7 @@ error: module has missing stability attribute
|
|||
LL | / #![feature(staged_api, never_type, rust_cold_cc)]
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | #[stable(feature = "a", since = "1")]
|
||||
LL | | #[stable(feature = "a", since = "3.3.3")]
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
|
|
Loading…
Add table
Reference in a new issue