Skip to content

Commit 8f8a23f

Browse files
authored
Rollup merge of rust-lang#65364 - XiangQingW:master, r=estebank
Collect occurrences of empty blocks for mismatched braces diagnostic Fix rust-lang#63904
2 parents bb53fed + fe819a0 commit 8f8a23f

File tree

4 files changed

+39
-3
lines changed

4 files changed

+39
-3
lines changed

src/libsyntax/parse/lexer/tokentrees.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_data_structures::fx::FxHashMap;
12
use syntax_pos::Span;
23

34
use crate::print::pprust::token_to_string;
@@ -16,6 +17,7 @@ impl<'a> StringReader<'a> {
1617
unmatched_braces: Vec::new(),
1718
matching_delim_spans: Vec::new(),
1819
last_unclosed_found_span: None,
20+
last_delim_empty_block_spans: FxHashMap::default()
1921
};
2022
let res = tt_reader.parse_all_token_trees();
2123
(res, tt_reader.unmatched_braces)
@@ -34,6 +36,7 @@ struct TokenTreesReader<'a> {
3436
/// Used only for error recovery when arriving to EOF with mismatched braces.
3537
matching_delim_spans: Vec<(token::DelimToken, Span, Span)>,
3638
last_unclosed_found_span: Option<Span>,
39+
last_delim_empty_block_spans: FxHashMap<token::DelimToken, Span>
3740
}
3841

3942
impl<'a> TokenTreesReader<'a> {
@@ -121,13 +124,20 @@ impl<'a> TokenTreesReader<'a> {
121124
// Correct delimiter.
122125
token::CloseDelim(d) if d == delim => {
123126
let (open_brace, open_brace_span) = self.open_braces.pop().unwrap();
127+
let close_brace_span = self.token.span;
128+
129+
if tts.is_empty() {
130+
let empty_block_span = open_brace_span.to(close_brace_span);
131+
self.last_delim_empty_block_spans.insert(delim, empty_block_span);
132+
}
133+
124134
if self.open_braces.len() == 0 {
125135
// Clear up these spans to avoid suggesting them as we've found
126136
// properly matched delimiters so far for an entire block.
127137
self.matching_delim_spans.clear();
128138
} else {
129139
self.matching_delim_spans.push(
130-
(open_brace, open_brace_span, self.token.span),
140+
(open_brace, open_brace_span, close_brace_span),
131141
);
132142
}
133143
// Parse the close delimiter.
@@ -193,13 +203,20 @@ impl<'a> TokenTreesReader<'a> {
193203
tts.into()
194204
).into())
195205
},
196-
token::CloseDelim(_) => {
206+
token::CloseDelim(delim) => {
197207
// An unexpected closing delimiter (i.e., there is no
198208
// matching opening delimiter).
199209
let token_str = token_to_string(&self.token);
200210
let msg = format!("unexpected close delimiter: `{}`", token_str);
201211
let mut err = self.string_reader.sess.span_diagnostic
202212
.struct_span_err(self.token.span, &msg);
213+
214+
if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) {
215+
err.span_label(
216+
span,
217+
"this block is empty, you might have not meant to close it"
218+
);
219+
}
203220
err.span_label(self.token.span, "unexpected close delimiter");
204221
Err(err)
205222
},

src/libsyntax/parse/token.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub enum BinOpToken {
3333
}
3434

3535
/// A delimiter token.
36-
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
36+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
3737
pub enum DelimToken {
3838
/// A round parenthesis (i.e., `(` or `)`).
3939
Paren,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
3+
}
4+
let _ = ();
5+
} //~ ERROR unexpected close delimiter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unexpected close delimiter: `}`
2+
--> $DIR/mismatched-delim-brace-empty-block.rs:5:1
3+
|
4+
LL | fn main() {
5+
| ___________-
6+
LL | |
7+
LL | | }
8+
| |_- this block is empty, you might have not meant to close it
9+
LL | let _ = ();
10+
LL | }
11+
| ^ unexpected close delimiter
12+
13+
error: aborting due to previous error
14+

0 commit comments

Comments
 (0)