1
+ use rustc_data_structures:: fx:: FxHashMap ;
1
2
use syntax_pos:: Span ;
2
3
3
4
use crate :: print:: pprust:: token_to_string;
@@ -16,6 +17,7 @@ impl<'a> StringReader<'a> {
16
17
unmatched_braces : Vec :: new ( ) ,
17
18
matching_delim_spans : Vec :: new ( ) ,
18
19
last_unclosed_found_span : None ,
20
+ last_delim_empty_block_spans : FxHashMap :: default ( )
19
21
} ;
20
22
let res = tt_reader. parse_all_token_trees ( ) ;
21
23
( res, tt_reader. unmatched_braces )
@@ -34,6 +36,7 @@ struct TokenTreesReader<'a> {
34
36
/// Used only for error recovery when arriving to EOF with mismatched braces.
35
37
matching_delim_spans : Vec < ( token:: DelimToken , Span , Span ) > ,
36
38
last_unclosed_found_span : Option < Span > ,
39
+ last_delim_empty_block_spans : FxHashMap < token:: DelimToken , Span >
37
40
}
38
41
39
42
impl < ' a > TokenTreesReader < ' a > {
@@ -121,13 +124,20 @@ impl<'a> TokenTreesReader<'a> {
121
124
// Correct delimiter.
122
125
token:: CloseDelim ( d) if d == delim => {
123
126
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
+
124
134
if self . open_braces . len ( ) == 0 {
125
135
// Clear up these spans to avoid suggesting them as we've found
126
136
// properly matched delimiters so far for an entire block.
127
137
self . matching_delim_spans . clear ( ) ;
128
138
} else {
129
139
self . matching_delim_spans . push (
130
- ( open_brace, open_brace_span, self . token . span ) ,
140
+ ( open_brace, open_brace_span, close_brace_span ) ,
131
141
) ;
132
142
}
133
143
// Parse the close delimiter.
@@ -193,13 +203,20 @@ impl<'a> TokenTreesReader<'a> {
193
203
tts. into ( )
194
204
) . into ( ) )
195
205
} ,
196
- token:: CloseDelim ( _ ) => {
206
+ token:: CloseDelim ( delim ) => {
197
207
// An unexpected closing delimiter (i.e., there is no
198
208
// matching opening delimiter).
199
209
let token_str = token_to_string ( & self . token ) ;
200
210
let msg = format ! ( "unexpected close delimiter: `{}`" , token_str) ;
201
211
let mut err = self . string_reader . sess . span_diagnostic
202
212
. 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
+ }
203
220
err. span_label ( self . token . span , "unexpected close delimiter" ) ;
204
221
Err ( err)
205
222
} ,
0 commit comments