diff options
| author | bors <bors@rust-lang.org> | 2019-11-04 02:30:45 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-04 02:30:45 +0000 |
| commit | f49f38871389041671cc710a044e8360091840a3 (patch) | |
| tree | ad7ea355839acdbf19ec6cc9f3af8b1cb12e864e /src/libsyntax/parse/parser.rs | |
| parent | 0d5264a03c2d873d9e23a22def748b9c6937c537 (diff) | |
| parent | 454e2aa8c99850c9393fb2314e1a71da08120063 (diff) | |
| download | rust-f49f38871389041671cc710a044e8360091840a3.tar.gz rust-f49f38871389041671cc710a044e8360091840a3.zip | |
Auto merge of #65838 - estebank:resilient-recovery, r=Centril
Reduce amount of errors given unclosed delimiter When in a file with a non-terminated item, catch the error and consume the block instead of trying to recover it on a more granular way in order to reduce the amount of unrelated errors that would be fixed after adding the missing closing brace. Also point out the possible location of the missing closing brace. Fix #63690.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6ead1ce811d..e81d4573b73 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -27,7 +27,7 @@ use crate::symbol::{kw, sym, Symbol}; use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use crate::ThinVec; -use errors::{Applicability, DiagnosticId, FatalError}; +use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{Span, BytePos, DUMMY_SP, FileName}; use log::debug; @@ -148,8 +148,7 @@ pub struct Parser<'a> { impl<'a> Drop for Parser<'a> { fn drop(&mut self) { - let diag = self.diagnostic(); - emit_unclosed_delims(&mut self.unclosed_delims, diag); + emit_unclosed_delims(&mut self.unclosed_delims, &self.sess); } } @@ -1370,20 +1369,31 @@ impl<'a> Parser<'a> { } } -pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) { - for unmatched in unclosed_delims.iter() { - let mut err = handler.struct_span_err(unmatched.found_span, &format!( - "incorrect close delimiter: `{}`", - pprust::token_kind_to_string(&token::CloseDelim(unmatched.found_delim)), - )); - err.span_label(unmatched.found_span, "incorrect close delimiter"); - if let Some(sp) = unmatched.candidate_span { - err.span_label(sp, "close delimiter possibly meant for this"); - } - if let Some(sp) = unmatched.unclosed_span { - err.span_label(sp, "un-closed delimiter"); - } - err.emit(); +crate fn make_unclosed_delims_error( + unmatched: UnmatchedBrace, + sess: &ParseSess, +) -> Option<DiagnosticBuilder<'_>> { + // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to + // `unmatched_braces` only for error recovery in the `Parser`. + let found_delim = unmatched.found_delim?; + let mut err = sess.span_diagnostic.struct_span_err(unmatched.found_span, &format!( + "incorrect close delimiter: `{}`", + pprust::token_kind_to_string(&token::CloseDelim(found_delim)), + )); + err.span_label(unmatched.found_span, "incorrect close delimiter"); + if let Some(sp) = unmatched.candidate_span { + err.span_label(sp, "close delimiter possibly meant for this"); + } + if let Some(sp) = unmatched.unclosed_span { + err.span_label(sp, "un-closed delimiter"); + } + Some(err) +} + +pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, sess: &ParseSess) { + *sess.reached_eof.borrow_mut() |= unclosed_delims.iter() + .any(|unmatched_delim| unmatched_delim.found_delim.is_none()); + for unmatched in unclosed_delims.drain(..) { + make_unclosed_delims_error(unmatched, sess).map(|mut e| e.emit()); } - unclosed_delims.clear(); } |
