2

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
  • 388,571
  • 95
  • 1,107
  • 1,366
Daniel Fath
  • 16,453
  • 7
  • 47
  • 82
  • Can you explain why you say "but that doesn't seem to be the case"? Otherwise, the proposed duplicate seems to answer all of your questions. – Shepmaster Apr 11 '17 at 12:18
  • Deref coercion may be a confusing mechanism. Calling it shenanigans sounds like you are underestimating it. :P – E_net4 Apr 11 '17 at 13:41
  • @Shepmaster I've looked into Slice, Array, Deref doesn't list the coercion. Where exactly is it listed? – Daniel Fath Apr 11 '17 at 14:00
  • @DanielFath The answer to the duplicate states this, verbatim: "1. where something expects a &[T] and you give it a &[T; n] it will coerce silently;" – E_net4 Apr 11 '17 at 14:17
  • 1
    @E_net4, assuming kennytm is right (and RustNomicon is correct), the right answer is Unsize coercion, *not* Deref coercion. – Daniel Fath Apr 11 '17 at 14:30

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
  • 388,571
  • 95
  • 1,107
  • 1,366
Daniel Fath
  • 16,453
  • 7
  • 47
  • 82