Open
Description
Currently this compiles in stable.
struct Foo<T, const N: usize>(T);
impl<T, const N: usize> Foo<T, N> {
const BAR: () = if N == 0 {
panic!()
};
}
struct Invoke<T, const N: usize>(T);
impl<T, const N: usize> Invoke<T, N> {
const FUN: fn() = if N != 0 {
|| Foo::<T, N>::BAR
} else {
|| {}
};
}
fn main() {
Invoke::<(), 0>::FUN();
}
This is a useful property¹ but if the panic path were not completely excluded this could lead to monomorphization-time errors which are undesirable since they only show up in cargo build
and not in cargo check
. But not as undesirable as #107503 where the errors are optimization-dependent.
Still, @RalfJung indicated that the current behavior might not be intentional so I'm filing this issue for clarification.
(Also see rust-lang/rfcs#3582 for more discussion of the same question.)
¹actual use could look like this:
// library-provided function:
/// Fails to compile if N == 0
fn chunks<const N: usize>(foo: Foo) -> &[[u8; N]] {
const {
assert!(N > 0)!
}
todo!()
}
// user-code, generic over all N
fn library_user_code<const N: usize>(foo: Foo) -> {
// this could be generated by a `const_if!()` macro or use inline const blocks
struct ConstIf< const N: usize>;
impl<const N: usize> ConstIf<N> {
const FUN: fn() = if N != 0 {
|foo| chunks::<N>(foo)
} else {
|foo| { /* fallback code here */ }
};
}
ConstIf::<N>::FUN(foo)
}