Skip to content

Commit 43efdf9

Browse files
committed
Validate #[stable(feature = "…")] identifier
1 parent d60d63f commit 43efdf9

File tree

1 file changed

+36
-37
lines changed

1 file changed

+36
-37
lines changed

compiler/rustc_attr/src/builtin.rs

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use rustc_ast::{self as ast, attr};
44
use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
55
use rustc_ast_pretty::pprust;
6+
use rustc_errors::ErrorGuaranteed;
67
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
78
use rustc_macros::HashStable_Generic;
89
use rustc_session::config::ExpectedValues;
@@ -48,33 +49,27 @@ pub(crate) enum UnsupportedLiteralReason {
4849
DeprecatedKvPair,
4950
}
5051

51-
fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
52+
fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) -> ErrorGuaranteed {
5253
match error {
5354
AttrError::MultipleItem(item) => {
54-
sess.emit_err(session_diagnostics::MultipleItem { span, item });
55+
sess.emit_err(session_diagnostics::MultipleItem { span, item })
5556
}
5657
AttrError::UnknownMetaItem(item, expected) => {
57-
sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected });
58-
}
59-
AttrError::MissingSince => {
60-
sess.emit_err(session_diagnostics::MissingSince { span });
61-
}
62-
AttrError::NonIdentFeature => {
63-
sess.emit_err(session_diagnostics::NonIdentFeature { span });
64-
}
65-
AttrError::MissingFeature => {
66-
sess.emit_err(session_diagnostics::MissingFeature { span });
58+
sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected })
6759
}
60+
AttrError::MissingSince => sess.emit_err(session_diagnostics::MissingSince { span }),
61+
AttrError::NonIdentFeature => sess.emit_err(session_diagnostics::NonIdentFeature { span }),
62+
AttrError::MissingFeature => sess.emit_err(session_diagnostics::MissingFeature { span }),
6863
AttrError::MultipleStabilityLevels => {
69-
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span });
64+
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span })
7065
}
7166
AttrError::UnsupportedLiteral(reason, is_bytestr) => {
7267
sess.emit_err(session_diagnostics::UnsupportedLiteral {
7368
span,
7469
reason,
7570
is_bytestr,
7671
start_point_span: sess.source_map().start_point(span),
77-
});
72+
})
7873
}
7974
}
8075
}
@@ -411,19 +406,23 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
411406
since = Some(rust_version_symbol());
412407
}
413408

409+
let feature = match feature {
410+
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
411+
Some(_bad_feature) => {
412+
Err(handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature))
413+
}
414+
None => Err(handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature)),
415+
};
416+
417+
let since =
418+
since.ok_or_else(|| handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince));
419+
414420
match (feature, since) {
415-
(Some(feature), Some(since)) => {
421+
(Ok(feature), Ok(since)) => {
416422
let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false };
417423
Some((feature, level))
418424
}
419-
(None, _) => {
420-
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
421-
None
422-
}
423-
_ => {
424-
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
425-
None
426-
}
425+
(Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
427426
}
428427
}
429428

@@ -497,12 +496,19 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
497496
}
498497
}
499498

500-
match (feature, reason, issue) {
501-
(Some(feature), reason, Some(_)) => {
502-
if !rustc_lexer::is_ident(feature.as_str()) {
503-
handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature);
504-
return None;
505-
}
499+
let feature = match feature {
500+
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
501+
Some(_bad_feature) => {
502+
Err(handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature))
503+
}
504+
None => Err(handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature)),
505+
};
506+
507+
let issue =
508+
issue.ok_or_else(|| sess.emit_err(session_diagnostics::MissingIssue { span: attr.span }));
509+
510+
match (feature, issue) {
511+
(Ok(feature), Ok(_)) => {
506512
let level = StabilityLevel::Unstable {
507513
reason: UnstableReason::from_opt_reason(reason),
508514
issue: issue_num,
@@ -511,14 +517,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
511517
};
512518
Some((feature, level))
513519
}
514-
(None, _, _) => {
515-
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
516-
return None;
517-
}
518-
_ => {
519-
sess.emit_err(session_diagnostics::MissingIssue { span: attr.span });
520-
return None;
521-
}
520+
(Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
522521
}
523522
}
524523

0 commit comments

Comments
 (0)