Hi I am playing the following code on the rust playground. This code is one of my attempt to use const generic param to calculate factorial by recursion.
#![feature(generic_const_exprs)]
struct FactImpl<const N: usize>();
impl<const N: usize> FactImpl<N>
where [(); N-1]:
{
const fn fact(self: Self) -> usize {
let f: FactImpl<{N-1}> = FactImpl;
f.fact() * N
}
}
impl<> FactImpl<0> {
const fn fact(self: Self) -> usize {
1
}
}
fn main() {
let f: FactImpl<0> = FactImpl;
println!("{}", f.fact());
}
Errors:
Compiling playground v0.0.1 (/playground)
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
--> src/main.rs:1:12
|
1 | #![feature(generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0080]: evaluation of `FactImpl::<0>::{constant#0}` failed
--> src/main.rs:8:12
|
8 | where [(); N-1]:
| ^^^ attempt to compute `0_usize - 1_usize`, which would overflow
For more information about this error, try `rustc --explain E0080`.
warning: `playground` (bin "playground") generated 1 warning
error: could not compile `playground` (bin "playground") due to 1 previous error; 1 warning emitted
In the code above I want to calculate the factorial using const generic param and generic recursion. I have tried to change the order of two impl blocks, remove the first impl block that is with generic param. When I remove the first impl block and leave only impl<> FactImpl<0>
the code compiles.
My questions are:
- What is the reason for the compile error? Is it a feature of bug?
- In C++ we have SFINAE, does rust employ SFINAE in type inference? If no, could the code pass compilation if rust have SFINAE?
- How to fix this code in rust version 2021?