Search code examples
rusttrait-objectsassociated-const

Why doesn't Rust support trait objects with associated constants?


I know it's because of object safety:

Object safe traits can be the base trait of a trait object. A trait is object safe if it has the following qualities (defined in RFC 255):

  • ...
  • It must not have any associated constants.

But if an associated constant is declared with a specific value, why does Rust still not support it? Here is an example:

trait Trait {
    const A: i32 = 64;
}

fn fun(t: Box<dyn Trait>) -> bool {
    return  true;
}

I want to use a function to return a constant value, and deliberately omit the &self parameter, but it still doesn't work. Here is the code:

trait Trait {
    fn getA() -> i32 {
        64
    }
}

fn fun(t: Box<dyn Trait>) -> bool {
    return  true;
}

Is there a low level reason why Rust doesn't support it? Or is it just because of the RFC rules?


Solution

  • They aren't object-safe, because the constant value may differ for trait implementers:

    trait Foo {
        const A: i32 = 4;
    }
    
    impl Foo for bool {
        const A: i32 = 5;
    }
    

    Which value should (dyn Foo)::A produce?

    By using dyn Foo the original type is erased, and without a pointer/reference to a dyn Foo value there is no vtable that could be consulted. The same problem exists for a trait method without a self parameter.

    You need regular generics for this:

    trait Trait {
        const A: i32 = 64;
    }
    
    fn fun<T: Trait>(t: T) -> i32 {
        T::A
    }