@@ -177,25 +177,44 @@ impl<'a> SpanUtils<'a> {
177177 }
178178
179179 // 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.
181181 pub fn sub_span_for_type_name ( & self , span : Span ) -> Option < Span > {
182182 let mut toks = self . retokenise_span ( span) ;
183183 let mut prev = toks. real_token ( ) ;
184184 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 ;
185194 let mut bracket_count = 0 ;
186195 loop {
187196 let next = toks. real_token ( ) ;
188197
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 &&
190201 prev. tok . is_ident ( ) {
191202 result = Some ( prev. sp ) ;
192203 }
193204
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+
194215 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 ,
199218 _ => 0 ,
200219 } ;
201220
@@ -204,7 +223,7 @@ impl<'a> SpanUtils<'a> {
204223 }
205224 prev = next;
206225 }
207- if bracket_count != 0 {
226+ if angle_count != 0 || bracket_count != 0 {
208227 let loc = self . sess . codemap ( ) . lookup_char_pos ( span. lo ) ;
209228 span_bug ! ( span,
210229 "Mis-counted brackets when breaking path? Parsing '{}' \
@@ -213,7 +232,7 @@ impl<'a> SpanUtils<'a> {
213232 loc. file. name,
214233 loc. line) ;
215234 }
216- if result. is_none ( ) && prev. tok . is_ident ( ) && bracket_count == 0 {
235+ if result. is_none ( ) && prev. tok . is_ident ( ) && angle_count == 0 {
217236 return self . make_sub_span ( span, Some ( prev. sp ) ) ;
218237 }
219238 self . make_sub_span ( span, result)
@@ -222,19 +241,20 @@ impl<'a> SpanUtils<'a> {
222241 // Reparse span and return an owned vector of sub spans of the first limit
223242 // identifier tokens in the given nesting level.
224243 // 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]
227246 pub fn spans_with_brackets ( & self , span : Span , nesting : isize , limit : isize ) -> Vec < Span > {
228247 let mut result: Vec < Span > = vec ! [ ] ;
229248
230249 let mut toks = self . retokenise_span ( span) ;
231250 // We keep track of how many brackets we're nested in
251+ let mut angle_count: isize = 0 ;
232252 let mut bracket_count: isize = 0 ;
233253 let mut found_ufcs_sep = false ;
234254 loop {
235255 let ts = toks. real_token ( ) ;
236256 if ts. tok == token:: Eof {
237- if bracket_count != 0 {
257+ if angle_count != 0 || bracket_count != 0 {
238258 if generated_code ( span) {
239259 return vec ! [ ] ;
240260 }
@@ -252,6 +272,14 @@ impl<'a> SpanUtils<'a> {
252272 return result;
253273 }
254274 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 {
255283 token:: Lt => 1 ,
256284 token:: Gt => -1 ,
257285 token:: BinOp ( token:: Shl ) => 2 ,
@@ -269,11 +297,11 @@ impl<'a> SpanUtils<'a> {
269297 // path, trying to pull out the non-nested idents (e.g., avoiding 'a
270298 // in `<A as B<'a>>::C`). So we end up with a span for `B>::C` from
271299 // 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 {
273301 found_ufcs_sep = true ;
274- bracket_count += 1 ;
302+ angle_count += 1 ;
275303 }
276- if ts. tok . is_ident ( ) && bracket_count == nesting {
304+ if ts. tok . is_ident ( ) && angle_count == nesting {
277305 result. push ( self . make_sub_span ( span, Some ( ts. sp ) ) . unwrap ( ) ) ;
278306 }
279307 }
0 commit comments