|
1 | 1 | use crate::errors; |
2 | 2 | use crate::fluent_generated as fluent; |
3 | | -use crate::maybe_whole; |
| 3 | +use crate::maybe_reparse_metavar_seq; |
4 | 4 |
|
5 | | -use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle}; |
| 5 | +use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, ParseNtResult, Parser, PathStyle}; |
6 | 6 | use rustc_ast as ast; |
7 | 7 | use rustc_ast::attr; |
8 | | -use rustc_ast::token::{self, Delimiter}; |
| 8 | +use rustc_ast::token::{self, Delimiter, NonterminalKind}; |
9 | 9 | use rustc_errors::{codes::*, Diag, PResult}; |
10 | 10 | use rustc_span::{sym, BytePos, Span}; |
11 | 11 | use thin_vec::ThinVec; |
@@ -249,7 +249,15 @@ impl<'a> Parser<'a> { |
249 | 249 | /// PATH `=` UNSUFFIXED_LIT |
250 | 250 | /// The delimiters or `=` are still put into the resulting token stream. |
251 | 251 | pub fn parse_attr_item(&mut self, capture_tokens: bool) -> PResult<'a, ast::AttrItem> { |
252 | | - maybe_whole!(self, NtMeta, |attr| attr.into_inner()); |
| 252 | + if let Some(item) = maybe_reparse_metavar_seq!( |
| 253 | + self, |
| 254 | + NonterminalKind::Meta, |
| 255 | + NonterminalKind::Meta, |
| 256 | + ParseNtResult::Meta(item), |
| 257 | + item |
| 258 | + ) { |
| 259 | + return Ok(item.into_inner()); |
| 260 | + } |
253 | 261 |
|
254 | 262 | let do_parse = |this: &mut Self| { |
255 | 263 | let path = this.parse_path(PathStyle::Mod)?; |
@@ -360,18 +368,22 @@ impl<'a> Parser<'a> { |
360 | 368 | /// MetaSeq = MetaItemInner (',' MetaItemInner)* ','? ; |
361 | 369 | /// ``` |
362 | 370 | pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> { |
363 | | - // We can't use `maybe_whole` here because it would bump in the `None` |
364 | | - // case, which we don't want. |
365 | | - if let token::Interpolated(nt) = &self.token.kind |
366 | | - && let token::NtMeta(attr_item) = &**nt |
367 | | - { |
368 | | - match attr_item.meta(attr_item.path.span) { |
| 371 | + // Clone the parser so we can backtrack in the case where `attr_item.meta()` fails. |
| 372 | + let mut parser = self.clone(); |
| 373 | + if let Some(attr_item) = maybe_reparse_metavar_seq!( |
| 374 | + parser, |
| 375 | + NonterminalKind::Meta, |
| 376 | + NonterminalKind::Meta, |
| 377 | + ParseNtResult::Meta(attr_item), |
| 378 | + attr_item |
| 379 | + ) { |
| 380 | + return match attr_item.meta(attr_item.path.span) { |
369 | 381 | Some(meta) => { |
370 | | - self.bump(); |
371 | | - return Ok(meta); |
| 382 | + *self = parser; |
| 383 | + Ok(meta) |
372 | 384 | } |
373 | | - None => self.unexpected()?, |
374 | | - } |
| 385 | + None => self.unexpected_any(), |
| 386 | + }; |
375 | 387 | } |
376 | 388 |
|
377 | 389 | let lo = self.token.span; |
@@ -410,7 +422,7 @@ impl<'a> Parser<'a> { |
410 | 422 |
|
411 | 423 | let mut err = errors::InvalidMetaItem { |
412 | 424 | span: self.token.span, |
413 | | - token: self.token.clone(), |
| 425 | + descr: super::token_descr(&self.token), |
414 | 426 | quote_ident_sugg: None, |
415 | 427 | }; |
416 | 428 |
|
|
0 commit comments