1
Fork 0

Introduce rustc_lexer::is_ident and use it in couple of places

This commit is contained in:
Vadim Petrochenkov 2020-08-10 22:27:48 +03:00
parent 1275cc15d6
commit 20c5044465
5 changed files with 25 additions and 9 deletions

View file

@ -3257,6 +3257,7 @@ dependencies = [
"rustc_data_structures", "rustc_data_structures",
"rustc_errors", "rustc_errors",
"rustc_feature", "rustc_feature",
"rustc_lexer",
"rustc_macros", "rustc_macros",
"rustc_serialize", "rustc_serialize",
"rustc_session", "rustc_session",

View file

@ -16,6 +16,7 @@ rustc_errors = { path = "../librustc_errors" }
rustc_span = { path = "../librustc_span" } rustc_span = { path = "../librustc_span" }
rustc_data_structures = { path = "../librustc_data_structures" } rustc_data_structures = { path = "../librustc_data_structures" }
rustc_feature = { path = "../librustc_feature" } rustc_feature = { path = "../librustc_feature" }
rustc_lexer = { path = "../librustc_lexer" }
rustc_macros = { path = "../librustc_macros" } rustc_macros = { path = "../librustc_macros" }
rustc_session = { path = "../librustc_session" } rustc_session = { path = "../librustc_session" }
rustc_ast = { path = "../librustc_ast" } rustc_ast = { path = "../librustc_ast" }

View file

@ -20,6 +20,7 @@ enum AttrError {
MultipleItem(String), MultipleItem(String),
UnknownMetaItem(String, &'static [&'static str]), UnknownMetaItem(String, &'static [&'static str]),
MissingSince, MissingSince,
NonIdentFeature,
MissingFeature, MissingFeature,
MultipleStabilityLevels, MultipleStabilityLevels,
UnsupportedLiteral(&'static str, /* is_bytestr */ bool), UnsupportedLiteral(&'static str, /* is_bytestr */ bool),
@ -40,6 +41,9 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
AttrError::MissingSince => { AttrError::MissingSince => {
struct_span_err!(diag, span, E0542, "missing 'since'").emit(); struct_span_err!(diag, span, E0542, "missing 'since'").emit();
} }
AttrError::NonIdentFeature => {
struct_span_err!(diag, span, E0546, "'feature' is not an identifier").emit();
}
AttrError::MissingFeature => { AttrError::MissingFeature => {
struct_span_err!(diag, span, E0546, "missing 'feature'").emit(); struct_span_err!(diag, span, E0546, "missing 'feature'").emit();
} }
@ -344,6 +348,14 @@ where
match (feature, reason, issue) { match (feature, reason, issue) {
(Some(feature), reason, Some(_)) => { (Some(feature), reason, Some(_)) => {
if !rustc_lexer::is_ident(&feature.as_str()) {
handle_errors(
&sess.parse_sess,
attr.span,
AttrError::NonIdentFeature,
);
continue;
}
let level = Unstable { reason, issue: issue_num, is_soft }; let level = Unstable { reason, issue: issue_num, is_soft };
if sym::unstable == meta_name { if sym::unstable == meta_name {
stab = Some(Stability { level, feature }); stab = Some(Stability { level, feature });

View file

@ -319,18 +319,10 @@ pub struct Ident {
} }
impl Ident { impl Ident {
fn is_valid(string: &str) -> bool {
let mut chars = string.chars();
if let Some(start) = chars.next() {
rustc_lexer::is_id_start(start) && chars.all(rustc_lexer::is_id_continue)
} else {
false
}
}
fn new(sess: &ParseSess, sym: Symbol, is_raw: bool, span: Span) -> Ident { fn new(sess: &ParseSess, sym: Symbol, is_raw: bool, span: Span) -> Ident {
let sym = nfc_normalize(&sym.as_str()); let sym = nfc_normalize(&sym.as_str());
let string = sym.as_str(); let string = sym.as_str();
if !Self::is_valid(&string) { if !rustc_lexer::is_ident(&string) {
panic!("`{:?}` is not a valid identifier", string) panic!("`{:?}` is not a valid identifier", string)
} }
if is_raw && !sym.can_be_raw() { if is_raw && !sym.can_be_raw() {

View file

@ -274,6 +274,16 @@ pub fn is_id_continue(c: char) -> bool {
|| (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c)) || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
} }
/// The passed string is lexically an identifier.
pub fn is_ident(string: &str) -> bool {
let mut chars = string.chars();
if let Some(start) = chars.next() {
is_id_start(start) && chars.all(is_id_continue)
} else {
false
}
}
impl Cursor<'_> { impl Cursor<'_> {
/// Parses a token from the input string. /// Parses a token from the input string.
fn advance_token(&mut self) -> Token { fn advance_token(&mut self) -> Token {