Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use maybe_unwrap_block when checking for macro calls in a block expr #132653

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
35 changes: 31 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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,
}
}

Expand Down
29 changes: 10 additions & 19 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
},
)
}
}

Expand Down
13 changes: 0 additions & 13 deletions tests/crashes/131915.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Regression test for #131915 where we did not handle macro calls as
// statements correctly when determining if a const argument should
// have a `DefId` created or not.

macro_rules! y {
( $($matcher:tt)*) => {
x
//~^ ERROR: cannot find value `x` in this scope
};
}

const _: A<
//~^ ERROR: free constant item without body
//~| ERROR: cannot find type `A` in this scope
{
y! { test.tou8 }
},
>;

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error: free constant item without body
--> $DIR/const_arg_trivial_macro_expansion-2.rs:12:1
|
LL | / const _: A<
LL | |
LL | |
LL | | {
LL | | y! { test.tou8 }
LL | | },
LL | | >;
| | ^ help: provide a definition for the constant: `= <expr>;`
| |__|
|

error[E0412]: cannot find type `A` in this scope
--> $DIR/const_arg_trivial_macro_expansion-2.rs:12:10
|
LL | const _: A<
| ^ not found in this scope

error[E0425]: cannot find value `x` in this scope
--> $DIR/const_arg_trivial_macro_expansion-2.rs:7:9
|
LL | x
| ^ not found in this scope
...
LL | y! { test.tou8 }
| ---------------- in this macro invocation
|
= note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might be missing a const parameter
|
LL | const _<const x: /* Type */>: A<
| +++++++++++++++++++++

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0412, E0425.
For more information about an error, try `rustc --explain E0412`.
Loading
Loading