Stable rust: specialize generics

In stable rust, is there a way to 'specialize' a trait impl?

I.e. I want a standard piece of code for [T; N], but I want a special path for [u8; N] and [i8; N] and [i16; N], and [u16; N]

If you add T: 'static you could use TypeId. If it's only about the size you can use mem::size_of.

Does this dispatch at runtime or compile time? This is part of serialization routine, and I'd prefer it dispatch at compile time.

The former is not yet stably const, the latter is. But I'd expect them to optimize like const branches either way due to optimizations.

After monomorphization and barely any inlining, for a TypeId check the optimizer essentially ends up seeing

fn do_thing::<[i8; 8]>(…) {
    if 0x8c5f36fd29e019646a2d37bc7143a725 == 0x8c5f36fd29e019646a2d37bc7143a725 {
        // do thing for [i8; 8]
    } else {
        // do thing for general case
    }
}

For effectively all intents and purposes, you can assume that the other branch will be optimized out. The type id (and size, for T: Sized types) is known at compile time and there's no reason for the compiler to fail to keep track of this unless you start introducing dynamic things with the TypeId and/or dyn Any.

Strictly speaking, the compiler is free to polymorphize most generics to do this if it really wanted to. It's never going to because that would go against the compiler's goals, but there are no guarantees about performance or not doing any benign redundant effort.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.