@@ -44,9 +44,9 @@ use std::{cmp, fmt, iter, mem};
44
44
pub enum TokenTree {
45
45
/// A single token. Should never be `OpenDelim` or `CloseDelim`, because
46
46
/// delimiters are implicitly represented by `Delimited`.
47
- Token ( Token , Spacing ) ,
47
+ Token ( Token , Spacing , Span ) ,
48
48
/// A delimited sequence of token trees.
49
- Delimited ( DelimSpan , Delimiter , TokenStream ) ,
49
+ Delimited ( DelimSpan , Delimiter , TokenStream , Span ) ,
50
50
}
51
51
52
52
// Ensure all fields of `TokenTree` are `DynSend` and `DynSync`.
@@ -65,8 +65,10 @@ impl TokenTree {
65
65
/// Checks if this `TokenTree` is equal to the other, regardless of span information.
66
66
pub fn eq_unspanned ( & self , other : & TokenTree ) -> bool {
67
67
match ( self , other) {
68
- ( TokenTree :: Token ( token, _) , TokenTree :: Token ( token2, _) ) => token. kind == token2. kind ,
69
- ( TokenTree :: Delimited ( _, delim, tts) , TokenTree :: Delimited ( _, delim2, tts2) ) => {
68
+ ( TokenTree :: Token ( token, _, _) , TokenTree :: Token ( token2, _, _) ) => {
69
+ token. kind == token2. kind
70
+ }
71
+ ( TokenTree :: Delimited ( _, delim, tts, _) , TokenTree :: Delimited ( _, delim2, tts2, _) ) => {
70
72
delim == delim2 && tts. eq_unspanned ( tts2)
71
73
}
72
74
_ => false ,
@@ -76,33 +78,33 @@ impl TokenTree {
76
78
/// Retrieves the `TokenTree`'s span.
77
79
pub fn span ( & self ) -> Span {
78
80
match self {
79
- TokenTree :: Token ( token, _) => token. span ,
81
+ TokenTree :: Token ( token, _, _ ) => token. span ,
80
82
TokenTree :: Delimited ( sp, ..) => sp. entire ( ) ,
81
83
}
82
84
}
83
85
84
86
/// Modify the `TokenTree`'s span in-place.
85
87
pub fn set_span ( & mut self , span : Span ) {
86
88
match self {
87
- TokenTree :: Token ( token, _) => token. span = span,
89
+ TokenTree :: Token ( token, _, _ ) => token. span = span,
88
90
TokenTree :: Delimited ( dspan, ..) => * dspan = DelimSpan :: from_single ( span) ,
89
91
}
90
92
}
91
93
92
94
/// Create a `TokenTree::Token` with alone spacing.
93
95
pub fn token_alone ( kind : TokenKind , span : Span ) -> TokenTree {
94
- TokenTree :: Token ( Token :: new ( kind, span) , Spacing :: Alone )
96
+ TokenTree :: Token ( Token :: new ( kind, span) , Spacing :: Alone , span )
95
97
}
96
98
97
99
/// Create a `TokenTree::Token` with joint spacing.
98
100
pub fn token_joint ( kind : TokenKind , span : Span ) -> TokenTree {
99
- TokenTree :: Token ( Token :: new ( kind, span) , Spacing :: Joint )
101
+ TokenTree :: Token ( Token :: new ( kind, span) , Spacing :: Joint , span )
100
102
}
101
103
102
104
pub fn uninterpolate ( & self ) -> Cow < ' _ , TokenTree > {
103
105
match self {
104
- TokenTree :: Token ( token, spacing) => match token. uninterpolate ( ) {
105
- Cow :: Owned ( token) => Cow :: Owned ( TokenTree :: Token ( token, * spacing) ) ,
106
+ TokenTree :: Token ( token, spacing, span ) => match token. uninterpolate ( ) {
107
+ Cow :: Owned ( token) => Cow :: Owned ( TokenTree :: Token ( token, * spacing, * span ) ) ,
106
108
Cow :: Borrowed ( _) => Cow :: Borrowed ( self ) ,
107
109
} ,
108
110
_ => Cow :: Borrowed ( self ) ,
@@ -206,12 +208,15 @@ impl AttrTokenStream {
206
208
. iter ( )
207
209
. flat_map ( |tree| match & tree {
208
210
AttrTokenTree :: Token ( inner, spacing) => {
209
- smallvec ! [ TokenTree :: Token ( inner. clone( ) , * spacing) ] . into_iter ( )
210
- }
211
- AttrTokenTree :: Delimited ( span, delim, stream) => {
212
- smallvec ! [ TokenTree :: Delimited ( * span, * delim, stream. to_tokenstream( ) ) , ]
213
- . into_iter ( )
211
+ smallvec ! [ TokenTree :: Token ( inner. clone( ) , * spacing, inner. span) ] . into_iter ( )
214
212
}
213
+ AttrTokenTree :: Delimited ( span, delim, stream) => smallvec ! [ TokenTree :: Delimited (
214
+ * span,
215
+ * delim,
216
+ stream. to_tokenstream( ) ,
217
+ span. entire( )
218
+ ) , ]
219
+ . into_iter ( ) ,
215
220
AttrTokenTree :: Attributes ( data) => {
216
221
let idx = data
217
222
. attrs
@@ -230,7 +235,7 @@ impl AttrTokenStream {
230
235
let mut found = false ;
231
236
// Check the last two trees (to account for a trailing semi)
232
237
for tree in target_tokens. iter_mut ( ) . rev ( ) . take ( 2 ) {
233
- if let TokenTree :: Delimited ( span, delim, delim_tokens) = tree {
238
+ if let TokenTree :: Delimited ( span, delim, delim_tokens, _ ) = tree {
234
239
// Inner attributes are only supported on extern blocks, functions,
235
240
// impls, and modules. All of these have their inner attributes
236
241
// placed at the beginning of the rightmost outermost braced group:
@@ -250,7 +255,7 @@ impl AttrTokenStream {
250
255
stream. push_stream ( inner_attr. tokens ( ) ) ;
251
256
}
252
257
stream. push_stream ( delim_tokens. clone ( ) ) ;
253
- * tree = TokenTree :: Delimited ( * span, * delim, stream) ;
258
+ * tree = TokenTree :: Delimited ( * span, * delim, stream, span . entire ( ) ) ;
254
259
found = true ;
255
260
break ;
256
261
}
@@ -330,10 +335,10 @@ impl TokenStream {
330
335
while let Some ( ( pos, ts) ) = iter. next ( ) {
331
336
if let Some ( ( _, next) ) = iter. peek ( ) {
332
337
let sp = match ( & ts, & next) {
333
- ( _, TokenTree :: Token ( Token { kind : token:: Comma , .. } , _) ) => continue ,
338
+ ( _, TokenTree :: Token ( Token { kind : token:: Comma , .. } , _, _ ) ) => continue ,
334
339
(
335
- TokenTree :: Token ( token_left, Spacing :: Alone ) ,
336
- TokenTree :: Token ( token_right, _) ,
340
+ TokenTree :: Token ( token_left, Spacing :: Alone , _ ) ,
341
+ TokenTree :: Token ( token_right, _, _ ) ,
337
342
) if ( ( token_left. is_ident ( ) && !token_left. is_reserved_ident ( ) )
338
343
|| token_left. is_lit ( ) )
339
344
&& ( ( token_right. is_ident ( ) && !token_right. is_reserved_ident ( ) )
@@ -433,7 +438,7 @@ impl TokenStream {
433
438
434
439
/// Create a token stream containing a single `Delimited`.
435
440
pub fn delimited ( span : DelimSpan , delim : Delimiter , tts : TokenStream ) -> TokenStream {
436
- TokenStream :: new ( vec ! [ TokenTree :: Delimited ( span, delim, tts) ] )
441
+ TokenStream :: new ( vec ! [ TokenTree :: Delimited ( span, delim, tts, span . entire ( ) ) ] )
437
442
}
438
443
439
444
pub fn from_ast ( node : & ( impl HasAttrs + HasSpan + HasTokens + fmt:: Debug ) ) -> TokenStream {
@@ -475,25 +480,32 @@ impl TokenStream {
475
480
}
476
481
}
477
482
478
- fn flatten_token ( token : & Token , spacing : Spacing ) -> TokenTree {
483
+ fn flatten_token ( token : & Token , spacing : Spacing , span : Span ) -> TokenTree {
479
484
match & token. kind {
480
485
token:: Interpolated ( nt) if let token:: NtIdent ( ident, is_raw) = nt. 0 => {
481
- TokenTree :: Token ( Token :: new ( token:: Ident ( ident. name , is_raw) , ident. span ) , spacing)
486
+ TokenTree :: Token (
487
+ Token :: new ( token:: Ident ( ident. name , is_raw) , ident. span ) ,
488
+ spacing,
489
+ token. span ,
490
+ )
482
491
}
483
492
token:: Interpolated ( nt) => TokenTree :: Delimited (
484
493
DelimSpan :: from_single ( token. span ) ,
485
494
Delimiter :: Invisible ,
486
495
TokenStream :: from_nonterminal_ast ( & nt. 0 ) . flattened ( ) ,
496
+ token. span ,
487
497
) ,
488
- _ => TokenTree :: Token ( token. clone ( ) , spacing) ,
498
+ _ => TokenTree :: Token ( token. clone ( ) , spacing, span ) ,
489
499
}
490
500
}
491
501
492
502
fn flatten_token_tree ( tree : & TokenTree ) -> TokenTree {
493
503
match tree {
494
- TokenTree :: Token ( token, spacing) => TokenStream :: flatten_token ( token, * spacing) ,
495
- TokenTree :: Delimited ( span, delim, tts) => {
496
- TokenTree :: Delimited ( * span, * delim, tts. flattened ( ) )
504
+ TokenTree :: Token ( token, spacing, span) => {
505
+ TokenStream :: flatten_token ( token, * spacing, * span)
506
+ }
507
+ TokenTree :: Delimited ( span, delim, tts, span2) => {
508
+ TokenTree :: Delimited ( * span, * delim, tts. flattened ( ) , * span2)
497
509
}
498
510
}
499
511
}
@@ -502,8 +514,8 @@ impl TokenStream {
502
514
pub fn flattened ( & self ) -> TokenStream {
503
515
fn can_skip ( stream : & TokenStream ) -> bool {
504
516
stream. trees ( ) . all ( |tree| match tree {
505
- TokenTree :: Token ( token, _) => !matches ! ( token. kind, token:: Interpolated ( _) ) ,
506
- TokenTree :: Delimited ( _, _, inner) => can_skip ( inner) ,
517
+ TokenTree :: Token ( token, _, _ ) => !matches ! ( token. kind, token:: Interpolated ( _) ) ,
518
+ TokenTree :: Delimited ( _, _, inner, _ ) => can_skip ( inner) ,
507
519
} )
508
520
}
509
521
@@ -517,13 +529,13 @@ impl TokenStream {
517
529
// If `vec` is not empty, try to glue `tt` onto its last token. The return
518
530
// value indicates if gluing took place.
519
531
fn try_glue_to_last ( vec : & mut Vec < TokenTree > , tt : & TokenTree ) -> bool {
520
- if let Some ( TokenTree :: Token ( last_tok, Spacing :: Joint ) ) = vec. last ( )
521
- && let TokenTree :: Token ( tok, spacing) = tt
532
+ if let Some ( TokenTree :: Token ( last_tok, Spacing :: Joint , _ ) ) = vec. last ( )
533
+ && let TokenTree :: Token ( tok, spacing, span ) = tt
522
534
&& let Some ( glued_tok) = last_tok. glue ( tok)
523
535
{
524
536
// ...then overwrite the last token tree in `vec` with the
525
537
// glued token, and skip the first token tree from `stream`.
526
- * vec. last_mut ( ) . unwrap ( ) = TokenTree :: Token ( glued_tok, * spacing) ;
538
+ * vec. last_mut ( ) . unwrap ( ) = TokenTree :: Token ( glued_tok, * spacing, * span ) ;
527
539
true
528
540
} else {
529
541
false
@@ -582,6 +594,7 @@ impl TokenStream {
582
594
& TokenTree :: Token (
583
595
Token { kind : token:: DocComment ( _, attr_style, data) , span } ,
584
596
_spacing,
597
+ _,
585
598
) => {
586
599
let desugared = desugared_tts ( attr_style, data, span) ;
587
600
let desugared_len = desugared. len ( ) ;
@@ -592,9 +605,14 @@ impl TokenStream {
592
605
593
606
& TokenTree :: Token ( ..) => i += 1 ,
594
607
595
- & TokenTree :: Delimited ( sp, delim, ref delim_stream) => {
608
+ & TokenTree :: Delimited ( sp, delim, ref delim_stream, _ ) => {
596
609
if let Some ( desugared_delim_stream) = desugar_inner ( delim_stream. clone ( ) ) {
597
- let new_tt = TokenTree :: Delimited ( sp, delim, desugared_delim_stream) ;
610
+ let new_tt = TokenTree :: Delimited (
611
+ sp,
612
+ delim,
613
+ desugared_delim_stream,
614
+ sp. entire ( ) ,
615
+ ) ;
598
616
Lrc :: make_mut ( & mut stream. 0 ) [ i] = new_tt;
599
617
modified = true ;
600
618
}
@@ -637,6 +655,7 @@ impl TokenStream {
637
655
]
638
656
. into_iter ( )
639
657
. collect :: < TokenStream > ( ) ,
658
+ delim_span. entire ( ) ,
640
659
) ;
641
660
642
661
if attr_style == AttrStyle :: Inner {
@@ -748,6 +767,6 @@ mod size_asserts {
748
767
static_assert_size ! ( AttrTokenTree , 32 ) ;
749
768
static_assert_size ! ( LazyAttrTokenStream , 8 ) ;
750
769
static_assert_size ! ( TokenStream , 8 ) ;
751
- static_assert_size ! ( TokenTree , 32 ) ;
770
+ static_assert_size ! ( TokenTree , 40 ) ;
752
771
// tidy-alphabetical-end
753
772
}
0 commit comments