@@ -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