@@ -19,8 +19,10 @@ pub(super) struct TokenTreesReader<'a> {
19
19
/// Used only for error recovery when arriving to EOF with mismatched braces.
20
20
matching_delim_spans : Vec < ( Delimiter , Span , Span ) > ,
21
21
last_unclosed_found_span : Option < Span > ,
22
+
22
23
/// Collect empty block spans that might have been auto-inserted by editors.
23
- last_delim_empty_block_spans : FxHashMap < Delimiter , Span > ,
24
+ empty_block_spans : FxHashMap < Span , Delimiter > ,
25
+
24
26
/// Collect the spans of braces (Open, Close). Used only
25
27
/// for detecting if blocks are empty and only braces.
26
28
matching_block_spans : Vec < ( Span , Span ) > ,
@@ -37,7 +39,7 @@ impl<'a> TokenTreesReader<'a> {
37
39
unmatched_braces : Vec :: new ( ) ,
38
40
matching_delim_spans : Vec :: new ( ) ,
39
41
last_unclosed_found_span : None ,
40
- last_delim_empty_block_spans : FxHashMap :: default ( ) ,
42
+ empty_block_spans : FxHashMap :: default ( ) ,
41
43
matching_block_spans : Vec :: new ( ) ,
42
44
} ;
43
45
let res = tt_reader. parse_token_trees ( /* is_delimited */ false ) ;
@@ -135,11 +137,11 @@ impl<'a> TokenTreesReader<'a> {
135
137
if !sm. is_multiline ( empty_block_span) {
136
138
// Only track if the block is in the form of `{}`, otherwise it is
137
139
// likely that it was written on purpose.
138
- self . last_delim_empty_block_spans . insert ( open_delim , empty_block_span ) ;
140
+ self . empty_block_spans . insert ( empty_block_span , open_delim ) ;
139
141
}
140
142
}
141
143
142
- //only add braces
144
+ // only add braces
143
145
if let ( Delimiter :: Brace , Delimiter :: Brace ) = ( open_brace, open_delim) {
144
146
self . matching_block_spans . push ( ( open_brace_span, close_brace_span) ) ;
145
147
@@ -230,9 +232,8 @@ impl<'a> TokenTreesReader<'a> {
230
232
}
231
233
}
232
234
233
- fn report_error_prone_delim_block ( & self , delim : Delimiter , err : & mut Diagnostic ) {
235
+ fn report_error_prone_delim_block ( & mut self , delim : Delimiter , err : & mut Diagnostic ) {
234
236
let mut matched_spans = vec ! [ ] ;
235
- let mut candidate_span = None ;
236
237
237
238
for & ( d, open_sp, close_sp) in & self . matching_delim_spans {
238
239
if d == delim {
@@ -259,6 +260,7 @@ impl<'a> TokenTreesReader<'a> {
259
260
}
260
261
}
261
262
263
+ let mut candidate_span = None ;
262
264
// Find the innermost span candidate for final report
263
265
for ( block_span, same_ident) in matched_spans. into_iter ( ) . rev ( ) {
264
266
if !same_ident {
@@ -276,6 +278,15 @@ impl<'a> TokenTreesReader<'a> {
276
278
block_span. shrink_to_hi ( ) ,
277
279
"...as it matches this but it has different indentation" ,
278
280
) ;
281
+
282
+ // If there is a empty block in the mismatched span, note it
283
+ for span in self . empty_block_spans . keys ( ) {
284
+ if let Some ( d) = self . empty_block_spans . get ( span) &&
285
+ * d == delim && block_span. contains ( * span) {
286
+ err. span_label ( * span, "block is empty, you might have not meant to close it" ) ;
287
+ break ;
288
+ }
289
+ }
279
290
}
280
291
}
281
292
}
0 commit comments