@@ -19,8 +19,10 @@ pub(super) struct TokenTreesReader<'a> {
1919 /// Used only for error recovery when arriving to EOF with mismatched braces.
2020 matching_delim_spans : Vec < ( Delimiter , Span , Span ) > ,
2121 last_unclosed_found_span : Option < Span > ,
22+
2223 /// 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+
2426 /// Collect the spans of braces (Open, Close). Used only
2527 /// for detecting if blocks are empty and only braces.
2628 matching_block_spans : Vec < ( Span , Span ) > ,
@@ -37,7 +39,7 @@ impl<'a> TokenTreesReader<'a> {
3739 unmatched_braces : Vec :: new ( ) ,
3840 matching_delim_spans : Vec :: new ( ) ,
3941 last_unclosed_found_span : None ,
40- last_delim_empty_block_spans : FxHashMap :: default ( ) ,
42+ empty_block_spans : FxHashMap :: default ( ) ,
4143 matching_block_spans : Vec :: new ( ) ,
4244 } ;
4345 let res = tt_reader. parse_token_trees ( /* is_delimited */ false ) ;
@@ -135,11 +137,11 @@ impl<'a> TokenTreesReader<'a> {
135137 if !sm. is_multiline ( empty_block_span) {
136138 // Only track if the block is in the form of `{}`, otherwise it is
137139 // 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 ) ;
139141 }
140142 }
141143
142- //only add braces
144+ // only add braces
143145 if let ( Delimiter :: Brace , Delimiter :: Brace ) = ( open_brace, open_delim) {
144146 self . matching_block_spans . push ( ( open_brace_span, close_brace_span) ) ;
145147
@@ -230,9 +232,8 @@ impl<'a> TokenTreesReader<'a> {
230232 }
231233 }
232234
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 ) {
234236 let mut matched_spans = vec ! [ ] ;
235- let mut candidate_span = None ;
236237
237238 for & ( d, open_sp, close_sp) in & self . matching_delim_spans {
238239 if d == delim {
@@ -259,6 +260,7 @@ impl<'a> TokenTreesReader<'a> {
259260 }
260261 }
261262
263+ let mut candidate_span = None ;
262264 // Find the innermost span candidate for final report
263265 for ( block_span, same_ident) in matched_spans. into_iter ( ) . rev ( ) {
264266 if !same_ident {
@@ -276,6 +278,15 @@ impl<'a> TokenTreesReader<'a> {
276278 block_span. shrink_to_hi ( ) ,
277279 "...as it matches this but it has different indentation" ,
278280 ) ;
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+ }
279290 }
280291 }
281292}
0 commit comments