rustc_parse: Use Token::ident
where possible
This commit is contained in:
parent
2cb0b8582e
commit
925e9a2188
7 changed files with 88 additions and 94 deletions
|
@ -156,44 +156,43 @@ fn parse_args<'a>(
|
||||||
if p.token == token::Eof {
|
if p.token == token::Eof {
|
||||||
break;
|
break;
|
||||||
} // accept trailing commas
|
} // accept trailing commas
|
||||||
if p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq) {
|
match p.token.ident() {
|
||||||
named = true;
|
Some((ident, _)) if p.look_ahead(1, |t| *t == token::Eq) => {
|
||||||
let name = if let token::Ident(name, _) = p.normalized_token.kind {
|
named = true;
|
||||||
p.bump();
|
p.bump();
|
||||||
name
|
p.expect(&token::Eq)?;
|
||||||
} else {
|
let e = p.parse_expr()?;
|
||||||
unreachable!();
|
if let Some(prev) = names.get(&ident.name) {
|
||||||
};
|
ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", ident))
|
||||||
|
.span_label(args[*prev].span, "previously here")
|
||||||
p.expect(&token::Eq)?;
|
.span_label(e.span, "duplicate argument")
|
||||||
let e = p.parse_expr()?;
|
.emit();
|
||||||
if let Some(prev) = names.get(&name) {
|
continue;
|
||||||
ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name))
|
|
||||||
.span_label(args[*prev].span, "previously here")
|
|
||||||
.span_label(e.span, "duplicate argument")
|
|
||||||
.emit();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve names into slots early.
|
|
||||||
// Since all the positional args are already seen at this point
|
|
||||||
// if the input is valid, we can simply append to the positional
|
|
||||||
// args. And remember the names.
|
|
||||||
let slot = args.len();
|
|
||||||
names.insert(name, slot);
|
|
||||||
args.push(e);
|
|
||||||
} else {
|
|
||||||
let e = p.parse_expr()?;
|
|
||||||
if named {
|
|
||||||
let mut err = ecx
|
|
||||||
.struct_span_err(e.span, "positional arguments cannot follow named arguments");
|
|
||||||
err.span_label(e.span, "positional arguments must be before named arguments");
|
|
||||||
for pos in names.values() {
|
|
||||||
err.span_label(args[*pos].span, "named argument");
|
|
||||||
}
|
}
|
||||||
err.emit();
|
|
||||||
|
// Resolve names into slots early.
|
||||||
|
// Since all the positional args are already seen at this point
|
||||||
|
// if the input is valid, we can simply append to the positional
|
||||||
|
// args. And remember the names.
|
||||||
|
let slot = args.len();
|
||||||
|
names.insert(ident.name, slot);
|
||||||
|
args.push(e);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let e = p.parse_expr()?;
|
||||||
|
if named {
|
||||||
|
let mut err = ecx.struct_span_err(
|
||||||
|
e.span,
|
||||||
|
"positional arguments cannot follow named arguments",
|
||||||
|
);
|
||||||
|
err.span_label(e.span, "positional arguments must be before named arguments");
|
||||||
|
for pos in names.values() {
|
||||||
|
err.span_label(args[*pos].span, "named argument");
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
args.push(e);
|
||||||
}
|
}
|
||||||
args.push(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((fmtstr, args, names))
|
Ok((fmtstr, args, names))
|
||||||
|
|
|
@ -750,15 +750,9 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
||||||
|
|
||||||
/// The token is an identifier, but not `_`.
|
/// The token is an identifier, but not `_`.
|
||||||
/// We prohibit passing `_` to macros expecting `ident` for now.
|
/// We prohibit passing `_` to macros expecting `ident` for now.
|
||||||
fn get_macro_name(token: &Token) -> Option<(Name, bool)> {
|
fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> {
|
||||||
match token.kind {
|
match token.ident() {
|
||||||
token::Ident(name, is_raw) if name != kw::Underscore => Some((name, is_raw)),
|
Some((ident, is_raw)) if ident.name != kw::Underscore => Some((ident, is_raw)),
|
||||||
token::Interpolated(ref nt) => match **nt {
|
|
||||||
token::NtIdent(ident, is_raw) if ident.name != kw::Underscore => {
|
|
||||||
Some((ident.name, is_raw))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -783,7 +777,7 @@ fn may_begin_with(token: &Token, name: Name) -> bool {
|
||||||
&& !token.is_keyword(kw::Let)
|
&& !token.is_keyword(kw::Let)
|
||||||
}
|
}
|
||||||
sym::ty => token.can_begin_type(),
|
sym::ty => token.can_begin_type(),
|
||||||
sym::ident => get_macro_name(token).is_some(),
|
sym::ident => get_macro_ident(token).is_some(),
|
||||||
sym::literal => token.can_begin_literal_or_bool(),
|
sym::literal => token.can_begin_literal_or_bool(),
|
||||||
sym::vis => match token.kind {
|
sym::vis => match token.kind {
|
||||||
// The follow-set of :vis + "priv" keyword + interpolated
|
// The follow-set of :vis + "priv" keyword + interpolated
|
||||||
|
@ -888,9 +882,9 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
|
||||||
sym::ty => token::NtTy(p.parse_ty()?),
|
sym::ty => token::NtTy(p.parse_ty()?),
|
||||||
// this could be handled like a token, since it is one
|
// this could be handled like a token, since it is one
|
||||||
sym::ident => {
|
sym::ident => {
|
||||||
if let Some((name, is_raw)) = get_macro_name(&p.token) {
|
if let Some((ident, is_raw)) = get_macro_ident(&p.token) {
|
||||||
p.bump();
|
p.bump();
|
||||||
token::NtIdent(Ident::new(name, p.normalized_prev_token.span), is_raw)
|
token::NtIdent(ident, is_raw)
|
||||||
} else {
|
} else {
|
||||||
let token_str = pprust::token_to_string(&p.token);
|
let token_str = pprust::token_to_string(&p.token);
|
||||||
let msg = &format!("expected ident, found {}", &token_str);
|
let msg = &format!("expected ident, found {}", &token_str);
|
||||||
|
|
|
@ -192,17 +192,19 @@ impl<'a> Parser<'a> {
|
||||||
TokenKind::CloseDelim(token::DelimToken::Brace),
|
TokenKind::CloseDelim(token::DelimToken::Brace),
|
||||||
TokenKind::CloseDelim(token::DelimToken::Paren),
|
TokenKind::CloseDelim(token::DelimToken::Paren),
|
||||||
];
|
];
|
||||||
if let token::Ident(name, false) = self.normalized_token.kind {
|
match self.token.ident() {
|
||||||
if Ident::new(name, self.normalized_token.span).is_raw_guess()
|
Some((ident, false))
|
||||||
&& self.look_ahead(1, |t| valid_follow.contains(&t.kind))
|
if ident.is_raw_guess()
|
||||||
|
&& self.look_ahead(1, |t| valid_follow.contains(&t.kind)) =>
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
self.normalized_token.span,
|
ident.span,
|
||||||
"you can escape reserved keywords to use them as identifiers",
|
"you can escape reserved keywords to use them as identifiers",
|
||||||
format!("r#{}", name),
|
format!("r#{}", ident.name),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
if let Some(token_descr) = super::token_descr_opt(&self.token) {
|
if let Some(token_descr) = super::token_descr_opt(&self.token) {
|
||||||
err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
|
err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
|
||||||
|
|
|
@ -97,9 +97,10 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> {
|
fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> {
|
||||||
match self.parse_expr() {
|
match self.parse_expr() {
|
||||||
Ok(expr) => Ok(expr),
|
Ok(expr) => Ok(expr),
|
||||||
Err(mut err) => match self.normalized_token.kind {
|
Err(mut err) => match self.token.ident() {
|
||||||
token::Ident(name, false)
|
Some((ident, false))
|
||||||
if name == kw::Underscore && self.look_ahead(1, |t| t == &token::Comma) =>
|
if ident.name == kw::Underscore
|
||||||
|
&& self.look_ahead(1, |t| t == &token::Comma) =>
|
||||||
{
|
{
|
||||||
// Special-case handling of `foo(_, _, _)`
|
// Special-case handling of `foo(_, _, _)`
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -331,21 +332,19 @@ impl<'a> Parser<'a> {
|
||||||
///
|
///
|
||||||
/// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively.
|
/// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively.
|
||||||
fn check_assoc_op(&self) -> Option<Spanned<AssocOp>> {
|
fn check_assoc_op(&self) -> Option<Spanned<AssocOp>> {
|
||||||
Some(Spanned {
|
let (op, span) = match (AssocOp::from_token(&self.token), self.token.ident()) {
|
||||||
node: match (AssocOp::from_token(&self.token), &self.normalized_token.kind) {
|
(Some(op), _) => (op, self.token.span),
|
||||||
(Some(op), _) => op,
|
(None, Some((ident, false))) if ident.name == sym::and => {
|
||||||
(None, token::Ident(sym::and, false)) => {
|
self.error_bad_logical_op("and", "&&", "conjunction");
|
||||||
self.error_bad_logical_op("and", "&&", "conjunction");
|
(AssocOp::LAnd, ident.span)
|
||||||
AssocOp::LAnd
|
}
|
||||||
}
|
(None, Some((ident, false))) if ident.name == sym::or => {
|
||||||
(None, token::Ident(sym::or, false)) => {
|
self.error_bad_logical_op("or", "||", "disjunction");
|
||||||
self.error_bad_logical_op("or", "||", "disjunction");
|
(AssocOp::LOr, ident.span)
|
||||||
AssocOp::LOr
|
}
|
||||||
}
|
_ => return None,
|
||||||
_ => return None,
|
};
|
||||||
},
|
Some(source_map::respan(span, op))
|
||||||
span: self.normalized_token.span,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error on `and` and `or` suggesting `&&` and `||` respectively.
|
/// Error on `and` and `or` suggesting `&&` and `||` respectively.
|
||||||
|
@ -1907,20 +1906,23 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Use in case of error after field-looking code: `S { foo: () with a }`.
|
/// Use in case of error after field-looking code: `S { foo: () with a }`.
|
||||||
fn find_struct_error_after_field_looking_code(&self) -> Option<Field> {
|
fn find_struct_error_after_field_looking_code(&self) -> Option<Field> {
|
||||||
if let token::Ident(name, _) = self.normalized_token.kind {
|
match self.token.ident() {
|
||||||
if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) {
|
Some((ident, is_raw))
|
||||||
return Some(ast::Field {
|
if (is_raw || !ident.is_reserved())
|
||||||
ident: Ident::new(name, self.normalized_token.span),
|
&& self.look_ahead(1, |t| *t == token::Colon) =>
|
||||||
|
{
|
||||||
|
Some(ast::Field {
|
||||||
|
ident,
|
||||||
span: self.token.span,
|
span: self.token.span,
|
||||||
expr: self.mk_expr_err(self.token.span),
|
expr: self.mk_expr_err(self.token.span),
|
||||||
is_shorthand: false,
|
is_shorthand: false,
|
||||||
attrs: AttrVec::new(),
|
attrs: AttrVec::new(),
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
is_placeholder: false,
|
is_placeholder: false,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recover_struct_comma_after_dotdot(&mut self, span: Span) {
|
fn recover_struct_comma_after_dotdot(&mut self, span: Span) {
|
||||||
|
|
|
@ -750,10 +750,10 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
|
fn parse_ident_or_underscore(&mut self) -> PResult<'a, ast::Ident> {
|
||||||
match self.normalized_token.kind {
|
match self.token.ident() {
|
||||||
token::Ident(name @ kw::Underscore, false) => {
|
Some((ident, false)) if ident.name == kw::Underscore => {
|
||||||
self.bump();
|
self.bump();
|
||||||
Ok(Ident::new(name, self.normalized_prev_token.span))
|
Ok(ident)
|
||||||
}
|
}
|
||||||
_ => self.parse_ident(),
|
_ => self.parse_ident(),
|
||||||
}
|
}
|
||||||
|
@ -1609,15 +1609,12 @@ impl<'a> Parser<'a> {
|
||||||
/// Returns the parsed optional self parameter and whether a self shortcut was used.
|
/// Returns the parsed optional self parameter and whether a self shortcut was used.
|
||||||
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
|
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
|
||||||
// Extract an identifier *after* having confirmed that the token is one.
|
// Extract an identifier *after* having confirmed that the token is one.
|
||||||
let expect_self_ident = |this: &mut Self| {
|
let expect_self_ident = |this: &mut Self| match this.token.ident() {
|
||||||
match this.normalized_token.kind {
|
Some((ident, false)) => {
|
||||||
// Preserve hygienic context.
|
this.bump();
|
||||||
token::Ident(name, _) => {
|
ident
|
||||||
this.bump();
|
|
||||||
Ident::new(name, this.normalized_prev_token.span)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
// Is `self` `n` tokens ahead?
|
// Is `self` `n` tokens ahead?
|
||||||
let is_isolated_self = |this: &Self, n| {
|
let is_isolated_self = |this: &Self, n| {
|
||||||
|
|
|
@ -480,9 +480,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
|
fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
|
||||||
match self.normalized_token.kind {
|
match self.token.ident() {
|
||||||
token::Ident(name, _) => {
|
Some((ident, is_raw)) => {
|
||||||
if self.token.is_reserved_ident() {
|
if !is_raw && ident.is_reserved() {
|
||||||
let mut err = self.expected_ident_found();
|
let mut err = self.expected_ident_found();
|
||||||
if recover {
|
if recover {
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -491,7 +491,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.bump();
|
self.bump();
|
||||||
Ok(Ident::new(name, self.normalized_prev_token.span))
|
Ok(ident)
|
||||||
}
|
}
|
||||||
_ => Err(match self.prev_token.kind {
|
_ => Err(match self.prev_token.kind {
|
||||||
TokenKind::DocComment(..) => {
|
TokenKind::DocComment(..) => {
|
||||||
|
|
|
@ -240,10 +240,10 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn parse_path_segment_ident(&mut self) -> PResult<'a, Ident> {
|
pub(super) fn parse_path_segment_ident(&mut self) -> PResult<'a, Ident> {
|
||||||
match self.normalized_token.kind {
|
match self.token.ident() {
|
||||||
token::Ident(name, _) if name.is_path_segment_keyword() => {
|
Some((ident, false)) if ident.is_path_segment_keyword() => {
|
||||||
self.bump();
|
self.bump();
|
||||||
Ok(Ident::new(name, self.normalized_prev_token.span))
|
Ok(ident)
|
||||||
}
|
}
|
||||||
_ => self.parse_ident(),
|
_ => self.parse_ident(),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue