diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index bf574cf463cc0..7f1b58dd1de08 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -423,10 +423,6 @@ pub trait MacResult { None } - fn make_method_receiver_expr(self: Box) -> Option> { - self.make_expr() - } - /// Creates zero or more items. fn make_items(self: Box) -> Option; 1]>> { None diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index b6611e7e0ca0c..741c34e0304af 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -68,6 +68,7 @@ macro_rules! ast_fragments { /// Can also serve as an input and intermediate result for macro expansion operations. pub enum AstFragment { OptExpr(Option>), + MethodReceiverExpr(Box), $($Kind($AstTy),)* } @@ -75,6 +76,7 @@ macro_rules! ast_fragments { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum AstFragmentKind { OptExpr, + MethodReceiverExpr, $($Kind,)* } @@ -82,6 +84,7 @@ macro_rules! ast_fragments { pub fn name(self) -> &'static str { match self { AstFragmentKind::OptExpr => "expression", + AstFragmentKind::MethodReceiverExpr => "expression", $(AstFragmentKind::$Kind => $kind_name,)* } } @@ -90,6 +93,8 @@ macro_rules! ast_fragments { match self { AstFragmentKind::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),)* } } @@ -116,6 +121,13 @@ macro_rules! ast_fragments { } } + pub(crate) fn make_method_receiver_expr(self) -> Box { + 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 { match self { AstFragment::$Kind(ast) => ast, @@ -134,6 +146,7 @@ macro_rules! ast_fragments { *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) => ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)* @@ -144,6 +157,7 @@ macro_rules! ast_fragments { match self { AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)), 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) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)* } @@ -166,11 +180,6 @@ ast_fragments! { one fn visit_expr; fn make_expr; } - MethodReceiverExpr(Box) { - "expression"; - one fn visit_method_receiver_expr; - fn make_method_receiver_expr; - } Pat(Box) { "pattern"; one fn visit_pat; diff --git a/tests/ui/macros/auxiliary/semicolon-in-exprs.rs b/tests/ui/macros/auxiliary/semicolon-in-exprs.rs new file mode 100644 index 0000000000000..87a1c1786c1e4 --- /dev/null +++ b/tests/ui/macros/auxiliary/semicolon-in-exprs.rs @@ -0,0 +1,4 @@ +#[macro_export] +macro_rules! outer { + ($inner:ident) => { $inner![1, 2, 3]; }; +} diff --git a/tests/ui/macros/semicolon-in-exprs.rs b/tests/ui/macros/semicolon-in-exprs.rs new file mode 100644 index 0000000000000..1d6c9d895f067 --- /dev/null +++ b/tests/ui/macros/semicolon-in-exprs.rs @@ -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 = semicolon_in_exprs::outer!(inner).into_iter().collect(); +}