Rollup merge of #156184 - cyrgani:macros-are-weird, r=petrochenkov

Revert "remove `MethodReceiverExpr` special-casing"

This reverts commit 5ad560f7ec and adds a regression test.

Fixes rust-lang/rust#156084.

r? @petrochenkov
This commit is contained in:
Jonathan Brouwer
2026-05-05 14:25:24 +02:00
committed by GitHub
4 changed files with 33 additions and 9 deletions
-4
View File
@@ -423,10 +423,6 @@ pub trait MacResult {
None None
} }
fn make_method_receiver_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
self.make_expr()
}
/// Creates zero or more items. /// Creates zero or more items.
fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> { fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
None None
+14 -5
View File
@@ -68,6 +68,7 @@ macro_rules! ast_fragments {
/// Can also serve as an input and intermediate result for macro expansion operations. /// Can also serve as an input and intermediate result for macro expansion operations.
pub enum AstFragment { pub enum AstFragment {
OptExpr(Option<Box<ast::Expr>>), OptExpr(Option<Box<ast::Expr>>),
MethodReceiverExpr(Box<ast::Expr>),
$($Kind($AstTy),)* $($Kind($AstTy),)*
} }
@@ -75,6 +76,7 @@ macro_rules! ast_fragments {
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AstFragmentKind { pub enum AstFragmentKind {
OptExpr, OptExpr,
MethodReceiverExpr,
$($Kind,)* $($Kind,)*
} }
@@ -82,6 +84,7 @@ macro_rules! ast_fragments {
pub fn name(self) -> &'static str { pub fn name(self) -> &'static str {
match self { match self {
AstFragmentKind::OptExpr => "expression", AstFragmentKind::OptExpr => "expression",
AstFragmentKind::MethodReceiverExpr => "expression",
$(AstFragmentKind::$Kind => $kind_name,)* $(AstFragmentKind::$Kind => $kind_name,)*
} }
} }
@@ -90,6 +93,8 @@ macro_rules! ast_fragments {
match self { match self {
AstFragmentKind::OptExpr => AstFragmentKind::OptExpr =>
result.make_expr().map(Some).map(AstFragment::OptExpr), result.make_expr().map(Some).map(AstFragment::OptExpr),
AstFragmentKind::MethodReceiverExpr =>
result.make_expr().map(AstFragment::MethodReceiverExpr),
$(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)* $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
} }
} }
@@ -116,6 +121,13 @@ macro_rules! ast_fragments {
} }
} }
pub(crate) fn make_method_receiver_expr(self) -> Box<ast::Expr> {
match self {
AstFragment::MethodReceiverExpr(expr) => expr,
_ => panic!("AstFragment::make_method_receiver_expr called on the wrong kind of fragment"),
}
}
$(pub fn $make_ast(self) -> $AstTy { $(pub fn $make_ast(self) -> $AstTy {
match self { match self {
AstFragment::$Kind(ast) => ast, AstFragment::$Kind(ast) => ast,
@@ -134,6 +146,7 @@ macro_rules! ast_fragments {
*opt_expr = vis.filter_map_expr(expr) *opt_expr = vis.filter_map_expr(expr)
} }
} }
AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr),
$($(AstFragment::$Kind(ast) => vis.$visit_ast(ast),)?)* $($(AstFragment::$Kind(ast) => vis.$visit_ast(ast),)?)*
$($(AstFragment::$Kind(ast) => $($(AstFragment::$Kind(ast) =>
ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)* ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)*
@@ -144,6 +157,7 @@ macro_rules! ast_fragments {
match self { match self {
AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)), AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)),
AstFragment::OptExpr(None) => {} AstFragment::OptExpr(None) => {}
AstFragment::MethodReceiverExpr(expr) => try_visit!(visitor.visit_method_receiver_expr(expr)),
$($(AstFragment::$Kind(ast) => try_visit!(visitor.$visit_ast(ast)),)?)* $($(AstFragment::$Kind(ast) => try_visit!(visitor.$visit_ast(ast)),)?)*
$($(AstFragment::$Kind(ast) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)* $($(AstFragment::$Kind(ast) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)*
} }
@@ -166,11 +180,6 @@ ast_fragments! {
one fn visit_expr; one fn visit_expr;
fn make_expr; fn make_expr;
} }
MethodReceiverExpr(Box<ast::Expr>) {
"expression";
one fn visit_method_receiver_expr;
fn make_method_receiver_expr;
}
Pat(Box<ast::Pat>) { Pat(Box<ast::Pat>) {
"pattern"; "pattern";
one fn visit_pat; one fn visit_pat;
@@ -0,0 +1,4 @@
#[macro_export]
macro_rules! outer {
($inner:ident) => { $inner![1, 2, 3]; };
}
+15
View File
@@ -0,0 +1,15 @@
//! Regression test for https://github.com/rust-lang/rust/issues/156084.
//! This test can probably be removed again once
//! `semicolon_in_expressions_from_macros` is a hard error.
//@ check-pass
//@ aux-build:semicolon-in-exprs.rs
//@ edition: 2021
extern crate semicolon_in_exprs;
macro_rules! inner {
[$($x:expr),*] => { [$($x),*] };
}
fn main() {
let _v: Vec<i32> = semicolon_in_exprs::outer!(inner).into_iter().collect();
}