|
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