reject inline const patterns pre-expansion

This commit is contained in:
dianne 2026-02-12 08:26:03 -08:00
parent 7ad4e69ad5
commit 60f802fe11
7 changed files with 91 additions and 52 deletions

View file

@ -1524,7 +1524,7 @@ impl<'a> Parser<'a> {
},
)
} else if this.check_inline_const(0) {
this.parse_const_block(lo)
this.parse_const_block(lo, false)
} else if this.may_recover() && this.is_do_catch_block() {
this.recover_do_catch()
} else if this.is_try_block() {

View file

@ -1270,7 +1270,7 @@ impl<'a> Parser<'a> {
}
/// Parses inline const expressions.
fn parse_const_block(&mut self, span: Span) -> PResult<'a, Box<Expr>> {
fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, Box<Expr>> {
self.expect_keyword(exp!(Const))?;
let (attrs, blk) = self.parse_inner_attrs_and_block(None)?;
let anon_const = AnonConst {
@ -1279,7 +1279,18 @@ impl<'a> Parser<'a> {
mgca_disambiguation: MgcaDisambiguation::AnonConst,
};
let blk_span = anon_const.value.span;
let kind = ExprKind::ConstBlock(anon_const);
let kind = if pat {
let guar = self
.dcx()
.struct_span_err(blk_span, "const blocks cannot be used as patterns")
.with_help(
"use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead",
)
.emit();
ExprKind::Err(guar)
} else {
ExprKind::ConstBlock(anon_const)
};
Ok(self.mk_expr_with_attrs(span.to(blk_span), kind, attrs))
}

View file

@ -785,10 +785,8 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(exp!(Box)) {
self.parse_pat_box()?
} else if self.check_inline_const(0) {
// Parse `const pat`.
// NOTE: This will always error later during AST lowering because
// inline const cannot be used as patterns.
let const_expr = self.parse_const_block(lo.to(self.token.span))?;
// Parse `const pat`
let const_expr = self.parse_const_block(lo.to(self.token.span), true)?;
if let Some(re) = self.parse_range_end() {
self.parse_pat_range_begin_with(const_expr, re)?
@ -1283,7 +1281,7 @@ impl<'a> Parser<'a> {
.then_some(self.prev_token.span);
let bound = if self.check_inline_const(0) {
self.parse_const_block(self.token.span)
self.parse_const_block(self.token.span, true)
} else if self.check_path() {
let lo = self.token.span;
let (qself, path) = if self.eat_lt() {

View file

@ -4,63 +4,63 @@
fn main() {
match 1 {
const { 1 + 7 } => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
2 => {}
_ => {}
}
match 5 {
const { 1 } ..= 10 => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
1 ..= const { 10 } => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
const { 1 } ..= const { 10 } => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~| ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
//~| ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
const { 1 } .. 10 => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
1 .. const { 10 } => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
const { 1 + 2 } ..= 10 => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
1 ..= const { 5 + 5 } => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
const { 3 } .. => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
match 5 {
..= const { 7 } => {}
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR const blocks cannot be used as patterns
_ => {}
}
}

View file

@ -1,88 +1,88 @@
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:6:9
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:6:15
|
LL | const { 1 + 7 } => {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:13:9
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:13:15
|
LL | const { 1 } ..= 10 => {}
| ^^^^^^^^^^^
| ^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:19:15
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:19:21
|
LL | 1 ..= const { 10 } => {}
| ^^^^^^^^^^^^
| ^^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:25:9
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:25:15
|
LL | const { 1 } ..= const { 10 } => {}
| ^^^^^^^^^^^
| ^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:25:25
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:25:31
|
LL | const { 1 } ..= const { 10 } => {}
| ^^^^^^^^^^^^
| ^^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:32:9
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:32:15
|
LL | const { 1 } .. 10 => {}
| ^^^^^^^^^^^
| ^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:38:14
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:38:20
|
LL | 1 .. const { 10 } => {}
| ^^^^^^^^^^^^
| ^^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:44:9
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:44:15
|
LL | const { 1 + 2 } ..= 10 => {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:50:15
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:50:21
|
LL | 1 ..= const { 5 + 5 } => {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:56:9
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:56:15
|
LL | const { 3 } .. => {}
| ^^^^^^^^^^^
| ^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: arbitrary expressions aren't allowed in patterns
--> $DIR/in-pat-recovery.rs:62:13
error: const blocks cannot be used as patterns
--> $DIR/in-pat-recovery.rs:62:19
|
LL | ..= const { 7 } => {}
| ^^^^^^^^^^^
| ^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead

View file

@ -0,0 +1,12 @@
//! Regression test for <https://github.com/rust-lang/rust/issues/152499>: reject inline const
//! patterns pre-expansion when possible.
macro_rules! analyze { ($p:pat) => {}; }
analyze!(const { 0 });
//~^ ERROR: const blocks cannot be used as patterns
#[cfg(false)]
fn scope() { let const { 0 }; }
//~^ ERROR: const blocks cannot be used as patterns
fn main() {}

View file

@ -0,0 +1,18 @@
error: const blocks cannot be used as patterns
--> $DIR/reject-const-block-pat-pre-expansion.rs:9:24
|
LL | fn scope() { let const { 0 }; }
| ^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: const blocks cannot be used as patterns
--> $DIR/reject-const-block-pat-pre-expansion.rs:5:16
|
LL | analyze!(const { 0 });
| ^^^^^
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
error: aborting due to 2 previous errors