1
Fork 0

Avoid snapshotting the parser in parse_path_inner.

This commit is contained in:
Nicholas Nethercote 2025-02-21 16:47:07 +11:00
parent 76b04437be
commit 0f490b040a
6 changed files with 24 additions and 24 deletions

View file

@ -84,7 +84,9 @@ pub enum MetaVarKind {
// This field is needed for `Token::can_begin_string_literal`. // This field is needed for `Token::can_begin_string_literal`.
can_begin_string_literal: bool, can_begin_string_literal: bool,
}, },
Ty, Ty {
is_path: bool,
},
Ident, Ident,
Lifetime, Lifetime,
Literal, Literal,
@ -104,7 +106,7 @@ impl fmt::Display for MetaVarKind {
MetaVarKind::Pat(PatParam { inferred: false }) => sym::pat_param, MetaVarKind::Pat(PatParam { inferred: false }) => sym::pat_param,
MetaVarKind::Expr { kind: Expr2021 { inferred: true } | Expr, .. } => sym::expr, MetaVarKind::Expr { kind: Expr2021 { inferred: true } | Expr, .. } => sym::expr,
MetaVarKind::Expr { kind: Expr2021 { inferred: false }, .. } => sym::expr_2021, MetaVarKind::Expr { kind: Expr2021 { inferred: false }, .. } => sym::expr_2021,
MetaVarKind::Ty => sym::ty, MetaVarKind::Ty { .. } => sym::ty,
MetaVarKind::Ident => sym::ident, MetaVarKind::Ident => sym::ident,
MetaVarKind::Lifetime => sym::lifetime, MetaVarKind::Lifetime => sym::lifetime,
MetaVarKind::Literal => sym::literal, MetaVarKind::Literal => sym::literal,
@ -666,7 +668,7 @@ impl Token {
MetaVarKind::Meta | MetaVarKind::Meta |
MetaVarKind::Pat(_) | MetaVarKind::Pat(_) |
MetaVarKind::Path | MetaVarKind::Path |
MetaVarKind::Ty MetaVarKind::Ty { .. }
))) => true, ))) => true,
_ => false, _ => false,
} }
@ -689,7 +691,7 @@ impl Token {
PathSep => true, // global path PathSep => true, // global path
Interpolated(ref nt) => matches!(&**nt, NtPath(..)), Interpolated(ref nt) => matches!(&**nt, NtPath(..)),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Ty | MetaVarKind::Ty { .. } |
MetaVarKind::Path MetaVarKind::Path
))) => true, ))) => true,
// For anonymous structs or unions, which only appear in specific positions // For anonymous structs or unions, which only appear in specific positions

View file

