|
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, symbol::kw, 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 is_unsafe = this.eat_keyword(kw::Unsafe); |
@@ -374,18 +382,22 @@ impl<'a> Parser<'a> { |
374 | 382 | /// MetaSeq = MetaItemInner (',' MetaItemInner)* ','? ; |
375 | 383 | /// ``` |
376 | 384 | pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> { |
377 | | - // We can't use `maybe_whole` here because it would bump in the `None` |
378 | | - // case, which we don't want. |
379 | | - if let token::Interpolated(nt) = &self.token.kind |
380 | | - && let token::NtMeta(attr_item) = &**nt |
381 | | - { |
382 | | - match attr_item.meta(attr_item.path.span) { |
| 385 | + // Clone the parser so we can backtrack in the case where `attr_item.meta()` fails. |
| 386 | + let mut parser = self.clone(); |
| 387 | + if let Some(attr_item) = maybe_reparse_metavar_seq!( |
| 388 | + parser, |
| 389 | + NonterminalKind::Meta, |
| 390 | + NonterminalKind::Meta, |
| 391 | + ParseNtResult::Meta(attr_item), |
| 392 | + attr_item |
| 393 | + ) { |
| 394 | + return match attr_item.meta(attr_item.path.span) { |
383 | 395 | Some(meta) => { |
384 | | - self.bump(); |
385 | | - return Ok(meta); |
| 396 | + *self = parser; |
| 397 | + Ok(meta) |
386 | 398 | } |
387 | | - None => self.unexpected()?, |
388 | | - } |
| 399 | + None => self.unexpected_any(), |
| 400 | + }; |
389 | 401 | } |
390 | 402 |
|
391 | 403 | let lo = self.token.span; |
@@ -439,7 +451,7 @@ impl<'a> Parser<'a> { |
439 | 451 |
|
440 | 452 | let mut err = errors::InvalidMetaItem { |
441 | 453 | span: self.token.span, |
442 | | - token: self.token.clone(), |
| 454 | + descr: super::token_descr(&self.token), |
443 | 455 | quote_ident_sugg: None, |
444 | 456 | }; |
445 | 457 |
|
|
0 commit comments