Why do I need to a reference to a reference

I've defined a very simple trait, which allows me to read from a byte slice into anything which implements the Sized trait.

Here's the definition:

/// Allows data from an slice of bytes to be parsed to anything which implements the `Sized` trait.
pub trait FromSized: Sized {
    /// Read Self from data.
    fn read_from(data: &[u8]) -> Self;

I have implemented if, for a u16 instance.

/// Implement the `FromSized` trait for `u16`.
/// This allows us to read a `u16` from a slice of bytes.
impl FromSized for u16 {
    fn read_from(data: &[u8]) -> u16 {
        (data[0] as u16) << 8 | data[1] as u16

But, the following test doesn't work:

/// QA: Verify that the code in this file is implemented correctly.
mod tests {
    use super::*;

    fn read_u16() {
        // ARRANGE.
        let data: &[u8] = &[0x00, 0x00, 0x00, 0x00];

        // ACT.
        let result: u16 = u16::read_from(data[0..2]);

It produces the following error.

68 |         let result: u16 = u16::read_from(data[0..2]);
   |                                          ^^^^^^^^^^
   |                                          |
   |                                          expected `&[u8]`, found slice `[u8]`
   |                                          help: consider borrowing here: `&data[0..2]`

Can someone explain this?
The variable data is already defined as a reference let data: &[u8] = &[0x00, 0x00, 0x00, 0x00];, but yet the function want me to pass in &data[0..2].

Why is this?

data is &[u8], that's correct. But data[0..2] is not &[u8] - it's [u8], that is, not a reference, but a blob of bytes itself.

1 Like

That makes sense. Thanks for the explanation.