diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 377d43dec21a..0be83e418e30 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -1,9 +1,10 @@ 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; @@ -154,7 +155,7 @@ impl<'a> Parser<'a> { (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))); } }; @@ -329,7 +330,7 @@ impl<'a> Parser<'a> { 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)) } diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index f58b9a4c1444..578f816be58c 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -200,7 +200,7 @@ impl<'a> Parser<'a> { 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, @@ -225,7 +225,7 @@ impl<'a> Parser<'a> { ); } } - 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"); @@ -272,7 +272,7 @@ impl<'a> Parser<'a> { 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()) @@ -815,7 +815,7 @@ impl<'a> Parser<'a> { 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(_)) => { @@ -862,7 +862,7 @@ impl<'a> Parser<'a> { 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. @@ -1270,7 +1270,7 @@ impl<'a> Parser<'a> { } pub(super) fn expected_semi_or_open_brace(&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) @@ -1447,7 +1447,7 @@ impl<'a> Parser<'a> { } _ => ( 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); diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 606714b5fa2e..9b106b6db3c0 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -442,35 +442,37 @@ impl<'a> Parser<'a> { } /// Parses a prefix-unary-operator expr. - fn parse_prefix_expr(&mut self, already_parsed_attrs: Option) -> PResult<'a, P> { - let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?; + fn parse_prefix_expr(&mut self, attrs: Option) -> PResult<'a, P> { + 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)) + } + + fn parse_prefix_expr_common(&mut self, lo: Span) -> PResult<'a, (Span, P)> { + 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.bump(); - let expr = self.parse_prefix_expr(None); - let (span, expr) = self.interpolated_or_expr_span(expr)?; self.struct_span_err(lo, "`~` cannot be used as a unary operator") .span_suggestion_short( lo, @@ -479,31 +481,13 @@ impl<'a> Parser<'a> { 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))) } @@ -521,26 +505,24 @@ impl<'a> Parser<'a> { /// 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. @@ -738,7 +720,7 @@ impl<'a> Parser<'a> { 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(); } @@ -1142,7 +1124,7 @@ impl<'a> Parser<'a> { 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) }) } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 8f8e5fbb7876..343c6667d47d 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1348,7 +1348,7 @@ impl<'a> Parser<'a> { 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 @@ -1374,7 +1374,7 @@ impl<'a> Parser<'a> { 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"); @@ -1411,7 +1411,7 @@ impl<'a> Parser<'a> { } 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 @@ -1498,7 +1498,7 @@ impl<'a> Parser<'a> { 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 diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 97084482025b..103bbe5dd763 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -354,6 +354,24 @@ pub enum FollowedByType { 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, @@ -422,29 +440,6 @@ impl<'a> Parser<'a> { 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(&mut self) -> PResult<'a, T> { match self.expect_one_of(&[], &[]) { Err(e) => Err(e), diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index eaeb3af4ca2a..3f54e0b6de03 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -79,7 +79,7 @@ impl<'a> Parser<'a> { } 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"); diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 9b5bf7e2378f..01b122618acb 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -670,7 +670,7 @@ impl<'a> Parser<'a> { 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)); @@ -875,7 +875,7 @@ impl<'a> Parser<'a> { 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 `}`"); diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 44a197503bd7..8270da6c0234 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -323,7 +323,7 @@ impl<'a> Parser<'a> { fn error_block_no_opening_brace(&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; @@ -463,7 +463,7 @@ impl<'a> Parser<'a> { 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" diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index fe3db358accd..049c077c3cea 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -135,7 +135,7 @@ impl<'a> Parser<'a> { 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); diff --git a/src/libsyntax_expand/expand.rs b/src/libsyntax_expand/expand.rs index b9b449d17791..4df51ff41f3f 100644 --- a/src/libsyntax_expand/expand.rs +++ b/src/libsyntax_expand/expand.rs @@ -904,10 +904,8 @@ pub fn ensure_complete_parse<'a>( 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); diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs index 4f46252f8be6..fccc36e2ea80 100644 --- a/src/libsyntax_ext/source_util.rs +++ b/src/libsyntax_ext/source_util.rs @@ -133,15 +133,17 @@ pub fn expand_include<'cx>( 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)