diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-11-12 06:27:17 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-12 06:27:17 +0100 |
| commit | b7dc4813a8ea9debafd7bc86bda3baafe6646f93 (patch) | |
| tree | bd2d761c689d84e3b2f938d44891676e9a4ae0d5 /compiler | |
| parent | 2ad4a3568d9932bc4ecba48142a1f400c6c260aa (diff) | |
| parent | 1d6e8476746d79d21bde97243c30937738750227 (diff) | |
Rollup merge of #132653 - BoxyUwU:const_arg_stmt_mac_call, r=compiler-errors
Don't use `maybe_unwrap_block` when checking for macro calls in a block expr
Fixes #131915
Using `maybe_unwrap_block` to determine if we are looking at a `{ mac_call!{} }` will fail sometimes as `mac_call!{}` could be a `StmtKind::MacCall` not a `StmtKind::Expr`. This caused the def collector to think that `{ mac_call!{} }` was a non-trivial const argument and create a definition for it even though it should not.
r? `@compiler-errors` cc `@camelid`
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/def_collector.rs | 29 |
2 files changed, 41 insertions, 23 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 997c44cffff..5f71fb97d76 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1194,7 +1194,7 @@ impl Expr { /// /// Does not ensure that the path resolves to a const param, the caller should check this. pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool { - let this = if strip_identity_block { self.maybe_unwrap_block().1 } else { self }; + let this = if strip_identity_block { self.maybe_unwrap_block() } else { self }; if let ExprKind::Path(None, path) = &this.kind && path.is_potential_trivial_const_arg() @@ -1206,14 +1206,41 @@ impl Expr { } /// Returns an expression with (when possible) *one* outter brace removed - pub fn maybe_unwrap_block(&self) -> (bool, &Expr) { + pub fn maybe_unwrap_block(&self) -> &Expr { if let ExprKind::Block(block, None) = &self.kind && let [stmt] = block.stmts.as_slice() && let StmtKind::Expr(expr) = &stmt.kind { - (true, expr) + expr } else { - (false, self) + self + } + } + + /// Determines whether this expression is a macro call optionally wrapped in braces . If + /// `already_stripped_block` is set then we do not attempt to peel off a layer of braces. + /// + /// Returns the [`NodeId`] of the macro call and whether a layer of braces has been peeled + /// either before, or part of, this function. + pub fn optionally_braced_mac_call( + &self, + already_stripped_block: bool, + ) -> Option<(bool, NodeId)> { + match &self.kind { + ExprKind::Block(block, None) + if let [stmt] = &*block.stmts + && !already_stripped_block => + { + match &stmt.kind { + StmtKind::MacCall(_) => Some((true, stmt.id)), + StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => { + Some((true, expr.id)) + } + _ => None, + } + } + ExprKind::MacCall(_) => Some((already_stripped_block, self.id)), + _ => None, } } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index a825458dc89..bf27b767a49 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -130,18 +130,16 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { &self, anon_const: &'a AnonConst, ) -> Option<(PendingAnonConstInfo, NodeId)> { - let (block_was_stripped, expr) = anon_const.value.maybe_unwrap_block(); - match expr { - Expr { kind: ExprKind::MacCall(..), id, .. } => Some(( + anon_const.value.optionally_braced_mac_call(false).map(|(block_was_stripped, id)| { + ( PendingAnonConstInfo { id: anon_const.id, span: anon_const.value.span, block_was_stripped, }, - *id, - )), - _ => None, - } + id, + ) + }) } /// Determines whether the expression `const_arg_sub_expr` is a simple macro call, sometimes @@ -161,18 +159,11 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { panic!("Checking expr is trivial macro call without having entered anon const: `{const_arg_sub_expr:?}`"), ); - let (block_was_stripped, expr) = if pending_anon.block_was_stripped { - (true, const_arg_sub_expr) - } else { - const_arg_sub_expr.maybe_unwrap_block() - }; - - match expr { - Expr { kind: ExprKind::MacCall(..), id, .. } => { - Some((PendingAnonConstInfo { block_was_stripped, ..pending_anon }, *id)) - } - _ => None, - } + const_arg_sub_expr.optionally_braced_mac_call(pending_anon.block_was_stripped).map( + |(block_was_stripped, id)| { + (PendingAnonConstInfo { block_was_stripped, ..pending_anon }, id) + }, + ) } } |
