Is this just a current limitation or is there a technical reason? As generic functions get compiled to specialized code, I don’t see what should prevent it from working. It also works fine in the main
function.
Example (playground):
#![feature(associated_consts)]
trait HasNumber<T> {
const Number: usize;
}
enum One {}
enum Two {}
enum Foo {}
impl<T> HasNumber<One> for T {
const Number: usize = 1;
}
impl<T> HasNumber<Two> for T {
const Number: usize = 2;
}
fn use_number<T, H: HasNumber<T>>() {
let a: [u8; H::Number] = unsafe { ::std::mem::uninitialized() };
}
fn main() {
let a: [u8; <Foo as HasNumber<One>>::Number] = unsafe { ::std::mem::uninitialized() };
println!("{}", <Foo as HasNumber<One>>::Number);
println!("{}", <Foo as HasNumber<Two>>::Number);
}
Short answer: It's not implemented yet, since it's hard to get right. There's even an open RFC named "Constants that depend on type parameters in generic code" for it.
Long answer:
This used to be a compiler-bug that caused the compiler to crash. It was "fixed" by @quantheory in PR 25091 by making this an error instead of a crash. @quantheory commented that
I haven't been able to deal with the array size or recursion issues yet for associated consts, though my hope was that the change I made for range match patterns might help with array sizes, too.
@quantheory also notes that this will stay an error until something along the lines of RFC 1062 is merged. Comments on the RFC are always appreciated, as they might hilight forgotten use-cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With