Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test for type equality in Rust?

I need to test if two types are equal in const fn. Comparing the TypeId doesn't work:

#![feature(const_if_match)]
#![feature(const_fn)]
#![feature(const_type_id)]

const fn t<T1: 'static, T2: 'static>() -> bool{
    std::any::TypeId::of::<T1>() == std::any::TypeId::of::<T2>()
}

Error:

error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 --> src/lib.rs:5:8
  |
5 |     std::any::TypeId::of::<T1>()==std::any::TypeId::of::<T2>()
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Template specialization as in C++ does not work in Rust, as Rust doesn't have "templates specialization". So, is there any way to test for type equality in Rust?

like image 816
炸鱼薯条德里克 Avatar asked Feb 09 '20 15:02

炸鱼薯条德里克


1 Answers

If you're using Rust nightly (which it seems like you are), you can use the unstable specialization feature and some helper traits to do this:

#![feature(specialization)]

/// Are `T` and `U` are the same type?
pub const fn type_eq<T: ?Sized, U: ?Sized>() -> bool {
    // Helper trait. `VALUE` is false, except for the specialization of the
    // case where `T == U`.
    trait TypeEq<U: ?Sized> {
        const VALUE: bool;
    }

    // Default implementation.
    impl<T: ?Sized, U: ?Sized> TypeEq<U> for T {
        default const VALUE: bool = false;
    }

    // Specialization for `T == U`.
    impl<T: ?Sized> TypeEq<T> for T {
        const VALUE: bool = true;
    }

    <T as TypeEq<U>>::VALUE
}

Example in playground

like image 162
Frxstrem Avatar answered Oct 23 '22 13:10

Frxstrem