diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-05-21 22:17:53 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-05-24 11:50:21 -0700 |
| commit | 5c5fa775e568bc42f876aa7efcb386b404906df4 (patch) | |
| tree | 3913ec15eee84bad790ebd7c79406651b7319f3f /src/libsyntax/parse/diagnostics.rs | |
| parent | 24160171e48a277ef71e84e14fbffffe3c81438a (diff) | |
| download | rust-5c5fa775e568bc42f876aa7efcb386b404906df4.tar.gz rust-5c5fa775e568bc42f876aa7efcb386b404906df4.zip | |
review comments
Diffstat (limited to 'src/libsyntax/parse/diagnostics.rs')
| -rw-r--r-- | src/libsyntax/parse/diagnostics.rs | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index 8ac5beb21b5..8174367ca45 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -13,7 +13,7 @@ use crate::symbol::kw; use crate::ThinVec; use errors::{Applicability, DiagnosticBuilder}; use log::debug; -use syntax_pos::Span; +use syntax_pos::{Span, DUMMY_SP}; pub trait RecoverQPath: Sized + 'static { const PATH_STYLE: PathStyle = PathStyle::Expr; @@ -201,7 +201,7 @@ impl<'a> Parser<'a> { let mut path = ast::Path { segments: Vec::new(), - span: syntax_pos::DUMMY_SP, + span: DUMMY_SP, }; self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?; path.span = ty_span.to(self.prev_span); @@ -267,6 +267,58 @@ impl<'a> Parser<'a> { } } + /// Create a `DiagnosticBuilder` for an unexpected token `t` and try to recover if it is a + /// closing delimiter. + pub fn unexpected_try_recover( + &mut self, + t: &token::Token, + ) -> PResult<'a, bool /* recovered */> { + let token_str = pprust::token_to_string(t); + let this_token_str = self.this_token_descr(); + let (prev_sp, sp) = match (&self.token, self.subparser_name) { + // Point at the end of the macro call when reaching end of macro arguments. + (token::Token::Eof, Some(_)) => { + let sp = self.sess.source_map().next_point(self.span); + (sp, sp) + } + // We don't want to point at the following span after DUMMY_SP. + // This happens when the parser finds an empty TokenStream. + _ if self.prev_span == DUMMY_SP => (self.span, self.span), + // EOF, don't want to point at the following char, but rather the last token. + (token::Token::Eof, None) => (self.prev_span, self.span), + _ => (self.sess.source_map().next_point(self.prev_span), self.span), + }; + let msg = format!( + "expected `{}`, found {}", + token_str, + match (&self.token, self.subparser_name) { + (token::Token::Eof, Some(origin)) => format!("end of {}", origin), + _ => this_token_str, + }, + ); + let mut err = self.struct_span_err(sp, &msg); + let label_exp = format!("expected `{}`", token_str); + match self.recover_closing_delimiter(&[t.clone()], err) { + Err(e) => err = e, + Ok(recovered) => { + return Ok(recovered); + } + } + let cm = self.sess.source_map(); + match (cm.lookup_line(prev_sp.lo()), cm.lookup_line(sp.lo())) { + (Ok(ref a), Ok(ref b)) if a.line == b.line => { + // When the spans are in the same line, it means that the only content + // between them is whitespace, point only at the found token. + err.span_label(sp, label_exp); + } + _ => { + err.span_label(prev_sp, label_exp); + err.span_label(sp, "unexpected token"); + } + } + Err(err) + } + /// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)` /// and `await { <expr> }`. crate fn parse_incorrect_await_syntax( |
