Skip to content

Commit

Permalink
Remove NtTy.
Browse files Browse the repository at this point in the history
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: ditto.

- The changes to metavariable descriptions in rust-lang#132629 are now visible in
  error message for several tests.
  • Loading branch information
nnethercote committed Nov 25, 2024
1 parent 4c098db commit 5552feb
Show file tree
Hide file tree
Showing 19 changed files with 88 additions and 42 deletions.
2 changes: 0 additions & 2 deletions compiler/rustc_ast/src/ast_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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(),
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,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();
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,6 @@ impl Token {
| NtMeta(..)
| NtPat(..)
| NtPath(..)
| NtTy(..)
),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Expr { .. } |
Expand Down Expand Up @@ -689,7 +688,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
Expand Down Expand Up @@ -1070,7 +1069,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>),
Expand Down Expand Up @@ -1168,7 +1166,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,
}
Expand All @@ -1182,7 +1179,6 @@ impl Nonterminal {
NtPat(..) => "pattern",
NtExpr(..) => "expression",
NtLiteral(..) => "literal",
NtTy(..) => "type",
NtMeta(..) => "attribute",
NtPath(..) => "path",
}
Expand All @@ -1207,7 +1203,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(..)"),
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,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),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_expand/src/mbe/transcribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,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))
}
Expand Down
33 changes: 28 additions & 5 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,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);
}
};
Expand Down Expand Up @@ -611,6 +615,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().0.clone();
let tt = tree_cursor.next_ref();
matches!(
tt,
Some(ast::tokenstream::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
Expand Down Expand Up @@ -1740,6 +1762,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`.
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_parse/src/parser/nonterminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ impl<'a> Parser<'a> {
NtStmt(_)
| NtPat(_)
| NtExpr(_)
| NtTy(_)
| NtLiteral(_) // `true`, `false`
| NtMeta(_)
| NtPath(_) => true,
Expand Down Expand Up @@ -99,7 +98,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
Expand Down Expand Up @@ -186,7 +185,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 => {
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -198,13 +198,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));
}
}

Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -19,7 +19,7 @@ use crate::errors::{
HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
NestedCVariadicType, ReturnTypesUseThinArrow,
};
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use crate::maybe_recover_from_interpolated_ty_qpath;

/// Signals whether parsing a type should allow `+`.
///
Expand Down Expand Up @@ -184,7 +184,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,
Expand Down Expand Up @@ -248,7 +249,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;
Expand Down
1 change: 1 addition & 0 deletions tests/ui/associated-consts/issue-93835.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ fn e() {
//~^ ERROR cannot find type `a` in this scope
//~| ERROR cannot find value
//~| ERROR associated const equality
//~| ERROR associated const equality
//~| ERROR cannot find trait `p` in this scope
}

Expand Down
13 changes: 12 additions & 1 deletion tests/ui/associated-consts/issue-93835.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,18 @@ 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`

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0405, E0412, E0425, E0658.
For more information about an error, try `rustc --explain E0405`.
2 changes: 1 addition & 1 deletion tests/ui/macros/macro-interpolation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
}

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/macros/macro-interpolation.stderr
Original file line number Diff line number Diff line change
@@ -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);
| -----------------------------
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/macros/syntax-error-recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/macros/syntax-error-recovery.stderr
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/macro/issue-37113.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
macro_rules! test_macro {
( $( $t:ty ),* $(),*) => {
enum SomeEnum {
$( $t, )* //~ ERROR expected identifier, found `String`
$( $t, )* //~ ERROR expected identifier, found metavariable
};
};
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/parser/macro/issue-37113.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions tests/ui/parser/macro/trait-object-macro-matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
10 changes: 9 additions & 1 deletion tests/ui/parser/macro/trait-object-macro-matcher.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

0 comments on commit 5552feb

Please sign in to comment.