Remove NtTy.

Notes about tests:

- tests/ui/parser/macro/trait-object-macro-matcher.rs: the syntax error
  is duplicated, because it occurs now when parsing the decl macro
  input, and also when parsing the expanded decl macro. But this won't
  show up for normal users due to error de-duplication.

- tests/ui/associated-consts/issue-93835.rs: similar, plus there are
  some additional errors about this very broken code.

- The changes to metavariable descriptions in #132629 are now visible in
  error message for several tests.
This commit is contained in:
Nicholas Nethercote 2024-04-17 13:17:44 +10:00
parent c7981d6411
commit 76b04437be
19 changed files with 112 additions and 51 deletions

View file

@ -117,12 +117,16 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
($self: expr, $allow_qpath_recovery: expr) => {
if $allow_qpath_recovery
&& $self.may_recover()
&& $self.look_ahead(1, |t| t == &token::PathSep)
&& let token::Interpolated(nt) = &$self.token.kind
&& let token::NtTy(ty) = &**nt
&& let Some(token::MetaVarKind::Ty) = $self.token.is_metavar_seq()
&& $self.check_noexpect_past_close_delim(&token::PathSep)
{
let ty = ty.clone();
$self.bump();
// Reparse the type, then move to recovery.
let ty = $self
.eat_metavar_seq(token::MetaVarKind::Ty, |this| {
this.parse_ty_no_question_mark_recover()
})
.expect("metavar seq ty");
return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty);
}
};
@ -614,6 +618,24 @@ impl<'a> Parser<'a> {
self.token == *tok
}
// Check the first token after the delimiter that closes the current
// delimited sequence. (Panics if used in the outermost token stream, which
// has no delimiters.) It uses a clone of the relevant tree cursor to skip
// past the entire `TokenTree::Delimited` in a single step, avoiding the
// need for unbounded token lookahead.
//
// Primarily used when `self.token` matches
// `OpenDelim(Delimiter::Invisible(_))`, to look ahead through the current
// metavar expansion.
fn check_noexpect_past_close_delim(&self, tok: &TokenKind) -> bool {
let mut tree_cursor = self.token_cursor.stack.last().unwrap().clone();
tree_cursor.bump();
matches!(
tree_cursor.curr(),
Some(TokenTree::Token(token::Token { kind, .. }, _)) if kind == tok
)
}
/// Consumes a token 'tok' if it exists. Returns whether the given token was present.
///
/// the main purpose of this function is to reduce the cluttering of the suggestions list
@ -1724,6 +1746,7 @@ pub enum ParseNtResult {
Tt(TokenTree),
Ident(Ident, IdentIsRaw),
Lifetime(Ident, IdentIsRaw),
Ty(P<ast::Ty>),
Vis(P<ast::Visibility>),
/// This variant will eventually be removed, along with `Token::Interpolate`.

View file

@ -51,7 +51,6 @@ impl<'a> Parser<'a> {
NtStmt(_)
| NtPat(_)
| NtExpr(_)
| NtTy(_)
| NtLiteral(_) // `true`, `false`
| NtMeta(_)
| NtPath(_) => true,
@ -100,7 +99,7 @@ impl<'a> Parser<'a> {
token::NtLifetime(..) => true,
token::Interpolated(nt) => match &**nt {
NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true,
NtItem(_) | NtPat(_) | NtTy(_) | NtMeta(_) | NtPath(_) => false,
NtItem(_) | NtPat(_) | NtMeta(_) | NtPath(_) => false,
},
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k {
MetaVarKind::Block
@ -187,7 +186,9 @@ impl<'a> Parser<'a> {
NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?)
}
NonterminalKind::Ty => {
NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?)
return Ok(ParseNtResult::Ty(
self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?,
));
}
// this could be handled like a token, since it is one
NonterminalKind::Ident => {

View file

@ -2,7 +2,7 @@ use std::mem;
use ast::token::IdentIsRaw;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
use rustc_ast::token::{self, Delimiter, MetaVarKind, Token, TokenKind};
use rustc_ast::{
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint,
AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
@ -196,13 +196,14 @@ impl<'a> Parser<'a> {
maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner()));
if let token::Interpolated(nt) = &self.token.kind {
if let token::NtTy(ty) = &**nt {
if let ast::TyKind::Path(None, path) = &ty.kind {
let path = path.clone();
self.bump();
return Ok(reject_generics_if_mod_style(self, path));
}
if let Some(MetaVarKind::Ty) = self.token.is_metavar_seq() {
let mut snapshot = self.create_snapshot_for_diagnostic();
let ty = snapshot
.eat_metavar_seq(MetaVarKind::Ty, |this| this.parse_ty_no_question_mark_recover())
.expect("metavar seq ty");
if let ast::TyKind::Path(None, path) = ty.into_inner().kind {
self.restore_snapshot(snapshot);
return Ok(reject_generics_if_mod_style(self, path));
}
}

View file

@ -1,5 +1,5 @@
use rustc_ast::ptr::P;
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind};
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token, TokenKind};
use rustc_ast::util::case::Case;
use rustc_ast::{
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
@ -18,7 +18,7 @@ use crate::errors::{
HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
NestedCVariadicType, ReturnTypesUseThinArrow,
};
use crate::{exp, maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use crate::{exp, maybe_recover_from_interpolated_ty_qpath};
/// Signals whether parsing a type should allow `+`.
///
@ -183,7 +183,8 @@ impl<'a> Parser<'a> {
)
}
/// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>`
/// Parse a type without recovering `:` as `->` to avoid breaking code such
/// as `where fn() : for<'a>`.
pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
self.parse_ty_common(
AllowPlus::Yes,
@ -247,7 +248,12 @@ impl<'a> Parser<'a> {
) -> PResult<'a, P<Ty>> {
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
maybe_whole!(self, NtTy, |ty| ty);
if let Some(ty) =
self.eat_metavar_seq(MetaVarKind::Ty, |this| this.parse_ty_no_question_mark_recover())
{
return Ok(ty);
}
let lo = self.token.span;
let mut impl_dyn_multi = false;