@@ -177,25 +177,44 @@ impl<'a> SpanUtils<'a> {
177
177
}
178
178
179
179
// Return the span for the last ident before a `<` and outside any
180
- // brackets, or the last span.
180
+ // angle brackets, or the last span.
181
181
pub fn sub_span_for_type_name ( & self , span : Span ) -> Option < Span > {
182
182
let mut toks = self . retokenise_span ( span) ;
183
183
let mut prev = toks. real_token ( ) ;
184
184
let mut result = None ;
185
+
186
+ // We keep track of the following two counts - the depth of nesting of
187
+ // angle brackets, and the depth of nesting of square brackets. For the
188
+ // angle bracket count, we only count tokens which occur outside of any
189
+ // square brackets (i.e. bracket_count == 0). The intutition here is
190
+ // that we want to count angle brackets in the type, but not any which
191
+ // could be in expression context (because these could mean 'less than',
192
+ // etc.).
193
+ let mut angle_count = 0 ;
185
194
let mut bracket_count = 0 ;
186
195
loop {
187
196
let next = toks. real_token ( ) ;
188
197
189
- if ( next. tok == token:: Lt || next. tok == token:: Colon ) && bracket_count == 0 &&
198
+ if ( next. tok == token:: Lt || next. tok == token:: Colon ) &&
199
+ angle_count == 0 &&
200
+ bracket_count == 0 &&
190
201
prev. tok . is_ident ( ) {
191
202
result = Some ( prev. sp ) ;
192
203
}
193
204
205
+ if bracket_count == 0 {
206
+ angle_count += match prev. tok {
207
+ token:: Lt => 1 ,
208
+ token:: Gt => -1 ,
209
+ token:: BinOp ( token:: Shl ) => 2 ,
210
+ token:: BinOp ( token:: Shr ) => -2 ,
211
+ _ => 0 ,
212
+ } ;
213
+ }
214
+
194
215
bracket_count += match prev. tok {
195
- token:: Lt => 1 ,
196
- token:: Gt => -1 ,
197
- token:: BinOp ( token:: Shl ) => 2 ,
198
- token:: BinOp ( token:: Shr ) => -2 ,
216
+ token:: OpenDelim ( token:: Bracket ) => 1 ,
217
+ token:: CloseDelim ( token:: Bracket ) => -1 ,
199
218
_ => 0 ,
200
219
} ;
201
220
@@ -204,7 +223,7 @@ impl<'a> SpanUtils<'a> {
204
223
}
205
224
prev = next;
206
225
}
207
- if bracket_count != 0 {
226
+ if angle_count != 0 || bracket_count != 0 {
208
227
let loc = self . sess . codemap ( ) . lookup_char_pos ( span. lo ) ;
209
228
span_bug ! ( span,
210
229
"Mis-counted brackets when breaking path? Parsing '{}' \
@@ -213,7 +232,7 @@ impl<'a> SpanUtils<'a> {
213
232
loc. file. name,
214
233
loc. line) ;
215
234
}
216
- if result. is_none ( ) && prev. tok . is_ident ( ) && bracket_count == 0 {
235
+ if result. is_none ( ) && prev. tok . is_ident ( ) && angle_count == 0 {
217
236
return self . make_sub_span ( span, Some ( prev. sp ) ) ;
218
237
}
219
238
self . make_sub_span ( span, result)
@@ -222,19 +241,20 @@ impl<'a> SpanUtils<'a> {
222
241
// Reparse span and return an owned vector of sub spans of the first limit
223
242
// identifier tokens in the given nesting level.
224
243
// example with Foo<Bar<T,V>, Bar<T,V>>
225
- // Nesting = 0: all idents outside of brackets: [Foo]
226
- // Nesting = 1: idents within one level of brackets: [Bar, Bar]
244
+ // Nesting = 0: all idents outside of angle brackets: [Foo]
245
+ // Nesting = 1: idents within one level of angle brackets: [Bar, Bar]
227
246
pub fn spans_with_brackets ( & self , span : Span , nesting : isize , limit : isize ) -> Vec < Span > {
228
247
let mut result: Vec < Span > = vec ! [ ] ;
229
248
230
249
let mut toks = self . retokenise_span ( span) ;
231
250
// We keep track of how many brackets we're nested in
251
+ let mut angle_count: isize = 0 ;
232
252
let mut bracket_count: isize = 0 ;
233
253
let mut found_ufcs_sep = false ;
234
254
loop {
235
255
let ts = toks. real_token ( ) ;
236
256
if ts. tok == token:: Eof {
237
- if bracket_count != 0 {
257
+ if angle_count != 0 || bracket_count != 0 {
238
258
if generated_code ( span) {
239
259
return vec ! [ ] ;
240
260
}
@@ -252,6 +272,14 @@ impl<'a> SpanUtils<'a> {
252
272
return result;
253
273
}
254
274
bracket_count += match ts. tok {
275
+ token:: OpenDelim ( token:: Bracket ) => 1 ,
276
+ token:: CloseDelim ( token:: Bracket ) => -1 ,
277
+ _ => 0 ,
278
+ } ;
279
+ if bracket_count > 0 {
280
+ continue ;
281
+ }
282
+ angle_count += match ts. tok {
255
283
token:: Lt => 1 ,
256
284
token:: Gt => -1 ,
257
285
token:: BinOp ( token:: Shl ) => 2 ,
@@ -269,11 +297,11 @@ impl<'a> SpanUtils<'a> {
269
297
// path, trying to pull out the non-nested idents (e.g., avoiding 'a
270
298
// in `<A as B<'a>>::C`). So we end up with a span for `B>::C` from
271
299
// the start of the first ident to the end of the path.
272
- if !found_ufcs_sep && bracket_count == -1 {
300
+ if !found_ufcs_sep && angle_count == -1 {
273
301
found_ufcs_sep = true ;
274
- bracket_count += 1 ;
302
+ angle_count += 1 ;
275
303
}
276
- if ts. tok . is_ident ( ) && bracket_count == nesting {
304
+ if ts. tok . is_ident ( ) && angle_count == nesting {
277
305
result. push ( self . make_sub_span ( span, Some ( ts. sp ) ) . unwrap ( ) ) ;
278
306
}
279
307
}
0 commit comments