4

It's well documented that [T; n] can coerce to [T]. The following code is also well-formed:

fn test(){
    let _a: &[i32] = &[1, 2, 3];
}

Here we have that &[T; n] is coerced to &[T].

Is it true that for all types T, U if T is coerced to U then &T is coerced to &U?

It's not documented in the reference (at least explicitly).

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Some Name
  • 8,555
  • 5
  • 27
  • 77

1 Answers1

5

No, because adding one more layer of & causes it to fail:

fn oops() {
    let a: &[i32; 3] = &[1, 2, 3];
    let _b: &&[i32] = &a;
}
error[E0308]: mismatched types
 --> src/lib.rs:8:23
  |
8 |     let _b: &&[i32] = &a;
  |             -------   ^^ expected slice `[i32]`, found array `[i32; 3]`
  |             |
  |             expected due to this
  |
  = note: expected reference `&&[i32]`
             found reference `&&[i32; 3]`

Further, it is not the case that [T; n] coerces to [T] in the same sense that &[T; n] coerces to &[T]. The documentation you linked describes the two traits related to unsized coercions: Unsize and CoerceUnsized. [T; n] implements Unsize<[T]>, and therefore &[T; n] implements CoerceUnsized<&[T]>; this is essentially the same thing, and your code effectively demonstrates both. It would not be possible to write a function that coerces [T; n] to [T] without using references (or pointers of some sort) because unsizing coercions only take place behind some kind of pointer.

trent
  • 25,033
  • 7
  • 51
  • 90
  • 3
    Essentially, an unsized coercion always converts some kind of _pointer_ into a _fat pointer_. The documentation is indeed somewhat confusingly worded and could be imporved. – Sven Marnach Aug 17 '20 at 20:15