@@ -61,6 +61,11 @@ pub enum ForceCollect {
61
61
No ,
62
62
}
63
63
64
+ pub enum TrailingToken {
65
+ None ,
66
+ Semi ,
67
+ }
68
+
64
69
/// Like `maybe_whole_expr`, but for things other than expressions.
65
70
#[ macro_export]
66
71
macro_rules! maybe_whole {
@@ -1225,6 +1230,13 @@ impl<'a> Parser<'a> {
1225
1230
}
1226
1231
}
1227
1232
1233
+ pub fn collect_tokens < R : HasTokens > (
1234
+ & mut self ,
1235
+ f : impl FnOnce ( & mut Self ) -> PResult < ' a , R > ,
1236
+ ) -> PResult < ' a , R > {
1237
+ self . collect_tokens_trailing_token ( |this| Ok ( ( f ( this) ?, TrailingToken :: None ) ) )
1238
+ }
1239
+
1228
1240
/// Records all tokens consumed by the provided callback,
1229
1241
/// including the current token. These tokens are collected
1230
1242
/// into a `LazyTokenStream`, and returned along with the result
@@ -1241,9 +1253,9 @@ impl<'a> Parser<'a> {
1241
1253
/// This restriction shouldn't be an issue in practice,
1242
1254
/// since this function is used to record the tokens for
1243
1255
/// a parsed AST item, which always has matching delimiters.
1244
- pub fn collect_tokens < R : HasTokens > (
1256
+ pub fn collect_tokens_trailing_token < R : HasTokens > (
1245
1257
& mut self ,
1246
- f : impl FnOnce ( & mut Self ) -> PResult < ' a , R > ,
1258
+ f : impl FnOnce ( & mut Self ) -> PResult < ' a , ( R , TrailingToken ) > ,
1247
1259
) -> PResult < ' a , R > {
1248
1260
let start_token = ( self . token . clone ( ) , self . token_spacing ) ;
1249
1261
let cursor_snapshot = TokenCursor {
@@ -1256,7 +1268,7 @@ impl<'a> Parser<'a> {
1256
1268
append_unglued_token : self . token_cursor . append_unglued_token . clone ( ) ,
1257
1269
} ;
1258
1270
1259
- let mut ret = f ( self ) ?;
1271
+ let ( mut ret, trailing_token ) = f ( self ) ?;
1260
1272
1261
1273
// Produces a `TokenStream` on-demand. Using `cursor_snapshot`
1262
1274
// and `num_calls`, we can reconstruct the `TokenStream` seen
@@ -1275,55 +1287,44 @@ impl<'a> Parser<'a> {
1275
1287
cursor_snapshot : TokenCursor ,
1276
1288
num_calls : usize ,
1277
1289
desugar_doc_comments : bool ,
1278
- trailing_semi : bool ,
1279
1290
append_unglued_token : Option < TreeAndSpacing > ,
1280
1291
}
1281
1292
impl CreateTokenStream for LazyTokenStreamImpl {
1282
1293
fn create_token_stream ( & self ) -> TokenStream {
1283
- let mut num_calls = self . num_calls ;
1284
- if self . trailing_semi {
1285
- num_calls += 1 ;
1286
- }
1287
1294
// The token produced by the final call to `next` or `next_desugared`
1288
1295
// was not actually consumed by the callback. The combination
1289
1296
// of chaining the initial token and using `take` produces the desired
1290
1297
// result - we produce an empty `TokenStream` if no calls were made,
1291
1298
// and omit the final token otherwise.
1292
1299
let mut cursor_snapshot = self . cursor_snapshot . clone ( ) ;
1293
1300
let tokens = std:: iter:: once ( self . start_token . clone ( ) )
1294
- . chain ( ( 0 ..num_calls) . map ( |_| {
1301
+ . chain ( ( 0 ..self . num_calls ) . map ( |_| {
1295
1302
if self . desugar_doc_comments {
1296
1303
cursor_snapshot. next_desugared ( )
1297
1304
} else {
1298
1305
cursor_snapshot. next ( )
1299
1306
}
1300
1307
} ) )
1301
- . take ( num_calls) ;
1308
+ . take ( self . num_calls ) ;
1302
1309
1303
1310
make_token_stream ( tokens, self . append_unglued_token . clone ( ) )
1304
1311
}
1305
- fn add_trailing_semi ( & self ) -> Box < dyn CreateTokenStream > {
1306
- if self . trailing_semi {
1307
- panic ! ( "Called `add_trailing_semi` twice!" ) ;
1308
- }
1309
- if self . append_unglued_token . is_some ( ) {
1310
- panic ! (
1311
- "Cannot call `add_trailing_semi` when we have an unglued token {:?}" ,
1312
- self . append_unglued_token
1313
- ) ;
1314
- }
1315
- let mut new = self . clone ( ) ;
1316
- new. trailing_semi = true ;
1317
- Box :: new ( new)
1312
+ }
1313
+
1314
+ let mut num_calls = self . token_cursor . num_next_calls - cursor_snapshot. num_next_calls ;
1315
+ match trailing_token {
1316
+ TrailingToken :: None => { }
1317
+ TrailingToken :: Semi => {
1318
+ assert_eq ! ( self . token. kind, token:: Semi ) ;
1319
+ num_calls += 1 ;
1318
1320
}
1319
1321
}
1320
1322
1321
1323
let lazy_impl = LazyTokenStreamImpl {
1322
1324
start_token,
1323
- num_calls : self . token_cursor . num_next_calls - cursor_snapshot . num_next_calls ,
1325
+ num_calls,
1324
1326
cursor_snapshot,
1325
1327
desugar_doc_comments : self . desugar_doc_comments ,
1326
- trailing_semi : false ,
1327
1328
append_unglued_token : self . token_cursor . append_unglued_token . clone ( ) ,
1328
1329
} ;
1329
1330
ret. finalize_tokens ( LazyTokenStream :: new ( lazy_impl) ) ;
@@ -1427,9 +1428,9 @@ macro_rules! maybe_collect_tokens {
1427
1428
if matches!( $force_collect, ForceCollect :: Yes )
1428
1429
|| $crate:: parser:: attr:: maybe_needs_tokens( $attrs)
1429
1430
{
1430
- $self. collect_tokens ( $f)
1431
+ $self. collect_tokens_trailing_token ( $f)
1431
1432
} else {
1432
- $f( $self)
1433
+ Ok ( $f( $self) ? . 0 )
1433
1434
}
1434
1435
} ;
1435
1436
}
0 commit comments