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:
parent
c7981d6411
commit
76b04437be
19 changed files with 112 additions and 51 deletions
|
@ -203,7 +203,6 @@ impl HasTokens for Nonterminal {
|
|||
Nonterminal::NtStmt(stmt) => stmt.tokens(),
|
||||
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
|
||||
Nonterminal::NtPat(pat) => pat.tokens(),
|
||||
Nonterminal::NtTy(ty) => ty.tokens(),
|
||||
Nonterminal::NtMeta(attr_item) => attr_item.tokens(),
|
||||
Nonterminal::NtPath(path) => path.tokens(),
|
||||
Nonterminal::NtBlock(block) => block.tokens(),
|
||||
|
@ -215,7 +214,6 @@ impl HasTokens for Nonterminal {
|
|||
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
|
||||
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
|
||||
Nonterminal::NtPat(pat) => pat.tokens_mut(),
|
||||
Nonterminal::NtTy(ty) => ty.tokens_mut(),
|
||||
Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(),
|
||||
Nonterminal::NtPath(path) => path.tokens_mut(),
|
||||
Nonterminal::NtBlock(block) => block.tokens_mut(),
|
||||
|
|
|
@ -907,7 +907,6 @@ fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
|
|||
}),
|
||||
token::NtPat(pat) => vis.visit_pat(pat),
|
||||
token::NtExpr(expr) => vis.visit_expr(expr),
|
||||
token::NtTy(ty) => vis.visit_ty(ty),
|
||||
token::NtLiteral(expr) => vis.visit_expr(expr),
|
||||
token::NtMeta(item) => {
|
||||
let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut();
|
||||
|
|
|
@ -659,7 +659,6 @@ impl Token {
|
|||
| NtMeta(..)
|
||||
| NtPat(..)
|
||||
| NtPath(..)
|
||||
| NtTy(..)
|
||||
),
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
|
||||
MetaVarKind::Expr { .. } |
|
||||
|
@ -688,7 +687,7 @@ impl Token {
|
|||
Lifetime(..) | // lifetime bound in trait object
|
||||
Lt | BinOp(Shl) | // associated path
|
||||
PathSep => true, // global path
|
||||
Interpolated(ref nt) => matches!(&**nt, NtTy(..) | NtPath(..)),
|
||||
Interpolated(ref nt) => matches!(&**nt, NtPath(..)),
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
|
||||
MetaVarKind::Ty |
|
||||
MetaVarKind::Path
|
||||
|
@ -1076,7 +1075,6 @@ pub enum Nonterminal {
|
|||
NtStmt(P<ast::Stmt>),
|
||||
NtPat(P<ast::Pat>),
|
||||
NtExpr(P<ast::Expr>),
|
||||
NtTy(P<ast::Ty>),
|
||||
NtLiteral(P<ast::Expr>),
|
||||
/// Stuff inside brackets for attributes
|
||||
NtMeta(P<ast::AttrItem>),
|
||||
|
@ -1174,7 +1172,6 @@ impl Nonterminal {
|
|||
NtStmt(stmt) => stmt.span,
|
||||
NtPat(pat) => pat.span,
|
||||
NtExpr(expr) | NtLiteral(expr) => expr.span,
|
||||
NtTy(ty) => ty.span,
|
||||
NtMeta(attr_item) => attr_item.span(),
|
||||
NtPath(path) => path.span,
|
||||
}
|
||||
|
@ -1188,7 +1185,6 @@ impl Nonterminal {
|
|||
NtPat(..) => "pattern",
|
||||
NtExpr(..) => "expression",
|
||||
NtLiteral(..) => "literal",
|
||||
NtTy(..) => "type",
|
||||
NtMeta(..) => "attribute",
|
||||
NtPath(..) => "path",
|
||||
}
|
||||
|
@ -1213,7 +1209,6 @@ impl fmt::Debug for Nonterminal {
|
|||
NtStmt(..) => f.pad("NtStmt(..)"),
|
||||
NtPat(..) => f.pad("NtPat(..)"),
|
||||
NtExpr(..) => f.pad("NtExpr(..)"),
|
||||
NtTy(..) => f.pad("NtTy(..)"),
|
||||
NtLiteral(..) => f.pad("NtLiteral(..)"),
|
||||
NtMeta(..) => f.pad("NtMeta(..)"),
|
||||
NtPath(..) => f.pad("NtPath(..)"),
|
||||
|
|
|
@ -469,7 +469,6 @@ impl TokenStream {
|
|||
}
|
||||
Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt),
|
||||
Nonterminal::NtPat(pat) => TokenStream::from_ast(pat),
|
||||
Nonterminal::NtTy(ty) => TokenStream::from_ast(ty),
|
||||
Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr),
|
||||
Nonterminal::NtPath(path) => TokenStream::from_ast(path),
|
||||
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),
|
||||
|
|
|
@ -322,6 +322,9 @@ pub(super) fn transcribe<'a>(
|
|||
let kind = token::NtLifetime(*ident, *is_raw);
|
||||
TokenTree::token_alone(kind, sp)
|
||||
}
|
||||
MatchedSingle(ParseNtResult::Ty(ty)) => {
|
||||
mk_delimited(MetaVarKind::Ty, TokenStream::from_ast(ty))
|
||||
}
|
||||
MatchedSingle(ParseNtResult::Vis(vis)) => {
|
||||
mk_delimited(MetaVarKind::Vis, TokenStream::from_ast(vis))
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
fn e() {
|
||||
type_ascribe!(p, a<p:p<e=6>>);
|
||||
//~^ ERROR cannot find type `a` in this scope
|
||||
//~| ERROR path separator must be a double colon
|
||||
//~| ERROR cannot find value
|
||||
//~| ERROR associated const equality
|
||||
//~| ERROR cannot find trait `p` in this scope
|
||||
//~| ERROR associated const equality
|
||||
//~| ERROR failed to resolve: use of unresolved module or unlinked crate `p`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
error: path separator must be a double colon
|
||||
--> $DIR/issue-93835.rs:4:25
|
||||
|
|
||||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^
|
||||
|
|
||||
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | type_ascribe!(p, a<p::p<e=6>>);
|
||||
| +
|
||||
|
||||
error[E0425]: cannot find value `p` in this scope
|
||||
--> $DIR/issue-93835.rs:4:19
|
||||
|
|
||||
|
@ -10,12 +22,6 @@ error[E0412]: cannot find type `a` in this scope
|
|||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0405]: cannot find trait `p` in this scope
|
||||
--> $DIR/issue-93835.rs:4:26
|
||||
|
|
||||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0658]: associated const equality is incomplete
|
||||
--> $DIR/issue-93835.rs:4:28
|
||||
|
|
||||
|
@ -26,7 +32,26 @@ LL | type_ascribe!(p, a<p:p<e=6>>);
|
|||
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0658]: associated const equality is incomplete
|
||||
--> $DIR/issue-93835.rs:4:28
|
||||
|
|
||||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
|
||||
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
Some errors have detailed explanations: E0405, E0412, E0425, E0658.
|
||||
For more information about an error, try `rustc --explain E0405`.
|
||||
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p`
|
||||
--> $DIR/issue-93835.rs:4:24
|
||||
|
|
||||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^ use of unresolved module or unlinked crate `p`
|
||||
|
|
||||
= help: you might be missing a crate named `p`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0412, E0425, E0433, E0658.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
|
|
|
@ -19,7 +19,7 @@ macro_rules! qpath {
|
|||
|
||||
(ty, <$type:ty as $trait:ty>::$name:ident) => {
|
||||
<$type as $trait>::$name
|
||||
//~^ ERROR expected identifier, found `!`
|
||||
//~^ ERROR expected identifier, found metavariable
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error: expected identifier, found `!`
|
||||
error: expected identifier, found metavariable
|
||||
--> $DIR/macro-interpolation.rs:21:19
|
||||
|
|
||||
LL | <$type as $trait>::$name
|
||||
| ^^^^^^ expected identifier
|
||||
| ^^^^^^ expected identifier, found metavariable
|
||||
...
|
||||
LL | let _: qpath!(ty, <str as !>::Owned);
|
||||
| -----------------------------
|
||||
|
|
|
@ -9,8 +9,8 @@ macro_rules! values {
|
|||
}
|
||||
};
|
||||
}
|
||||
//~^^^^^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found type `(String)`
|
||||
//~| ERROR macro expansion ignores type `(String)` and any tokens following
|
||||
//~^^^^^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `ty` metavariable
|
||||
//~| ERROR macro expansion ignores `ty` metavariable and any tokens following
|
||||
|
||||
values!(STRING(1) as (String) => cfg(test),);
|
||||
//~^ ERROR expected one of `!` or `::`, found `<eof>`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `(`, `,`, `=`, `{`, or `}`, found type `(String)`
|
||||
error: expected one of `(`, `,`, `=`, `{`, or `}`, found `ty` metavariable
|
||||
--> $DIR/syntax-error-recovery.rs:7:26
|
||||
|
|
||||
LL | $token $($inner)? = $value,
|
||||
|
@ -10,7 +10,7 @@ LL | values!(STRING(1) as (String) => cfg(test),);
|
|||
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
|
||||
= note: this error originates in the macro `values` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: macro expansion ignores type `(String)` and any tokens following
|
||||
error: macro expansion ignores `ty` metavariable and any tokens following
|
||||
--> $DIR/syntax-error-recovery.rs:7:26
|
||||
|
|
||||
LL | $token $($inner)? = $value,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
macro_rules! test_macro {
|
||||
( $( $t:ty ),* $(),*) => {
|
||||
enum SomeEnum {
|
||||
$( $t, )* //~ ERROR expected identifier, found `String`
|
||||
$( $t, )* //~ ERROR expected identifier, found metavariable
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error: expected identifier, found `String`
|
||||
error: expected identifier, found metavariable
|
||||
--> $DIR/issue-37113.rs:4:16
|
||||
|
|
||||
LL | enum SomeEnum {
|
||||
| -------- while parsing this enum
|
||||
LL | $( $t, )*
|
||||
| ^^ expected identifier
|
||||
| ^^ expected identifier, found metavariable
|
||||
...
|
||||
LL | test_macro!(String,);
|
||||
| -------------------- in this macro invocation
|
||||
|
|
|
@ -10,5 +10,6 @@ macro_rules! m {
|
|||
fn main() {
|
||||
m!('static);
|
||||
//~^ ERROR lifetime in trait object type must be followed by `+`
|
||||
//~| ERROR lifetime in trait object type must be followed by `+`
|
||||
//~| ERROR at least one trait is required for an object type
|
||||
}
|
||||
|
|
|
@ -4,12 +4,20 @@ error: lifetime in trait object type must be followed by `+`
|
|||
LL | m!('static);
|
||||
| ^^^^^^^
|
||||
|
||||
error: lifetime in trait object type must be followed by `+`
|
||||
--> $DIR/trait-object-macro-matcher.rs:11:8
|
||||
|
|
||||
LL | m!('static);
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0224]: at least one trait is required for an object type
|
||||
--> $DIR/trait-object-macro-matcher.rs:11:8
|
||||
|
|
||||
LL | m!('static);
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0224`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue