Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ impl fmt::Display for MetaVarKind {
MetaVarKind::Item => sym::item,
MetaVarKind::Block => sym::block,
MetaVarKind::Stmt => sym::stmt,
MetaVarKind::Pat(PatParam { inferred: true } | PatWithOr) => sym::pat,
MetaVarKind::Pat(PatParam { inferred: false }) => sym::pat_param,
MetaVarKind::Pat(Pat2018 | PatWithOr) => sym::pat,
MetaVarKind::Pat(PatParam) => sym::pat_param,
MetaVarKind::Expr { kind: Expr2021 { inferred: true } | Expr, .. } => sym::expr,
MetaVarKind::Expr { kind: Expr2021 { inferred: false }, .. } => sym::expr_2021,
MetaVarKind::Ty { .. } => sym::ty,
Expand Down Expand Up @@ -1119,10 +1119,10 @@ pub fn ident_of_kind_is_reserved(id: sp::Ident, kind: IdentKind) -> bool {
pub enum NtPatKind {
// Matches or-patterns. Was written using `pat` in edition 2021 or later.
PatWithOr,
// Doesn't match or-patterns.
// - `inferred`: was written using `pat` in edition 2015 or 2018.
// - `!inferred`: was written using `pat_param`.
PatParam { inferred: bool },
// Doesn't match or-patterns. Was written using `pat_param`.
PatParam,
// Doesn't match or-patterns. Was written using `pat` in edition 2015 or 2018.
Pat2018,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, StableHash)]
Expand Down Expand Up @@ -1170,10 +1170,10 @@ impl NonterminalKind {
if edition().at_least_rust_2021() {
NonterminalKind::Pat(PatWithOr)
} else {
NonterminalKind::Pat(PatParam { inferred: true })
NonterminalKind::Pat(Pat2018)
}
}
sym::pat_param => NonterminalKind::Pat(PatParam { inferred: false }),
sym::pat_param => NonterminalKind::Pat(PatParam),
sym::expr => {
if edition().at_least_rust_2024() {
NonterminalKind::Expr(Expr)
Expand All @@ -1200,8 +1200,8 @@ impl NonterminalKind {
NonterminalKind::Item => sym::item,
NonterminalKind::Block => sym::block,
NonterminalKind::Stmt => sym::stmt,
NonterminalKind::Pat(PatParam { inferred: true } | PatWithOr) => sym::pat,
NonterminalKind::Pat(PatParam { inferred: false }) => sym::pat_param,
NonterminalKind::Pat(Pat2018 | PatWithOr) => sym::pat,
NonterminalKind::Pat(PatParam) => sym::pat_param,
NonterminalKind::Expr(Expr2021 { inferred: true } | Expr) => sym::expr,
NonterminalKind::Expr(Expr2021 { inferred: false }) => sym::expr_2021,
NonterminalKind::Ty => sym::ty,
Expand Down
25 changes: 21 additions & 4 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,7 @@ fn check_matcher_core<'tt>(
// the macro when compiling another crate that is using the
// macro. (See #86567.)
if is_defined_in_current_crate(node_id)
&& matches!(kind, NonterminalKind::Pat(PatParam { inferred: true }))
&& matches!(kind, NonterminalKind::Pat(Pat2018))
&& matches!(
next_token,
TokenTree::Token(token) if *token == token::Or
Expand All @@ -1593,7 +1593,7 @@ fn check_matcher_core<'tt>(
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl {
span,
name,
kind: NonterminalKind::Pat(PatParam { inferred: false }),
kind: NonterminalKind::Pat(PatParam),
});
sess.psess.buffer_lint(
RUST_2021_INCOMPATIBLE_OR_PATTERNS,
Expand Down Expand Up @@ -1629,11 +1629,13 @@ fn check_matcher_core<'tt>(
if kind == NonterminalKind::Pat(PatWithOr)
&& sess.psess.edition.at_least_rust_2021()
&& next_token.is_token(&token::Or)
|| matches!(kind, NonterminalKind::Pat(PatWithOr | Pat2018))
&& next_token.is_token(&token::Colon)
{
let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl {
span,
name,
kind: NonterminalKind::Pat(PatParam { inferred: false }),
kind: NonterminalKind::Pat(PatParam),
});
err.span_suggestion(
span,
Expand Down Expand Up @@ -1745,7 +1747,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
_ => IsInFollow::No(TOKENS),
}
}
NonterminalKind::Pat(PatParam { .. }) => {
NonterminalKind::Pat(Pat2018) => {
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`if let`", "`in`"];
match tok {
TokenTree::Token(token) => match token.kind {
Expand All @@ -1759,6 +1761,21 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
_ => IsInFollow::No(TOKENS),
}
}
NonterminalKind::Pat(PatParam) => {
const TOKENS: &[&str] =
&["`=>`", "`,`", "`=`", "`|`", "`:`", "`if`", "`if let`", "`in`"];
match tok {
TokenTree::Token(token) => match token.kind {
FatArrow | Comma | Eq | Or | Colon => IsInFollow::Yes,
Ident(kw::If | kw::In, IdentKind::Normal | IdentKind::ForcedKeyword) => {
IsInFollow::Yes
}
_ => IsInFollow::No(TOKENS),
},
TokenTree::MetaVarDecl { kind: NonterminalKind::Guard, .. } => IsInFollow::Yes,
_ => IsInFollow::No(TOKENS),
}
}
NonterminalKind::Pat(PatWithOr) => {
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`if let`", "`in`"];
match tok {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/nonterminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl<'a> Parser<'a> {
NonterminalKind::Pat(pat_kind) => Ok(ParseNtResult::Pat(
self.collect_tokens_no_attrs(|this| {
match pat_kind {
PatParam { .. } => this.parse_pat_no_top_alt(None, None),
PatParam | Pat2018 => this.parse_pat_no_top_alt(None, None),
PatWithOr => this.parse_pat_no_top_guard(
None,
RecoverComma::No,
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ impl<'a> Parser<'a> {
fn eat_metavar_pat(&mut self) -> Option<Pat> {
// Must try both kinds of pattern nonterminals.
if let Some(pat) = self.eat_metavar_seq_with_matcher(
|mv_kind| matches!(mv_kind, MetaVarKind::Pat(PatParam { .. })),
|mv_kind| matches!(mv_kind, MetaVarKind::Pat(PatParam | Pat2018)),
|this| this.parse_pat_no_top_alt(None, None),
) {
Some(pat)
Expand Down Expand Up @@ -733,9 +733,7 @@ impl<'a> Parser<'a> {
let mut lo = self.token.span;

if self.token.is_keyword(kw::Let)
&& self.look_ahead(1, |tok| {
tok.can_begin_pattern(token::NtPatKind::PatParam { inferred: false })
})
&& self.look_ahead(1, |tok| tok.can_begin_pattern(PatParam))
{
self.bump();
// Trim extra space after the `let`
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,7 @@ impl<'a> Parser<'a> {
&& prev_token_before_parsing == token::PathSep
&& (style == PathStyle::Expr && self.token.can_begin_expr()
|| style == PathStyle::Pat
&& self.token.can_begin_pattern(token::NtPatKind::PatParam {
inferred: false,
}))
&& self.token.can_begin_pattern(token::NtPatKind::PatParam))
{
snapshot = Some(self.create_snapshot_for_diagnostic());
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/rustfmt/src/parse/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
);
parse_macro_arg!(
Pat,
NonterminalKind::Pat(PatParam { inferred: false }),
NonterminalKind::Pat(PatParam),
|parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None),
|x: ast::Pat| Some(Box::new(x))
);
Expand Down
22 changes: 22 additions & 0 deletions tests/ui/macros/macro-follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ macro_rules! follow_pat {
($p:pat $i:item) => {}; //~ERROR `$p:pat` is followed by `$i:item`
($p:pat $m:meta) => {}; //~ERROR `$p:pat` is followed by `$m:meta`
}
// FOLLOW(pat_param) = {FOLLOW(pat), Colon[, Or]}
// optional inclusion of `Or` depends on the edition; this is tested separately,
// in `macro-pat-pattern-followed-by-or.rs` / `macro-pat-pattern-followed-by-or-in-2021.rs`
macro_rules! follow_pat {
($p:pat_param ()) => {}; //~ERROR `$p:pat_param` is followed by `(`
($p:pat_param []) => {}; //~ERROR `$p:pat_param` is followed by `[`
($p:pat_param {}) => {}; //~ERROR `$p:pat_param` is followed by `{`
($p:pat_param :) => {}; // ok
($p:pat_param >) => {}; //~ERROR `$p:pat_param` is followed by `>`
($p:pat_param +) => {}; //~ERROR `$p:pat_param` is followed by `+`
($p:pat_param ident) => {}; //~ERROR `$p:pat_param` is followed by `ident`
($p:pat_param $q:pat) => {}; //~ERROR `$p:pat_param` is followed by `$q:pat`
($p:pat_param $e:expr) => {}; //~ERROR `$p:pat_param` is followed by `$e:expr`
($p:pat_param $t:ty) => {}; //~ERROR `$p:pat_param` is followed by `$t:ty`
($p:pat_param $s:stmt) => {}; //~ERROR `$p:pat_param` is followed by `$s:stmt`
($p:pat_param $q:path) => {}; //~ERROR `$p:pat_param` is followed by `$q:path`
($p:pat_param $b:block) => {}; //~ERROR `$p:pat_param` is followed by `$b:block`
($p:pat_param $i:ident) => {}; //~ERROR `$p:pat_param` is followed by `$i:ident`
($p:pat_param $t:tt) => {}; //~ERROR `$p:pat_param` is followed by `$t:tt`
($p:pat_param $i:item) => {}; //~ERROR `$p:pat_param` is followed by `$i:item`
($p:pat_param $m:meta) => {}; //~ERROR `$p:pat_param` is followed by `$m:meta`
}
// FOLLOW(expr) = {FatArrow, Comma, Semicolon}
macro_rules! follow_expr {
($e:expr ()) => {}; //~ERROR `$e:expr` is followed by `(`
Expand Down
Loading
Loading