use super::{Parser, PathStyle, TokenType};
use rustc_errors::PResult;
use syntax::ast;
-use syntax::attr;
+use syntax::print::pprust;
use syntax::token::{self, Nonterminal};
use syntax::util::comments;
+use syntax::util::comments;
use syntax_pos::{Span, Symbol};
use log::debug;
(attr_sp, item, style)
}
_ => {
- let token_str = self.this_token_to_string();
+ let token_str = pprust::token_to_string(&self.token);
return Err(self.fatal(&format!("expected `#`, found `{}`", token_str)));
}
};
Err(ref mut err) => err.cancel(),
}
- let found = self.this_token_to_string();
+ let found = pprust::token_to_string(&self.token);
let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
Err(self.diagnostic().struct_span_err(self.token.span, &msg))
}
pub(super) fn expected_ident_found(&self) -> DiagnosticBuilder<'a> {
let mut err = self.struct_span_err(
self.token.span,
- &format!("expected identifier, found {}", self.this_token_descr()),
+ &format!("expected identifier, found {}", super::token_descr(&self.token)),
);
let valid_follow = &[
TokenKind::Eq,
);
}
}
- if let Some(token_descr) = self.token_descr() {
+ if let Some(token_descr) = super::token_descr_opt(&self.token) {
err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
} else {
err.span_label(self.token.span, "expected identifier");
expected.sort_by_cached_key(|x| x.to_string());
expected.dedup();
let expect = tokens_to_string(&expected[..]);
- let actual = self.this_token_descr();
+ let actual = super::token_descr(&self.token);
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
let short_expect = if expected.len() > 6 {
format!("{} possible tokens", expected.len())
t: &TokenKind,
) -> PResult<'a, bool /* recovered */> {
let token_str = pprust::token_kind_to_string(t);
- let this_token_str = self.this_token_descr();
+ let this_token_str = super::token_descr(&self.token);
let (prev_sp, sp) = match (&self.token.kind, self.subparser_name) {
// Point at the end of the macro call when reaching end of macro arguments.
(token::Eof, Some(_)) => {
return Ok(());
}
let sm = self.sess.source_map();
- let msg = format!("expected `;`, found `{}`", self.this_token_descr());
+ let msg = format!("expected `;`, found `{}`", super::token_descr(&self.token));
let appl = Applicability::MachineApplicable;
if self.token.span == DUMMY_SP || self.prev_span == DUMMY_SP {
// Likely inside a macro, can't provide meaninful suggestions.
}
pub(super) fn expected_semi_or_open_brace<T>(&mut self) -> PResult<'a, T> {
- let token_str = self.this_token_descr();
+ let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str));
err.span_label(self.token.span, "expected `;` or `{`");
Err(err)
}
_ => (
self.token.span,
- format!("expected expression, found {}", self.this_token_descr(),),
+ format!("expected expression, found {}", super::token_descr(&self.token),),
),
};
let mut err = self.struct_span_err(span, &msg);
}
/// Parses a prefix-unary-operator expr.
- fn parse_prefix_expr(&mut self, already_parsed_attrs: Option<AttrVec>) -> PResult<'a, P<Expr>> {
- let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
+ fn parse_prefix_expr(&mut self, attrs: Option<AttrVec>) -> PResult<'a, P<Expr>> {
+ let attrs = self.parse_or_use_outer_attributes(attrs)?;
let lo = self.token.span;
// Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
let (hi, ex) = match self.token.kind {
- token::Not => {
- self.bump();
- let e = self.parse_prefix_expr(None);
- let (span, e) = self.interpolated_or_expr_span(e)?;
- (lo.to(span), self.mk_unary(UnOp::Not, e))
- }
- token::Tilde => self.recover_tilde_expr(lo)?,
- token::BinOp(token::Minus) => self.parse_neg_expr(lo)?,
- token::BinOp(token::Star) => self.parse_deref_expr(lo)?,
- token::BinOp(token::And) | token::AndAnd => self.parse_borrow_expr(lo)?,
- token::Ident(..) if self.token.is_keyword(kw::Box) => self.parse_box_expr(lo)?,
- token::Ident(..) if self.is_mistaken_not_ident_negation() => {
- self.recover_not_expr(lo)?
- }
+ token::Not => self.parse_unary_expr(lo, UnOp::Not), // `!expr`
+ token::Tilde => self.recover_tilde_expr(lo), // `~expr`
+ token::BinOp(token::Minus) => self.parse_unary_expr(lo, UnOp::Neg), // `-expr`
+ token::BinOp(token::Star) => self.parse_unary_expr(lo, UnOp::Deref), // `*expr`
+ token::BinOp(token::And) | token::AndAnd => self.parse_borrow_expr(lo),
+ token::Ident(..) if self.token.is_keyword(kw::Box) => self.parse_box_expr(lo),
+ token::Ident(..) if self.is_mistaken_not_ident_negation() => self.recover_not_expr(lo),
_ => return self.parse_dot_or_call_expr(Some(attrs)),
- };
- return Ok(self.mk_expr(lo.to(hi), ex, attrs));
+ }?;
+ Ok(self.mk_expr(lo.to(hi), ex, attrs))
}
- // Recover on `!` suggesting for bitwise negation instead.
- fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
+ fn parse_prefix_expr_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
self.bump();
let expr = self.parse_prefix_expr(None);
let (span, expr) = self.interpolated_or_expr_span(expr)?;
+ Ok((lo.to(span), expr))
+ }
+
+ fn parse_unary_expr(&mut self, lo: Span, op: UnOp) -> PResult<'a, (Span, ExprKind)> {
+ let (span, expr) = self.parse_prefix_expr_common(lo)?;
+ Ok((span, self.mk_unary(op, expr)))
+ }
+
+ // Recover on `!` suggesting for bitwise negation instead.
+ fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
self.struct_span_err(lo, "`~` cannot be used as a unary operator")
.span_suggestion_short(
lo,
Applicability::MachineApplicable,
)
.emit();
- Ok((lo.to(span), self.mk_unary(UnOp::Not, expr)))
- }
- /// Parse `-expr`.
- fn parse_neg_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
- self.bump(); // `-`
- let expr = self.parse_prefix_expr(None);
- let (span, expr) = self.interpolated_or_expr_span(expr)?;
- Ok((lo.to(span), self.mk_unary(UnOp::Neg, expr)))
- }
-
- /// Parse `*expr`.
- fn parse_deref_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
- self.bump(); // `*`
- let expr = self.parse_prefix_expr(None);
- let (span, expr) = self.interpolated_or_expr_span(expr)?;
- Ok((lo.to(span), self.mk_unary(UnOp::Deref, expr)))
+ self.parse_unary_expr(lo, UnOp::Not)
}
/// Parse `box expr`.
fn parse_box_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
- self.bump(); // `box`
- let expr = self.parse_prefix_expr(None);
- let (span, expr) = self.interpolated_or_expr_span(expr)?;
- let span = lo.to(span);
+ let (span, expr) = self.parse_prefix_expr_common(lo)?;
self.sess.gated_spans.gate(sym::box_syntax, span);
Ok((span, ExprKind::Box(expr)))
}
/// Recover on `not expr` in favor of `!expr`.
fn recover_not_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
- self.bump();
- // Emit the error ...
+ // Emit the error...
+ let not_token = self.look_ahead(1, |t| t.clone());
self.struct_span_err(
- self.token.span,
- &format!("unexpected {} after identifier", self.this_token_descr()),
+ not_token.span,
+ &format!("unexpected {} after identifier", super::token_descr(¬_token)),
)
.span_suggestion_short(
// Span the `not` plus trailing whitespace to avoid
// trailing whitespace after the `!` in our suggestion
- self.sess.source_map().span_until_non_whitespace(lo.to(self.token.span)),
+ self.sess.source_map().span_until_non_whitespace(lo.to(not_token.span)),
"use `!` to perform logical negation",
"!".to_owned(),
Applicability::MachineApplicable,
)
.emit();
- // —and recover! (just as if we were in the block
- // for the `token::Not` arm)
- let expr = self.parse_prefix_expr(None);
- let (span, e) = self.interpolated_or_expr_span(expr)?;
- Ok((lo.to(span), self.mk_unary(UnOp::Not, e)))
+
+ // ...and recover!
+ self.parse_unary_expr(lo, UnOp::Not)
}
/// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
fn error_unexpected_after_dot(&self) {
// FIXME Could factor this out into non_fatal_unexpected or something.
- let actual = self.this_token_to_string();
+ let actual = pprust::token_to_string(&self.token);
self.struct_span_err(self.token.span, &format!("unexpected token: `{}`", actual)).emit();
}
pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
self.parse_opt_lit().ok_or_else(|| {
- let msg = format!("unexpected token: {}", self.this_token_descr());
+ let msg = format!("unexpected token: {}", super::token_descr(&self.token));
self.span_fatal(self.token.span, &msg)
})
}
self.expect_semi()?;
body
} else {
- let token_str = self.this_token_descr();
+ let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!(
"expected `where`, `{{`, `(`, or `;` after struct name, found {}",
token_str
let (fields, recovered) = self.parse_record_struct_body()?;
VariantData::Struct(fields, recovered)
} else {
- let token_str = self.this_token_descr();
+ let token_str = super::token_descr(&self.token);
let mut err = self
.fatal(&format!("expected `where` or `{{` after union name, found {}", token_str));
err.span_label(self.token.span, "expected `where` or `{` after union name");
}
self.eat(&token::CloseDelim(token::Brace));
} else {
- let token_str = self.this_token_descr();
+ let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!(
"expected `where`, or `{{` after struct name, found {}",
token_str
let sp = self.sess.source_map().next_point(self.prev_span);
let mut err = self.struct_span_err(
sp,
- &format!("expected `,`, or `}}`, found {}", self.this_token_descr()),
+ &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
);
if self.token.is_ident() {
// This is likely another field; emit the diagnostic and keep going
No,
}
+fn token_descr_opt(token: &Token) -> Option<&'static str> {
+ Some(match token.kind {
+ _ if token.is_special_ident() => "reserved identifier",
+ _ if token.is_used_keyword() => "keyword",
+ _ if token.is_unused_keyword() => "reserved keyword",
+ token::DocComment(..) => "doc comment",
+ _ => return None,
+ })
+}
+
+pub(super) fn token_descr(token: &Token) -> String {
+ let token_str = pprust::token_to_string(token);
+ match token_descr_opt(token) {
+ Some(prefix) => format!("{} `{}`", prefix, token_str),
+ _ => format!("`{}`", token_str),
+ }
+}
+
impl<'a> Parser<'a> {
pub fn new(
sess: &'a ParseSess,
next
}
- /// Converts the current token to a string using `self`'s reader.
- pub fn this_token_to_string(&self) -> String {
- pprust::token_to_string(&self.token)
- }
-
- fn token_descr(&self) -> Option<&'static str> {
- Some(match &self.token.kind {
- _ if self.token.is_special_ident() => "reserved identifier",
- _ if self.token.is_used_keyword() => "keyword",
- _ if self.token.is_unused_keyword() => "reserved keyword",
- token::DocComment(..) => "doc comment",
- _ => return None,
- })
- }
-
- pub(super) fn this_token_descr(&self) -> String {
- if let Some(prefix) = self.token_descr() {
- format!("{} `{}`", prefix, self.this_token_to_string())
- } else {
- format!("`{}`", self.this_token_to_string())
- }
- }
-
crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
match self.expect_one_of(&[], &[]) {
Err(e) => Err(e),
}
if !self.eat(term) {
- let token_str = self.this_token_descr();
+ let token_str = super::token_descr(&self.token);
if !self.maybe_consume_incorrect_semicolon(&items) {
let mut err = self.fatal(&format!("expected item, found {}", token_str));
err.span_label(self.token.span, "expected item");
err.cancel();
let expected = expected.unwrap_or("pattern");
- let msg = format!("expected {}, found {}", expected, self.this_token_descr());
+ let msg = format!("expected {}, found {}", expected, super::token_descr(&self.token));
let mut err = self.fatal(&msg);
err.span_label(self.token.span, format!("expected {}", expected));
etc_span = Some(etc_sp);
break;
}
- let token_str = self.this_token_descr();
+ let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!("expected `}}`, found {}", token_str));
err.span_label(self.token.span, "expected `}`");
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
let sp = self.token.span;
- let tok = self.this_token_descr();
+ let tok = super::token_descr(&self.token);
let mut e = self.span_fatal(sp, &format!("expected `{{`, found {}", tok));
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
fn warn_missing_semicolon(&self) {
self.diagnostic()
.struct_span_warn(self.token.span, {
- &format!("expected `;`, found {}", self.this_token_descr())
+ &format!("expected `;`, found {}", super::token_descr(&self.token))
})
.note({
"this was erroneously allowed and will become a hard error in a future release"
TyKind::Err
}
} else {
- let msg = format!("expected type, found {}", self.this_token_descr());
+ let msg = format!("expected type, found {}", super::token_descr(&self.token));
let mut err = self.struct_span_err(self.token.span, &msg);
err.span_label(self.token.span, "expected type");
self.maybe_annotate_with_ascription(&mut err, true);
span: Span,
) {
if this.token != token::Eof {
- let msg = format!(
- "macro expansion ignores token `{}` and any following",
- this.this_token_to_string()
- );
+ let token = pprust::token_to_string(&this.token);
+ let msg = format!("macro expansion ignores token `{}` and any following", token);
// Avoid emitting backtrace info twice.
let def_site_span = this.token.span.with_ctxt(SyntaxContext::root());
let mut err = this.struct_span_err(def_site_span, &msg);
while self.p.token != token::Eof {
match panictry!(self.p.parse_item()) {
Some(item) => ret.push(item),
- None => self
- .p
- .sess
- .span_diagnostic
- .span_fatal(
- self.p.token.span,
- &format!("expected item, found `{}`", self.p.this_token_to_string()),
- )
- .raise(),
+ None => {
+ let token = pprust::token_to_string(&self.p.token);
+ self.p
+ .sess
+ .span_diagnostic
+ .span_fatal(
+ self.p.token.span,
+ &format!("expected item, found `{}`", token),
+ )
+ .raise();
+ }
}
}
Some(ret)