Tracking issue for `const fn` integration with pattern matching
Centril opened this issue · 6 comments
Centril commented
Sub-tracking issue for rust-lang/rfcs#911.
This issue tracks integration of const fn
with pattern matching... For example:
#[derive(PartialEq, Eq)]
struct Foo { f: usize, g: usize }
const fn ZERO(x: usize) -> Foo { Foo { f: x, g: x } }
fn main() {
let f = Foo { f: 0, g: 1 };
match f {
ZERO(22) => println!("hi"),
_ => println!("1"),
}
}
This is currently not implemented:
error[E0532]: expected tuple struct/variant, found function `ZERO`
--> src/main.rs:11:9
|
11 | ZERO(22) => println!("hi"),
| ^^^^ not a tuple struct/variant
error: aborting due to previous error
RalfJung commented
rust-lang/rfcs#2920 by @ecstatic-morse suggests an alternative way of dealing with const
in patterns.
ecstatic-morse commented
rust-lang/rfcs#2920 would allow you to write the example in the OP with a few extra tokens.
fn main() {
let f = Foo { f: 0, g: 1 };
match f {
const { ZERO(22) } => println!("hi"), // <-
_ => println!("1"),
}
}
jieyouxu commented
The explicit requirement of a const { }
block seems to help clarify the intent (syntax bike-shedding):
- Just having
ZERO(22)
in the match arm suggests that we're trying to match a 1-tuple with an integer value22
, but really we're trying to match on the result of a CTFE. - By having the
const {}
block, it indicates to the reader that we're trying to force a CTFE.
fedinskiy commented
Another use case, which doesn't compile(error E0532) as of 1.47.0:
const Q: u8 = b'q';
const fn ctrl_key(key: u8) -> u8 {
key & 0x1f
}
const CTRL_Q: u8 = ctrl_key(Q);
fn main() {
let result: Option<u8> = read_byte_from_somewhere();
match result {
Some(Q) | Some(ctrl_key(Q)) => return,
Some(i) if i > 0 => println!("Read {} from somewhere", i),
_ => return,
}
}
Although, if Some(ctrl_key(Q))
is replaced with Some(CTRL_Q)
this example works as expected.
Nemo157 commented
joshtriplett commented
Closed in favor of RFC 2920 and const { ... }
blocks, tracked in #76001 .