Skip to content

Commit

Permalink
Validate #[stable(feature = "…")] identifier
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Oct 16, 2023
1 parent 58352c0 commit 9597aba
Showing 1 changed file with 36 additions and 37 deletions.
73 changes: 36 additions & 37 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -48,33 +49,27 @@ pub(crate) enum UnsupportedLiteralReason {
DeprecatedKvPair,
}

fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) -> ErrorGuaranteed {
match error {
AttrError::MultipleItem(item) => {
sess.emit_err(session_diagnostics::MultipleItem { span, item });
sess.emit_err(session_diagnostics::MultipleItem { span, item })
}
AttrError::UnknownMetaItem(item, expected) => {
sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected });
}
AttrError::MissingSince => {
sess.emit_err(session_diagnostics::MissingSince { span });
}
AttrError::NonIdentFeature => {
sess.emit_err(session_diagnostics::NonIdentFeature { span });
}
AttrError::MissingFeature => {
sess.emit_err(session_diagnostics::MissingFeature { span });
sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected })
}
AttrError::MissingSince => sess.emit_err(session_diagnostics::MissingSince { span }),
AttrError::NonIdentFeature => sess.emit_err(session_diagnostics::NonIdentFeature { span }),
AttrError::MissingFeature => sess.emit_err(session_diagnostics::MissingFeature { span }),
AttrError::MultipleStabilityLevels => {
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span });
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span })
}
AttrError::UnsupportedLiteral(reason, is_bytestr) => {
sess.emit_err(session_diagnostics::UnsupportedLiteral {
span,
reason,
is_bytestr,
start_point_span: sess.source_map().start_point(span),
});
})
}
}
}
Expand Down Expand Up @@ -411,19 +406,23 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
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(handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature))
}
None => Err(handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature)),
};

let since =
since.ok_or_else(|| handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince));

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, _) => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
None
}
_ => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
None
}
(Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
}
}

Expand Down Expand Up @@ -497,12 +496,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()) {
handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature);
return None;
}
let feature = match feature {
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
Some(_bad_feature) => {
Err(handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature))
}
None => Err(handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature)),
};

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,
Expand All @@ -511,14 +517,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
};
Some((feature, level))
}
(None, _, _) => {
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature);
return None;
}
_ => {
sess.emit_err(session_diagnostics::MissingIssue { span: attr.span });
return None;
}
(Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
}
}

Expand Down

0 comments on commit 9597aba

Please sign in to comment.