Validate #[stable(feature = "…")] identifier

This commit is contained in:
David Tolnay 2023-10-15 12:06:14 -07:00
parent e2068cdb09
commit 9853f6132f
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82

View File

@ -3,6 +3,7 @@
use rustc_ast::{self as ast, attr}; use rustc_ast::{self as ast, attr};
use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId}; use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_errors::ErrorGuaranteed;
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
use rustc_macros::HashStable_Generic; use rustc_macros::HashStable_Generic;
use rustc_session::config::ExpectedValues; use rustc_session::config::ExpectedValues;
@ -367,19 +368,23 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
since = Some(rust_version_symbol()); 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 =
since.ok_or_else(|| sess.emit_err(session_diagnostics::MissingSince { span: attr.span }));
match (feature, since) { match (feature, since) {
(Some(feature), Some(since)) => { (Ok(feature), Ok(since)) => {
let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false }; let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false };
Some((feature, level)) Some((feature, level))
} }
(None, _) => { (Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
None
}
_ => {
sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
None
}
} }
} }
@ -451,12 +456,19 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
} }
} }
match (feature, reason, issue) { let feature = match feature {
(Some(feature), reason, Some(_)) => { Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
if !rustc_lexer::is_ident(feature.as_str()) { Some(_bad_feature) => {
sess.emit_err(session_diagnostics::NonIdentFeature { span: attr.span }); Err(sess.emit_err(session_diagnostics::NonIdentFeature { span: attr.span }))
return None; }
} 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 { let level = StabilityLevel::Unstable {
reason: UnstableReason::from_opt_reason(reason), reason: UnstableReason::from_opt_reason(reason),
issue: issue_num, issue: issue_num,
@ -465,14 +477,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
}; };
Some((feature, level)) Some((feature, level))
} }
(None, _, _) => { (Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
sess.emit_err(session_diagnostics::MissingFeature { span: attr.span });
return None;
}
_ => {
sess.emit_err(session_diagnostics::MissingIssue { span: attr.span });
return None;
}
} }
} }