4

Question about rust arrays (the constant size ones, [T, ..Size]). I am trying to make the following work:

#[deriving(PartialEq)]
struct Test {
  dats : [f32, ..16]
}

I know I could not use deriving and simply write my own PartialEq, but that is rather obnoxious... The error message that is given is also cryptic to me (see bellow). Is there a proper rustic way to do this?

rustc ar.rs 
ar.rs:4:3: 4:20 error: mismatched types: expected `&&[f32]` but found `&[f32, .. 16]` (expected &-ptr but found vector)
ar.rs:4   dat : [f32, ..16]
          ^~~~~~~~~~~~~~~~~
note: in expansion of #[deriving]
ar.rs:2:1: 3:7 note: expansion site
ar.rs:4:3: 4:20 error: mismatched types: expected `&&[f32]` but found `&[f32, .. 16]` (expected &-ptr but found vector)
ar.rs:4   dat : [f32, ..16]
          ^~~~~~~~~~~~~~~~~
note: in expansion of #[deriving]
ar.rs:2:1: 3:7 note: expansion site
error: aborting due to 2 previous error

I am on the rust nightly build from today.

Thanks!

luke
  • 1,024
  • 3
  • 11
  • 21
  • 2
    It's currently not possible to parameterize `Size`, so the compiler cannot derive any traits. You'll have to implement it yourself. – A.B. Jun 14 '14 at 17:23

1 Answers1

4

This is a bug: #7622 "Fixed-length arrays implement no traits". As A.B. said, there is no way to parameterise the length of a fixed-length array, so the only way to implement traits is to actually write them out:

impl PartialEq for [f32, .. 0] { ... }

impl PartialEq for [f32, .. 1] { ... }

impl PartialEq for [f32, .. 2] { ... }

impl PartialEq for [f32, .. 3] { ... }

// ...

(Of course this could be done with a macro: but it still isn't feasible to do all possible lengths for all possible traits.)

You'll need to implement the traits yourself without deriving, e.g.

struct Test { dats: [f32, .. 16] }

impl PartialEq for Test {
    fn eq(&self, other: &Test) -> bool {
        self.dats == other.dats
    }
}

fn main() {
    let a = Test { dats: [0.0, .. 16 ]};
    let b = Test { dats: [100.0, .. 16 ]};

    println!("{}", a == b);
}

You might think it strange that you can use == with [f32, .. 16] without it implementing PartialEq (which is how one overloads == for most types, like Test above): it works because the compiler has a built-in understanding of how == works with fixed length vectors and so uses that directly without touch the trait.

huon
  • 94,605
  • 21
  • 231
  • 225
  • Great! I would have never have guessed == would work. I was going to do a nasty for loop :(. – luke Jun 15 '14 at 14:11
  • What to do if array is longer than 30 (like, 64) `an implementation of 'std::cmp::PartialEq' might be missing for '[u32; 64]'` – kirhgoff Dec 19 '18 at 09:00
  • 1
    @kirhgoff the arrays can be coerced to slices `&self.dats[..] == &other.dats[..]`, e.g. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c91c2caba521931e954e8f6128dce13e – huon Dec 20 '18 at 01:55