@@ -2,6 +2,7 @@ use rustc_ast::token::{self, Delimiter, Token};
2
2
use rustc_ast:: tokenstream:: { DelimSpacing , DelimSpan , Spacing , TokenStream , TokenTree } ;
3
3
use rustc_ast_pretty:: pprust:: token_to_string;
4
4
use rustc_errors:: Diag ;
5
+ use rustc_span:: Span ;
5
6
6
7
use super :: diagnostics:: { report_suspicious_mismatch_block, same_indentation_level} ;
7
8
use super :: { Lexer , UnmatchedDelim } ;
@@ -23,7 +24,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
23
24
// Invisible delimiters cannot occur here because `TokenTreesReader` parses
24
25
// code directly from strings, with no macro expansion involved.
25
26
debug_assert ! ( !matches!( delim, Delimiter :: Invisible ( _) ) ) ;
26
- buf. push ( match self . lex_token_tree_open_delim ( delim) {
27
+ buf. push ( match self . lex_token_tree_open_delim ( delim, self . token . span ) {
27
28
Ok ( val) => val,
28
29
Err ( errs) => return Err ( errs) ,
29
30
} )
@@ -59,8 +60,8 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
59
60
let mut err = self . dcx ( ) . struct_span_err ( self . token . span , msg) ;
60
61
61
62
let unclosed_delimiter_show_limit = 5 ;
62
- let len = usize:: min ( unclosed_delimiter_show_limit, self . diag_info . open_braces . len ( ) ) ;
63
- for & ( _, span) in & self . diag_info . open_braces [ ..len] {
63
+ let len = usize:: min ( unclosed_delimiter_show_limit, self . diag_info . open_delimiters . len ( ) ) ;
64
+ for & ( _, span) in & self . diag_info . open_delimiters [ ..len] {
64
65
err. span_label ( span, "unclosed delimiter" ) ;
65
66
self . diag_info . unmatched_delims . push ( UnmatchedDelim {
66
67
found_delim : None ,
@@ -70,19 +71,19 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
70
71
} ) ;
71
72
}
72
73
73
- if let Some ( ( _, span) ) = self . diag_info . open_braces . get ( unclosed_delimiter_show_limit)
74
- && self . diag_info . open_braces . len ( ) >= unclosed_delimiter_show_limit + 2
74
+ if let Some ( ( _, span) ) = self . diag_info . open_delimiters . get ( unclosed_delimiter_show_limit)
75
+ && self . diag_info . open_delimiters . len ( ) >= unclosed_delimiter_show_limit + 2
75
76
{
76
77
err. span_label (
77
78
* span,
78
79
format ! (
79
80
"another {} unclosed delimiters begin from here" ,
80
- self . diag_info. open_braces . len( ) - unclosed_delimiter_show_limit
81
+ self . diag_info. open_delimiters . len( ) - unclosed_delimiter_show_limit
81
82
) ,
82
83
) ;
83
84
}
84
85
85
- if let Some ( ( delim, _) ) = self . diag_info . open_braces . last ( ) {
86
+ if let Some ( ( delim, _) ) = self . diag_info . open_delimiters . last ( ) {
86
87
report_suspicious_mismatch_block (
87
88
& mut err,
88
89
& self . diag_info ,
@@ -96,11 +97,12 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
96
97
fn lex_token_tree_open_delim (
97
98
& mut self ,
98
99
open_delim : Delimiter ,
100
+ open_delim_span : Span ,
99
101
) -> Result < TokenTree , Vec < Diag < ' psess > > > {
100
102
// The span for beginning of the delimited section.
101
103
let pre_span = self . token . span ;
102
104
103
- self . diag_info . open_braces . push ( ( open_delim, self . token . span ) ) ;
105
+ self . diag_info . open_delimiters . push ( ( open_delim, self . token . span ) ) ;
104
106
105
107
// Lex the token trees within the delimiters.
106
108
// We stop at any delimiter so we can try to recover if the user
@@ -114,11 +116,12 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
114
116
let close_spacing = match self . token . kind {
115
117
// Correct delimiter.
116
118
token:: CloseDelim ( close_delim) if close_delim == open_delim => {
117
- let ( open_brace, open_brace_span) = self . diag_info . open_braces . pop ( ) . unwrap ( ) ;
118
- let close_brace_span = self . token . span ;
119
+ let ( open_delimiter, open_delimiter_span) =
120
+ self . diag_info . open_delimiters . pop ( ) . unwrap ( ) ;
121
+ let close_delim_span = self . token . span ;
119
122
120
123
if tts. is_empty ( ) && close_delim == Delimiter :: Brace {
121
- let empty_block_span = open_brace_span . to ( close_brace_span ) ;
124
+ let empty_block_span = open_delimiter_span . to ( close_delim_span ) ;
122
125
if !sm. is_multiline ( empty_block_span) {
123
126
// Only track if the block is in the form of `{}`, otherwise it is
124
127
// likely that it was written on purpose.
@@ -127,9 +130,11 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
127
130
}
128
131
129
132
// only add braces
130
- if let ( Delimiter :: Brace , Delimiter :: Brace ) = ( open_brace, open_delim) {
133
+ if let ( Delimiter :: Brace , Delimiter :: Brace ) = ( open_delimiter, open_delim)
134
+ && open_delimiter_span == open_delim_span
135
+ {
131
136
// Add all the matching spans, we will sort by span later
132
- self . diag_info . matching_block_spans . push ( ( open_brace_span , close_brace_span ) ) ;
137
+ self . diag_info . matching_block_spans . push ( ( open_delim_span , close_delim_span ) ) ;
133
138
}
134
139
135
140
// Move past the closing delimiter.
@@ -146,26 +151,26 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
146
151
// This is a conservative error: only report the last unclosed
147
152
// delimiter. The previous unclosed delimiters could actually be
148
153
// closed! The lexer just hasn't gotten to them yet.
149
- if let Some ( & ( _, sp) ) = self . diag_info . open_braces . last ( ) {
154
+ if let Some ( & ( _, sp) ) = self . diag_info . open_delimiters . last ( ) {
150
155
unclosed_delimiter = Some ( sp) ;
151
156
} ;
152
- for ( brace , brace_span ) in & self . diag_info . open_braces {
153
- if same_indentation_level ( sm, self . token . span , * brace_span )
154
- && brace == & close_delim
157
+ for ( delim , delim_span ) in & self . diag_info . open_delimiters {
158
+ if same_indentation_level ( sm, self . token . span , * delim_span )
159
+ && delim == & close_delim
155
160
{
156
161
// high likelihood of these two corresponding
157
- candidate = Some ( * brace_span ) ;
162
+ candidate = Some ( * delim_span ) ;
158
163
}
159
164
}
160
- let ( _, _) = self . diag_info . open_braces . pop ( ) . unwrap ( ) ;
165
+ let ( _, _) = self . diag_info . open_delimiters . pop ( ) . unwrap ( ) ;
161
166
self . diag_info . unmatched_delims . push ( UnmatchedDelim {
162
167
found_delim : Some ( close_delim) ,
163
168
found_span : self . token . span ,
164
169
unclosed_span : unclosed_delimiter,
165
170
candidate_span : candidate,
166
171
} ) ;
167
172
} else {
168
- self . diag_info . open_braces . pop ( ) ;
173
+ self . diag_info . open_delimiters . pop ( ) ;
169
174
}
170
175
171
176
// If the incorrect delimiter matches an earlier opening
@@ -175,7 +180,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
175
180
// fn foo() {
176
181
// bar(baz(
177
182
// } // Incorrect delimiter but matches the earlier `{`
178
- if !self . diag_info . open_braces . iter ( ) . any ( |& ( b , _) | b == close_delim) {
183
+ if !self . diag_info . open_delimiters . iter ( ) . any ( |& ( d , _) | d == close_delim) {
179
184
self . bump_minimal ( )
180
185
} else {
181
186
// The choice of value here doesn't matter.
0 commit comments