@ -1,13 +1,13 @@
use std::mem; use std::mem;
use std::sync::Arc; use std::sync::Arc;
use rustc_ast::ExprKind;
use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::token::{ use rustc_ast::token::{
self, Delimiter, IdentIsRaw, InvisibleOrigin, Lit, LitKind, MetaVarKind, Nonterminal, Token, self, Delimiter, IdentIsRaw, InvisibleOrigin, Lit, LitKind, MetaVarKind, Nonterminal, Token,
TokenKind, TokenKind,
}; };
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast::{ExprKind, TyKind};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize}; use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
use rustc_parse::lexer::nfc_normalize; use rustc_parse::lexer::nfc_normalize;
@ -323,7 +323,8 @@ pub(super) fn transcribe<'a>(
TokenTree::token_alone(kind, sp) TokenTree::token_alone(kind, sp)
} }
MatchedSingle(ParseNtResult::Ty(ty)) => { MatchedSingle(ParseNtResult::Ty(ty)) => {
mk_delimited(MetaVarKind::Ty, TokenStream::from_ast(ty)) let is_path = matches!(&ty.kind, TyKind::Path(None, _path));
mk_delimited(MetaVarKind::Ty { is_path }, TokenStream::from_ast(ty))
} }
MatchedSingle(ParseNtResult::Vis(vis)) => { MatchedSingle(ParseNtResult::Vis(vis)) => {
mk_delimited(MetaVarKind::Vis, TokenStream::from_ast(vis)) mk_delimited(MetaVarKind::Vis, TokenStream::from_ast(vis))

View file

@ -117,14 +117,13 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
($self: expr, $allow_qpath_recovery: expr) => { ($self: expr, $allow_qpath_recovery: expr) => {
if $allow_qpath_recovery if $allow_qpath_recovery
&& $self.may_recover() && $self.may_recover()
&& let Some(token::MetaVarKind::Ty) = $self.token.is_metavar_seq() && let Some(mv_kind) = $self.token.is_metavar_seq()
&& let token::MetaVarKind::Ty { .. } = mv_kind
&& $self.check_noexpect_past_close_delim(&token::PathSep) && $self.check_noexpect_past_close_delim(&token::PathSep)
{ {
// Reparse the type, then move to recovery. // Reparse the type, then move to recovery.
let ty = $self let ty = $self
.eat_metavar_seq(token::MetaVarKind::Ty, |this| { .eat_metavar_seq(mv_kind, |this| this.parse_ty_no_question_mark_recover())
this.parse_ty_no_question_mark_recover()
})
.expect("metavar seq ty"); .expect("metavar seq ty");
return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty); return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty);

View file

@ -30,7 +30,7 @@ impl<'a> Parser<'a> {
MetaVarKind::Stmt MetaVarKind::Stmt
| MetaVarKind::Pat(_) | MetaVarKind::Pat(_)
| MetaVarKind::Expr { .. } | MetaVarKind::Expr { .. }
| MetaVarKind::Ty | MetaVarKind::Ty { .. }
| MetaVarKind::Literal // `true`, `false` | MetaVarKind::Literal // `true`, `false`
| MetaVarKind::Meta | MetaVarKind::Meta
| MetaVarKind::Path => true, | MetaVarKind::Path => true,
@ -108,7 +108,7 @@ impl<'a> Parser<'a> {
| MetaVarKind::Literal => true, | MetaVarKind::Literal => true,
MetaVarKind::Item MetaVarKind::Item
| MetaVarKind::Pat(_) | MetaVarKind::Pat(_)
| MetaVarKind::Ty | MetaVarKind::Ty { .. }
| MetaVarKind::Meta | MetaVarKind::Meta
| MetaVarKind::Path | MetaVarKind::Path
| MetaVarKind::Vis => false, | MetaVarKind::Vis => false,

View file

@ -196,15 +196,12 @@ impl<'a> Parser<'a> {
maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner())); maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner()));
if let Some(MetaVarKind::Ty) = self.token.is_metavar_seq() { // If we have a `ty` metavar in the form of a path, reparse it directly as a path, instead
let mut snapshot = self.create_snapshot_for_diagnostic(); // of reparsing it as a `ty` and then extracting the path.
let ty = snapshot if let Some(path) = self.eat_metavar_seq(MetaVarKind::Ty { is_path: true }, |this| {
.eat_metavar_seq(MetaVarKind::Ty, |this| this.parse_ty_no_question_mark_recover()) this.parse_path(PathStyle::Type)
.expect("metavar seq ty"); }) {
if let ast::TyKind::Path(None, path) = ty.into_inner().kind { return Ok(reject_generics_if_mod_style(self, path));
self.restore_snapshot(snapshot);
return Ok(reject_generics_if_mod_style(self, path));
}
} }
let lo = self.token.span; let lo = self.token.span;

View file

@ -249,9 +249,10 @@ impl<'a> Parser<'a> {
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
if let Some(ty) = if let Some(ty) = self.eat_metavar_seq_with_matcher(
self.eat_metavar_seq(MetaVarKind::Ty, |this| this.parse_ty_no_question_mark_recover()) |mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }),
{ |this| this.parse_ty_no_question_mark_recover(),
) {
return Ok(ty); return Ok(ty);
} }