Skip to content

Commit debcff8

Browse files
committed
Validate since value in stable attribute
1 parent 303475f commit debcff8

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

compiler/rustc_attr/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ attr_invalid_repr_hint_no_paren =
5858
attr_invalid_repr_hint_no_value =
5959
invalid representation hint: `{$name}` does not take a value
6060
61+
attr_invalid_since =
62+
'since' must be a Rust version number, such as "1.31.0"
63+
6164
attr_missing_feature =
6265
missing 'feature'
6366

compiler/rustc_attr/src/builtin.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ enum AttrError {
3636
MultipleItem(String),
3737
UnknownMetaItem(String, &'static [&'static str]),
3838
MissingSince,
39+
InvalidSince,
3940
NonIdentFeature,
4041
MissingFeature,
4142
MultipleStabilityLevels,
@@ -58,6 +59,7 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) -> ErrorGuarant
5859
sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected })
5960
}
6061
AttrError::MissingSince => sess.emit_err(session_diagnostics::MissingSince { span }),
62+
AttrError::InvalidSince => sess.emit_err(session_diagnostics::InvalidSince { span }),
6163
AttrError::NonIdentFeature => sess.emit_err(session_diagnostics::NonIdentFeature { span }),
6264
AttrError::MissingFeature => sess.emit_err(session_diagnostics::MissingFeature { span }),
6365
AttrError::MultipleStabilityLevels => {
@@ -400,12 +402,6 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
400402
}
401403
}
402404

403-
if let Some(s) = since
404-
&& s.as_str() == VERSION_PLACEHOLDER
405-
{
406-
since = Some(rust_version_symbol());
407-
}
408-
409405
let feature = match feature {
410406
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
411407
Some(_bad_feature) => {
@@ -414,8 +410,17 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
414410
None => Err(handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature)),
415411
};
416412

417-
let since =
418-
since.ok_or_else(|| handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince));
413+
let since = if let Some(since) = since {
414+
if since.as_str() == VERSION_PLACEHOLDER {
415+
Ok(rust_version_symbol())
416+
} else if parse_version(since.as_str(), false).is_some() {
417+
Ok(since)
418+
} else {
419+
Err(handle_errors(&sess.parse_sess, attr.span, AttrError::InvalidSince))
420+
}
421+
} else {
422+
Err(handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince))
423+
};
419424

420425
match (feature, since) {
421426
(Ok(feature), Ok(since)) => {

compiler/rustc_attr/src/session_diagnostics.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,13 @@ pub(crate) struct ExpectsFeatures {
370370
pub name: String,
371371
}
372372

373+
#[derive(Diagnostic)]
374+
#[diag(attr_invalid_since)]
375+
pub(crate) struct InvalidSince {
376+
#[primary_span]
377+
pub span: Span,
378+
}
379+
373380
#[derive(Diagnostic)]
374381
#[diag(attr_soft_no_args)]
375382
pub(crate) struct SoftNoArgs {

0 commit comments

Comments
 (0)