Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expected a slice, found an array when asserting they are equal

Tags:

types

slice

rust

I'm trying to assert that two slices are equal, but one of the slices is being interpreted as an array:

#[derive(Debug, PartialEq)]
enum Error {
    TooBig,
}

type Bytes = [u8];

struct Fixed {
    length: u32,
}

impl<'a> Fixed {
    pub fn new(length: u32) -> Fixed {
        Fixed { length: length }
    }

    pub fn length(&self) -> u32 {
        self.length
    }

    pub fn encode(&self, decoded: &'a Bytes) -> Result<&'a Bytes, Error> {
        if decoded.len() > self.length() as usize {
            Err(Error::TooBig)
        } else {
            Ok(&decoded)
        }
    }

    pub fn decode(&self, decoded: &'a Bytes) -> Result<&'a Bytes, Error> {
        if decoded.len() > self.length() as usize {
            Err(Error::TooBig)
        } else {
            Ok(&decoded)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn fixed_0() {
        let length = 0;
        let fixed = Fixed::new(length);
        let encoded = [];
        let decoded = [];
        assert_eq!(fixed.length(), length);
        assert_eq!(fixed.encode(&decoded), Ok(&encoded));
        assert_eq!(fixed.decode(&encoded), Ok(&decoded));
        assert_eq!(fixed.encode(&[1]), Err(Error::TooBig));
    }

    #[test]
    fn fixed_1() {
        let length = 1;
        let fixed = Fixed::new(length);
        let encoded: [u8; 1] = [1];
        let decoded: [u8; 1] = [1];
        assert_eq!(fixed.length(), length);
        assert_eq!(fixed.encode(&decoded).unwrap(), &encoded);
        assert_eq!(fixed.decode(&encoded).unwrap(), &decoded);
    }
}

gist

And here's my errors:

error[E0308]: mismatched types
  --> src/lib.rs:49:9
   |
49 |         assert_eq!(fixed.encode(&decoded), Ok(&encoded));
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice, found array of 0 elements
   |
   = note: expected type `std::result::Result<&[u8], Error>`
              found type `std::result::Result<&[_; 0], _>`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0308]: mismatched types
  --> src/lib.rs:50:9
   |
50 |         assert_eq!(fixed.decode(&encoded), Ok(&decoded));
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice, found array of 0 elements
   |
   = note: expected type `std::result::Result<&[u8], Error>`
              found type `std::result::Result<&[u8; 0], _>`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

My reading of the docs leads me to believe that by using &, I should be creating a slice. What am I missing?

like image 858
Aakil Fernandes Avatar asked Nov 02 '18 21:11

Aakil Fernandes


1 Answers

Your example can be reduced:

fn example(input: Result<&[u8], ()>) {
    assert_eq!(input, Ok(&[]));
}

A reference to an array is a reference to an array, not a slice. In many contexts, a reference to an array may be coerced to a slice, but not everywhere. This is a case where it cannot.

Use more explicit slicing syntax instead:

assert_eq!(input, Ok(&[][..]));

See also:

  • assert_eq!(a,b) fails to compile for slices while assert!(a == b) works fine
  • What's the most idiomatic way to test two Options for equality when they contain values which can be tested for equality?
  • How does comparison of a slice with an array work in Rust?
like image 150
Shepmaster Avatar answered Oct 13 '22 01:10

Shepmaster