@@ -27,7 +27,7 @@ pub(super) struct TokenTreesReader<'a> {
27
27
}
28
28
29
29
impl < ' a > TokenTreesReader < ' a > {
30
- pub ( super ) fn parse_token_trees (
30
+ pub ( super ) fn parse_all_token_trees (
31
31
string_reader : StringReader < ' a > ,
32
32
) -> ( PResult < ' a , TokenStream > , Vec < UnmatchedBrace > ) {
33
33
let mut tt_reader = TokenTreesReader {
@@ -40,36 +40,51 @@ impl<'a> TokenTreesReader<'a> {
40
40
last_delim_empty_block_spans : FxHashMap :: default ( ) ,
41
41
matching_block_spans : Vec :: new ( ) ,
42
42
} ;
43
- let res = tt_reader. parse_all_token_trees ( ) ;
43
+ let res = tt_reader. parse_token_trees ( /* is_delimited */ false ) ;
44
44
( res, tt_reader. unmatched_braces )
45
45
}
46
46
47
- // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof` .
48
- fn parse_all_token_trees ( & mut self ) -> PResult < ' a , TokenStream > {
47
+ // Parse a stream of tokens into a list of `TokenTree`s.
48
+ fn parse_token_trees ( & mut self , is_delimited : bool ) -> PResult < ' a , TokenStream > {
49
49
self . token = self . string_reader . next_token ( ) . 0 ;
50
- let mut buf = TokenStreamBuilder :: default ( ) ;
50
+ let mut buf = Vec :: new ( ) ;
51
51
loop {
52
52
match self . token . kind {
53
53
token:: OpenDelim ( delim) => buf. push ( self . parse_token_tree_open_delim ( delim) ) ,
54
- token:: CloseDelim ( delim) => return Err ( self . close_delim_err ( delim) ) ,
55
- token:: Eof => return Ok ( buf. into_token_stream ( ) ) ,
56
- _ => buf. push ( self . parse_token_tree_non_delim_non_eof ( ) ) ,
57
- }
58
- }
59
- }
60
-
61
- // Parse a stream of tokens into a list of `TokenTree`s, up to a `CloseDelim`.
62
- fn parse_token_trees_until_close_delim ( & mut self ) -> TokenStream {
63
- let mut buf = TokenStreamBuilder :: default ( ) ;
64
- loop {
65
- match self . token . kind {
66
- token:: OpenDelim ( delim) => buf. push ( self . parse_token_tree_open_delim ( delim) ) ,
67
- token:: CloseDelim ( ..) => return buf. into_token_stream ( ) ,
54
+ token:: CloseDelim ( delim) => {
55
+ return if is_delimited {
56
+ Ok ( TokenStream :: new ( buf) )
57
+ } else {
58
+ Err ( self . close_delim_err ( delim) )
59
+ } ;
60
+ }
68
61
token:: Eof => {
69
- self . eof_err ( ) . emit ( ) ;
70
- return buf. into_token_stream ( ) ;
62
+ if is_delimited {
63
+ self . eof_err ( ) . emit ( ) ;
64
+ }
65
+ return Ok ( TokenStream :: new ( buf) ) ;
66
+ }
67
+ _ => {
68
+ // Get the next normal token. This might require getting multiple adjacent
69
+ // single-char tokens and joining them together.
70
+ let ( this_spacing, next_tok) = loop {
71
+ let ( next_tok, is_next_tok_preceded_by_whitespace) =
72
+ self . string_reader . next_token ( ) ;
73
+ if !is_next_tok_preceded_by_whitespace {
74
+ if let Some ( glued) = self . token . glue ( & next_tok) {
75
+ self . token = glued;
76
+ } else {
77
+ let this_spacing =
78
+ if next_tok. is_op ( ) { Spacing :: Joint } else { Spacing :: Alone } ;
79
+ break ( this_spacing, next_tok) ;
80
+ }
81
+ } else {
82
+ break ( Spacing :: Alone , next_tok) ;
83
+ }
84
+ } ;
85
+ let this_tok = std:: mem:: replace ( & mut self . token , next_tok) ;
86
+ buf. push ( TokenTree :: Token ( this_tok, this_spacing) ) ;
71
87
}
72
- _ => buf. push ( self . parse_token_tree_non_delim_non_eof ( ) ) ,
73
88
}
74
89
}
75
90
}
@@ -113,14 +128,12 @@ impl<'a> TokenTreesReader<'a> {
113
128
// The span for beginning of the delimited section
114
129
let pre_span = self . token . span ;
115
130
116
- // Move past the open delimiter.
117
131
self . open_braces . push ( ( open_delim, self . token . span ) ) ;
118
- self . token = self . string_reader . next_token ( ) . 0 ;
119
132
120
133
// Parse the token trees within the delimiters.
121
134
// We stop at any delimiter so we can try to recover if the user
122
135
// uses an incorrect delimiter.
123
- let tts = self . parse_token_trees_until_close_delim ( ) ;
136
+ let tts = self . parse_token_trees ( /* is_delimited */ true ) . unwrap ( ) ;
124
137
125
138
// Expand to cover the entire delimited token tree
126
139
let delim_span = DelimSpan :: from_pair ( pre_span, self . token . span ) ;
@@ -242,43 +255,4 @@ impl<'a> TokenTreesReader<'a> {
242
255
err. span_label ( self . token . span , "unexpected closing delimiter" ) ;
243
256
err
244
257
}
245
-
246
- #[ inline]
247
- fn parse_token_tree_non_delim_non_eof ( & mut self ) -> TokenTree {
248
- // `this_spacing` for the returned token refers to whether the token is
249
- // immediately followed by another op token. It is determined by the
250
- // next token: its kind and its `preceded_by_whitespace` status.
251
- let ( next_tok, is_next_tok_preceded_by_whitespace) = self . string_reader . next_token ( ) ;
252
- let this_spacing = if is_next_tok_preceded_by_whitespace || !next_tok. is_op ( ) {
253
- Spacing :: Alone
254
- } else {
255
- Spacing :: Joint
256
- } ;
257
- let this_tok = std:: mem:: replace ( & mut self . token , next_tok) ;
258
- TokenTree :: Token ( this_tok, this_spacing)
259
- }
260
- }
261
-
262
- #[ derive( Default ) ]
263
- struct TokenStreamBuilder {
264
- buf : Vec < TokenTree > ,
265
- }
266
-
267
- impl TokenStreamBuilder {
268
- #[ inline( always) ]
269
- fn push ( & mut self , tree : TokenTree ) {
270
- if let Some ( TokenTree :: Token ( prev_token, Spacing :: Joint ) ) = self . buf . last ( )
271
- && let TokenTree :: Token ( token, joint) = & tree
272
- && let Some ( glued) = prev_token. glue ( token)
273
- {
274
- self . buf . pop ( ) ;
275
- self . buf . push ( TokenTree :: Token ( glued, * joint) ) ;
276
- } else {
277
- self . buf . push ( tree)
278
- }
279
- }
280
-
281
- fn into_token_stream ( self ) -> TokenStream {
282
- TokenStream :: new ( self . buf )
283
- }
284
258
}
0 commit comments