1

How and why does Rust convert &[&u8; 2] to &[&u8] in this code? I thought originally it must be doing some kind of Deref shenanigans, but that doesn't seem to be the case.

struct Example<'a, 'b: 'a> {
    params: &'a [&'b u8],
}

fn main() {
    let a = 2u8;
    let b = 3u8;
    let x = &[&a, &b];
    let st = Example { params: x };
    println!(" Size of x: {} ", std::mem::size_of_val(&x));
    println!(" Size of &[&u8; 2]: {} ", std::mem::size_of::<&[&u8; 2]>());
    println!(" Size of Example: {} ", std::mem::size_of::<Example>());
}

// Console out:
// Size of x: 8
// Size of &[&u8; _]: 8
// Size of Example: 16

Playground

Shepmaster
  • 326,504
  • 69
  • 892
  • 1,159
Daniel Fath
  • 13,643
  • 6
  • 46
  • 76

1 Answers1

1

The answer I was looking for is CoerceUnsized.

Based on kennytm's answer and assuming the Rustnomicon is correct, &[&T; n] is coerced into &[T], using CoerceUnsized. The relevant parts:

Coercion is allowed between the following types:

  • Unsizing: T to U if T implements CoerceUnsized

CoerceUnsized<Pointer<U>> for Pointer<T> where T: Unsize<U> is implemented for all pointer types (including smart pointers like Box and Rc). Unsize is only implemented automatically, and enables the following transformations:

  • [T; n] => [T]
  • T => Trait where T: Trait
Shepmaster
  • 326,504
  • 69
  • 892
  • 1,159
Daniel Fath
  • 13,643
  • 6
  • 46
  • 76