Specify in Rust that a generic type supports coercion to a primitive type

90 views Asked by At

In Rust, I have several different enums that are all #[repr(u32)], meaning I can use as to cast them to a u32:

#[repr(u32)]
enum Foo {A, B, C}

fn f(foo: Foo) {
    dbg!(foo as u32);
}

Now I want to write a generic function that can take any of those enums:

fn f<T>(t: T) {
    dbg!(t as u32);
}

But I can't, because Rust doesn't know that T supports that coercion:

an as expression can only be used to convert between primitive types or to coerce to a specific trait object

I tried marking T as Into<u32>, but it's not, and I can't even easily implement it because the enums are coming from another crate. The best I can come up with is defining and implementing a new trait just for this, along the lines of:

#[repr(u32)]
#[derive(Clone, Copy)]
enum Foo {A, B, C}

trait Argh: Copy {
    fn to_u32(&self) -> u32;
}

impl Argh for Foo {
    fn to_u32(&self) -> u32 {
        *self as u32
    }
}

fn f<T: Argh>(t: T) {
    dbg!(t.to_u32());
}

But this makes me very sad. Is there some type specifier I can put on T to tell Rust that T as u32 is valid?

0

There are 0 answers