diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-04-01 14:32:14 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-01 14:32:14 +0200 |
| commit | c739465b1b760911d0e27df18a3b0460afbd4419 (patch) | |
| tree | c00d88de344604e53211cc9b7b699c880d5c1187 /src/librustc_parse/parser | |
| parent | 84a463388040a1bc86578c0e3df2bf65e91127d3 (diff) | |
| parent | 55a5eea763ed330bd9c3da4fbe9cf7d448afbe83 (diff) | |
Rollup merge of #70522 - rcoh:60762-raw-string-errors, r=petrochenkov
Improve error messages for raw strings (#60762) This diff improves error messages around raw strings in a few ways: - Catch extra trailing `#` in the parser. This can't be handled in the lexer because we could be in a macro that actually expects another # (see test) - Refactor & unify error handling in the lexer between ByteStrings and RawByteStrings - Detect potentially intended terminators (longest sequence of "#*" is suggested) Fixes #60762 cc @estebank who reviewed the original (abandoned) PR for the same ticket. r? @Centril
Diffstat (limited to 'src/librustc_parse/parser')
| -rw-r--r-- | src/librustc_parse/parser/diagnostics.rs | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index c4546dedfcd..12b9b682682 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -6,7 +6,7 @@ use rustc_ast::ast::{ }; use rustc_ast::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, TokenKind}; +use rustc_ast::token::{self, Lit, LitKind, TokenKind}; use rustc_ast::util::parser::AssocOp; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -255,6 +255,10 @@ impl<'a> Parser<'a> { } } + if self.check_too_many_raw_str_terminators(&mut err) { + return Err(err); + } + let sm = self.sess.source_map(); if self.prev_token.span == DUMMY_SP { // Account for macro context where the previous span might not be @@ -282,6 +286,29 @@ impl<'a> Parser<'a> { Err(err) } + fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool { + match (&self.prev_token.kind, &self.token.kind) { + ( + TokenKind::Literal(Lit { + kind: LitKind::StrRaw(n_hashes) | LitKind::ByteStrRaw(n_hashes), + .. + }), + TokenKind::Pound, + ) => { + err.set_primary_message("too many `#` when terminating raw string"); + err.span_suggestion( + self.token.span, + "remove the extra `#`", + String::new(), + Applicability::MachineApplicable, + ); + err.note(&format!("the raw string started with {} `#`s", n_hashes)); + true + } + _ => false, + } + } + pub fn maybe_annotate_with_ascription( &mut self, err: &mut DiagnosticBuilder<'_>, @@ -491,7 +518,7 @@ impl<'a> Parser<'a> { .unwrap_or_else(|_| pprust::expr_to_string(&e)) }; err.span_suggestion_verbose( - inner_op.span.shrink_to_hi(), + inner_op.span.shrink_to_hi(), "split the comparison into two", format!(" && {}", expr_to_str(&r1)), Applicability::MaybeIncorrect, @@ -1086,7 +1113,7 @@ impl<'a> Parser<'a> { self.look_ahead(2, |t| t.is_ident()) || self.look_ahead(1, |t| t == &token::ModSep) && (self.look_ahead(2, |t| t.is_ident()) || // `foo:bar::baz` - self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>` + self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>` } pub(super) fn recover_seq_parse_error( |
