Skip to content

Commit 9e215d2

Browse files
Deny braced macro invocations in let-else
1 parent 43dcc9b commit 9e215d2

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

compiler/rustc_ast/src/util/classify.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
// Predicates on exprs and stmts that the pretty-printer and parser use
44

5-
use crate::ast;
5+
use crate::{ast, token::Delimiter};
66

77
/// Does this expression require a semicolon to be treated
88
/// as a statement? The negation of this: 'can this expression
@@ -51,8 +51,12 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
5151
Gen(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
5252
| TryBlock(..) | While(..) | ConstBlock(_) => break Some(expr),
5353

54-
// FIXME: These can end in `}`, but changing these would break stable code.
55-
InlineAsm(_) | OffsetOf(_, _) | MacCall(_) | IncludedBytes(_) | FormatArgs(_) => {
54+
MacCall(mac) => {
55+
break (mac.args.delim == Delimiter::Brace).then_some(expr);
56+
}
57+
58+
InlineAsm(_) | OffsetOf(_, _) | IncludedBytes(_) | FormatArgs(_) => {
59+
// These should have been denied pre-expansion.
5660
break None;
5761
}
5862

tests/ui/parser/bad-let-else-statement.rs

+27
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,31 @@ fn q() {
161161
};
162162
}
163163

164+
fn r() {
165+
use std::arch::asm;
166+
167+
let ok = asm!(" nop ") else { return; };
168+
169+
let bad = asm! {" nop "} else { return; };
170+
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
171+
}
172+
173+
fn s() {
174+
macro_rules! a {
175+
() => { {} }
176+
}
177+
178+
macro_rules! b {
179+
(1) => {
180+
let x = a!() else { return; };
181+
};
182+
(2) => {
183+
let x = a! {} else { return; };
184+
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
185+
};
186+
}
187+
188+
b!(1); b!(2);
189+
}
190+
164191
fn main() {}

tests/ui/parser/bad-let-else-statement.stderr

+27-1
Original file line numberDiff line numberDiff line change
@@ -228,5 +228,31 @@ LL | x
228228
LL ~ }) else {
229229
|
230230

231-
error: aborting due to 17 previous errors
231+
error: right curly brace `}` before `else` in a `let...else` statement not allowed
232+
--> $DIR/bad-let-else-statement.rs:169:28
233+
|
234+
LL | let bad = asm! {" nop "} else { return; };
235+
| ^
236+
|
237+
help: wrap the expression in parentheses
238+
|
239+
LL | let bad = (asm! {" nop "}) else { return; };
240+
| + +
241+
242+
error: right curly brace `}` before `else` in a `let...else` statement not allowed
243+
--> $DIR/bad-let-else-statement.rs:183:25
244+
|
245+
LL | let x = a! {} else { return; };
246+
| ^
247+
...
248+
LL | b!(1); b!(2);
249+
| ----- in this macro invocation
250+
|
251+
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
252+
help: wrap the expression in parentheses
253+
|
254+
LL | let x = (a! {}) else { return; };
255+
| + +
256+
257+
error: aborting due to 19 previous errors
232258

0 commit comments

Comments
 (0)