diff options
| author | David Tolnay <dtolnay@gmail.com> | 2023-10-16 12:30:32 -0700 |
|---|---|---|
| committer | David Tolnay <dtolnay@gmail.com> | 2023-10-23 13:04:35 -0700 |
| commit | 82ed3f5e8b65291d4861f62f8c9c5bc8630e42b2 (patch) | |
| tree | ff1f408dce11f1e9e8f8386b9c544273d1b87929 | |
| parent | 01b909174bf44b72b927b524626b06738e5872a4 (diff) | |
| download | rust-82ed3f5e8b65291d4861f62f8c9c5bc8630e42b2.tar.gz rust-82ed3f5e8b65291d4861f62f8c9c5bc8630e42b2.zip | |
Validate `since` value in stable attribute
| -rw-r--r-- | compiler/rustc_attr/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_attr/src/builtin.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_attr/src/session_diagnostics.rs | 7 |
3 files changed, 21 insertions, 8 deletions
diff --git a/compiler/rustc_attr/messages.ftl b/compiler/rustc_attr/messages.ftl index e6cbbaf3704..7281282fec3 100644 --- a/compiler/rustc_attr/messages.ftl +++ b/compiler/rustc_attr/messages.ftl @@ -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' diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 50045cb1f0f..44ba495721d 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -362,12 +362,6 @@ 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) => { @@ -376,8 +370,17 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit None => Err(sess.emit_err(session_diagnostics::MissingFeature { span: attr.span })), }; - let since = - since.ok_or_else(|| sess.emit_err(session_diagnostics::MissingSince { 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) { (Ok(feature), Ok(since)) => { diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 86f27254db2..ca9bbd28b95 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -371,6 +371,13 @@ pub(crate) struct ExpectsFeatures { } #[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 { #[primary_span] |
