Why cant `TypeId` equality be made `const`?

Why cant this function:

fn is_string<T: ?Sized + Any>() -> bool {
    TypeId::of::<String>() == TypeId::of::<T>()
}

be made const? The comparison is implemented in PartialEq::Eq. The types are known at compile time and consting will open up possibilities to write compile time constraints on templates.

I ultimately found a work around (but requires use of nightly intrinsics feature.)

const fn is_string<T: ?Sized + Any>() -> bool {
    core::intrinsics::type_id::<T>() == core::intrinsics::type_id::<String>()
}

The TypeId::t is a u128 value (comes from core::intrinsics::type_id::<T>()), so why not make the TypeId::as_u128 public? or better still allow conversion of TypeId::of::<T> as u128

(p.s. this is my 1st week with rust and just getting hang of things so sorry for if it's a noob question)

Here's a tracking issue for const type_id. It definitely would have been unsound before this was fixed about 16 months ago.

That's intentionally an implementation detail. It used to be u64 and it might be something larger or something less trivial, such as a symbol name or pointer to a symbol name, in the future. (Though unlikely, collisions are still possible, which is unsound.) From what I understand, limiting future compatibility is the main blocker now. E.g. there are const challenges if TypeId ends up containing a pointer.

Trait methods aren't const stable yet, and structural equality for TypeId was intentionally removed, so that's another blocker for that particular function. Here's the reasoning for the removal (forward compatibility again). There's a tracking issue for const comparisons of TypeId specifically, too.

5 Likes