|
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