Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can associated constants not depend on type parameters?

Tags:

rust

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);    
}
like image 402
Ferio Avatar asked Jun 08 '15 09:06

Ferio


1 Answers

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.

like image 90
oli_obk Avatar answered Sep 28 '22 10:09

oli_obk