Skip to content

Commit fa59efa

Browse files
authored
Unrolled build for rust-lang#132653
Rollup merge of rust-lang#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 rust-lang#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`
2 parents 67f2127 + 1d6e847 commit fa59efa

File tree

6 files changed

+466
-36
lines changed

6 files changed

+466
-36
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+31-4
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@ impl Expr {
11941194
///
11951195
/// Does not ensure that the path resolves to a const param, the caller should check this.
11961196
pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool {
1197-
let this = if strip_identity_block { self.maybe_unwrap_block().1 } else { self };
1197+
let this = if strip_identity_block { self.maybe_unwrap_block() } else { self };
11981198

11991199
if let ExprKind::Path(None, path) = &this.kind
12001200
&& path.is_potential_trivial_const_arg()
@@ -1206,14 +1206,41 @@ impl Expr {
12061206
}
12071207

12081208
/// Returns an expression with (when possible) *one* outter brace removed
1209-
pub fn maybe_unwrap_block(&self) -> (bool, &Expr) {
1209+
pub fn maybe_unwrap_block(&self) -> &Expr {
12101210
if let ExprKind::Block(block, None) = &self.kind
12111211
&& let [stmt] = block.stmts.as_slice()
12121212
&& let StmtKind::Expr(expr) = &stmt.kind
12131213
{
1214-
(true, expr)
1214+
expr
12151215
} else {
1216-
(false, self)
1216+
self
1217+
}
1218+
}
1219+
1220+
/// Determines whether this expression is a macro call optionally wrapped in braces . If
1221+
/// `already_stripped_block` is set then we do not attempt to peel off a layer of braces.
1222+
///
1223+
/// Returns the [`NodeId`] of the macro call and whether a layer of braces has been peeled
1224+
/// either before, or part of, this function.
1225+
pub fn optionally_braced_mac_call(
1226+
&self,
1227+
already_stripped_block: bool,
1228+
) -> Option<(bool, NodeId)> {
1229+
match &self.kind {
1230+
ExprKind::Block(block, None)
1231+
if let [stmt] = &*block.stmts
1232+
&& !already_stripped_block =>
1233+
{
1234+
match &stmt.kind {
1235+
StmtKind::MacCall(_) => Some((true, stmt.id)),
1236+
StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1237+
Some((true, expr.id))
1238+
}
1239+
_ => None,
1240+
}
1241+
}
1242+
ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1243+
_ => None,
12171244
}
12181245
}
12191246

Diff for: compiler/rustc_resolve/src/def_collector.rs

+10-19
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,16 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
130130
&self,
131131
anon_const: &'a AnonConst,
132132
) -> Option<(PendingAnonConstInfo, NodeId)> {
133-
let (block_was_stripped, expr) = anon_const.value.maybe_unwrap_block();
134-
match expr {
135-
Expr { kind: ExprKind::MacCall(..), id, .. } => Some((
133+
anon_const.value.optionally_braced_mac_call(false).map(|(block_was_stripped, id)| {
134+
(
136135
PendingAnonConstInfo {
137136
id: anon_const.id,
138137
span: anon_const.value.span,
139138
block_was_stripped,
140139
},
141-
*id,
142-
)),
143-
_ => None,
144-
}
140+
id,
141+
)
142+
})
145143
}
146144

147145
/// 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> {
161159
panic!("Checking expr is trivial macro call without having entered anon const: `{const_arg_sub_expr:?}`"),
162160
);
163161

164-
let (block_was_stripped, expr) = if pending_anon.block_was_stripped {
165-
(true, const_arg_sub_expr)
166-
} else {
167-
const_arg_sub_expr.maybe_unwrap_block()
168-
};
169-
170-
match expr {
171-
Expr { kind: ExprKind::MacCall(..), id, .. } => {
172-
Some((PendingAnonConstInfo { block_was_stripped, ..pending_anon }, *id))
173-
}
174-
_ => None,
175-
}
162+
const_arg_sub_expr.optionally_braced_mac_call(pending_anon.block_was_stripped).map(
163+
|(block_was_stripped, id)| {
164+
(PendingAnonConstInfo { block_was_stripped, ..pending_anon }, id)
165+
},
166+
)
176167
}
177168
}
178169

Diff for: tests/crashes/131915.rs

-13
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Regression test for #131915 where we did not handle macro calls as
2+
// statements correctly when determining if a const argument should
3+
// have a `DefId` created or not.
4+
5+
macro_rules! y {
6+
( $($matcher:tt)*) => {
7+
x
8+
//~^ ERROR: cannot find value `x` in this scope
9+
};
10+
}
11+
12+
const _: A<
13+
//~^ ERROR: free constant item without body
14+
//~| ERROR: cannot find type `A` in this scope
15+
{
16+
y! { test.tou8 }
17+
},
18+
>;
19+
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error: free constant item without body
2+
--> $DIR/const_arg_trivial_macro_expansion-2.rs:12:1
3+
|
4+
LL | / const _: A<
5+
LL | |
6+
LL | |
7+
LL | | {
8+
LL | | y! { test.tou8 }
9+
LL | | },
10+
LL | | >;
11+
| | ^ help: provide a definition for the constant: `= <expr>;`
12+
| |__|
13+
|
14+
15+
error[E0412]: cannot find type `A` in this scope
16+
--> $DIR/const_arg_trivial_macro_expansion-2.rs:12:10
17+
|
18+
LL | const _: A<
19+
| ^ not found in this scope
20+
21+
error[E0425]: cannot find value `x` in this scope
22+
--> $DIR/const_arg_trivial_macro_expansion-2.rs:7:9
23+
|
24+
LL | x
25+
| ^ not found in this scope
26+
...
27+
LL | y! { test.tou8 }
28+
| ---------------- in this macro invocation
29+
|
30+
= note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)
31+
help: you might be missing a const parameter
32+
|
33+
LL | const _<const x: /* Type */>: A<
34+
| +++++++++++++++++++++
35+
36+
error: aborting due to 3 previous errors
37+
38+
Some errors have detailed explanations: E0412, E0425.
39+
For more information about an error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)