11use super :: { StringReader , UnmatchedBrace } ;
22
3- use rustc_ast:: token:: { self , Token } ;
3+ use rustc_ast:: token:: { self , DelimToken , Token } ;
44use rustc_ast:: tokenstream:: {
55 DelimSpan ,
66 IsJoint :: { self , * } ,
@@ -22,6 +22,7 @@ impl<'a> StringReader<'a> {
2222 matching_delim_spans : Vec :: new ( ) ,
2323 last_unclosed_found_span : None ,
2424 last_delim_empty_block_spans : FxHashMap :: default ( ) ,
25+ matching_block_spans : Vec :: new ( ) ,
2526 } ;
2627 let res = tt_reader. parse_all_token_trees ( ) ;
2728 ( res, tt_reader. unmatched_braces )
@@ -42,6 +43,9 @@ struct TokenTreesReader<'a> {
4243 last_unclosed_found_span : Option < Span > ,
4344 /// Collect empty block spans that might have been auto-inserted by editors.
4445 last_delim_empty_block_spans : FxHashMap < token:: DelimToken , Span > ,
46+ /// Collect the spans of braces (Open, Close). Used only
47+ /// for detecting if blocks are empty and only braces.
48+ matching_block_spans : Vec < ( Span , Span ) > ,
4549}
4650
4751impl < ' a > TokenTreesReader < ' a > {
@@ -77,6 +81,7 @@ impl<'a> TokenTreesReader<'a> {
7781
7882 fn parse_token_tree ( & mut self ) -> PResult < ' a , TreeAndJoint > {
7983 let sm = self . string_reader . sess . source_map ( ) ;
84+
8085 match self . token . kind {
8186 token:: Eof => {
8287 let msg = "this file contains an unclosed delimiter" ;
@@ -146,6 +151,14 @@ impl<'a> TokenTreesReader<'a> {
146151 }
147152 }
148153
154+ match ( open_brace, delim) {
155+ //only add braces
156+ ( DelimToken :: Brace , DelimToken :: Brace ) => {
157+ self . matching_block_spans . push ( ( open_brace_span, close_brace_span) ) ;
158+ }
159+ _ => { }
160+ }
161+
149162 if self . open_braces . is_empty ( ) {
150163 // Clear up these spans to avoid suggesting them as we've found
151164 // properly matched delimiters so far for an entire block.
@@ -164,6 +177,7 @@ impl<'a> TokenTreesReader<'a> {
164177 token:: CloseDelim ( other) => {
165178 let mut unclosed_delimiter = None ;
166179 let mut candidate = None ;
180+
167181 if self . last_unclosed_found_span != Some ( self . token . span ) {
168182 // do not complain about the same unclosed delimiter multiple times
169183 self . last_unclosed_found_span = Some ( self . token . span ) ;
@@ -224,12 +238,27 @@ impl<'a> TokenTreesReader<'a> {
224238 let mut err =
225239 self . string_reader . sess . span_diagnostic . struct_span_err ( self . token . span , & msg) ;
226240
227- if let Some ( span) = self . last_delim_empty_block_spans . remove ( & delim) {
228- err. span_label (
229- span,
230- "this block is empty, you might have not meant to close it" ,
231- ) ;
241+ // Braces are added at the end, so the last element is the biggest block
242+ if let Some ( parent) = self . matching_block_spans . last ( ) {
243+ if let Some ( span) = self . last_delim_empty_block_spans . remove ( & delim) {
244+ // Check if the (empty block) is in the last properly closed block
245+ if ( parent. 0 . to ( parent. 1 ) ) . contains ( span) {
246+ err. span_label (
247+ span,
248+ "block is empty, you might have not meant to close it" ,
249+ ) ;
250+ } else {
251+ err. span_label ( parent. 0 , "this opening brace..." ) ;
252+
253+ err. span_label ( parent. 1 , "...matches this closing brace" ) ;
254+ }
255+ } else {
256+ err. span_label ( parent. 0 , "this opening brace..." ) ;
257+
258+ err. span_label ( parent. 1 , "...matches this closing brace" ) ;
259+ }
232260 }
261+
233262 err. span_label ( self . token . span , "unexpected closing delimiter" ) ;
234263 Err ( err)
235264 }
0 commit comments