diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2019-10-18 13:48:16 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-18 13:48:16 -0700 |
| commit | 8f8a23f6422e78d1a30b40cb623e0b7b690218e9 (patch) | |
| tree | aa7de704a48f6e98d8308a59697840629c3db649 | |
| parent | bb53fed72f51dd5c0819d6ae3790154d34abde18 (diff) | |
| parent | fe819a074c748fd3d11fcc0be8164645a7cd58db (diff) | |
| download | rust-8f8a23f6422e78d1a30b40cb623e0b7b690218e9.tar.gz rust-8f8a23f6422e78d1a30b40cb623e0b7b690218e9.zip | |
Rollup merge of #65364 - XiangQingW:master, r=estebank
Collect occurrences of empty blocks for mismatched braces diagnostic Fix #63904
| -rw-r--r-- | src/libsyntax/parse/lexer/tokentrees.rs | 21 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/parser/mismatched-delim-brace-empty-block.rs | 5 | ||||
| -rw-r--r-- | src/test/ui/parser/mismatched-delim-brace-empty-block.stderr | 14 |
4 files changed, 39 insertions, 3 deletions
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs index e5ba7e45309..b4dd23c9f9b 100644 --- a/src/libsyntax/parse/lexer/tokentrees.rs +++ b/src/libsyntax/parse/lexer/tokentrees.rs @@ -1,3 +1,4 @@ +use rustc_data_structures::fx::FxHashMap; use syntax_pos::Span; use crate::print::pprust::token_to_string; @@ -16,6 +17,7 @@ impl<'a> StringReader<'a> { unmatched_braces: Vec::new(), matching_delim_spans: Vec::new(), last_unclosed_found_span: None, + last_delim_empty_block_spans: FxHashMap::default() }; let res = tt_reader.parse_all_token_trees(); (res, tt_reader.unmatched_braces) @@ -34,6 +36,7 @@ struct TokenTreesReader<'a> { /// Used only for error recovery when arriving to EOF with mismatched braces. matching_delim_spans: Vec<(token::DelimToken, Span, Span)>, last_unclosed_found_span: Option<Span>, + last_delim_empty_block_spans: FxHashMap<token::DelimToken, Span> } impl<'a> TokenTreesReader<'a> { @@ -121,13 +124,20 @@ impl<'a> TokenTreesReader<'a> { // Correct delimiter. token::CloseDelim(d) if d == delim => { let (open_brace, open_brace_span) = self.open_braces.pop().unwrap(); + let close_brace_span = self.token.span; + + if tts.is_empty() { + let empty_block_span = open_brace_span.to(close_brace_span); + self.last_delim_empty_block_spans.insert(delim, empty_block_span); + } + if self.open_braces.len() == 0 { // Clear up these spans to avoid suggesting them as we've found // properly matched delimiters so far for an entire block. self.matching_delim_spans.clear(); } else { self.matching_delim_spans.push( - (open_brace, open_brace_span, self.token.span), + (open_brace, open_brace_span, close_brace_span), ); } // Parse the close delimiter. @@ -193,13 +203,20 @@ impl<'a> TokenTreesReader<'a> { tts.into() ).into()) }, - token::CloseDelim(_) => { + token::CloseDelim(delim) => { // An unexpected closing delimiter (i.e., there is no // matching opening delimiter). let token_str = token_to_string(&self.token); let msg = format!("unexpected close delimiter: `{}`", token_str); let mut err = self.string_reader.sess.span_diagnostic .struct_span_err(self.token.span, &msg); + + if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) { + err.span_label( + span, + "this block is empty, you might have not meant to close it" + ); + } err.span_label(self.token.span, "unexpected close delimiter"); Err(err) }, diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index e527989fb0b..4a8b25c6107 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -33,7 +33,7 @@ pub enum BinOpToken { } /// A delimiter token. -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum DelimToken { /// A round parenthesis (i.e., `(` or `)`). Paren, diff --git a/src/test/ui/parser/mismatched-delim-brace-empty-block.rs b/src/test/ui/parser/mismatched-delim-brace-empty-block.rs new file mode 100644 index 00000000000..0f5a2cb09ec --- /dev/null +++ b/src/test/ui/parser/mismatched-delim-brace-empty-block.rs @@ -0,0 +1,5 @@ +fn main() { + +} + let _ = (); +} //~ ERROR unexpected close delimiter diff --git a/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr new file mode 100644 index 00000000000..5ae5fc91a4e --- /dev/null +++ b/src/test/ui/parser/mismatched-delim-brace-empty-block.stderr @@ -0,0 +1,14 @@ +error: unexpected close delimiter: `}` + --> $DIR/mismatched-delim-brace-empty-block.rs:5:1 + | +LL | fn main() { + | ___________- +LL | | +LL | | } + | |_- this block is empty, you might have not meant to close it +LL | let _ = (); +LL | } + | ^ unexpected close delimiter + +error: aborting due to previous error + |
