Getting the "base" type of an array


#1

Suppose I want a “pair” type generic over a fixed-length array and its primitive value type, e.g. something like:

use std::ops::Deref;

enum Test<IntT, ArrayT>
where ArrayT: Deref<Target=[IntT]>
{
    A(IntT, ArrayT),
}
 

fn main() {
    // should work (doesn't work)
    let test_good = Test::A(5u8, [10u8, 20u8]);
    
    // should fail
    let test_bad = Test::A(5u32, [10u8, 20u8]);

    //  actual use-case: get type inference correctly for the unspecified literal
        let test_use = Test::A(5, [10u8, 20u8]); // interpret 5 as u8
}

Is there any (stable) way of doing this? Given the definition of the Deref trait I thought this would work, since &[type; N] coerces to &[type], but the compiler’s error messages say otherwise.


#2

It should work if you change your type bound to ArrayT: AsRef<[T]>.


#3

Well that was embarrassingly simple, thanks for setting me straight!


#4

Though I don’t expect to be handling this scenario, what if my array exceeds 32 elements?


#5

You can use a Vec (if allocating isn’t a problem) or a slice (if you’re fine with borrowing).

If you need arrays, your SOL until we get type-level constants. Here’s the latest RFC if you’re interested:


#6

That’s what I thought – I’m trying to expose as much compile-time information as I can for optimizations, which is the only reason I haven’t just used a Vec. With that said, my particular application’s run-time would probably exceed the heat-death of the universe with much more than 32 elements :slight_smile:, so I’m not too worried. I am eagerly awaiting const generics though.