This type of coercion is intended to work, but not implemented.
Arrays do not implement Deref , so the cast &[T; n] β &[T] &[T; n] β &[T] &[T; n] β &[T] &[T; n] β &[T] not a forced application and does not work the same as one. Instead, it is called "unregulated coercion" because it turns a dimensional type ( [T; n] ) into a non-standard type ( [T] ).
However, the language reference (which is not normative and may be outdated, but bear with me) lists possible coercive measures, including the following:
T_1 T_3 where T_1 leads to T_2 and T_2 T_3 to T_3 (transition case)
Please note that this is not yet fully supported.
&T to &U if T implements Deref<Target = U> .TyCtor ( T ) - TyCtor ( U ), where TyCtor ( T ) is one of
&T&mut T*const T*mut TBox<T>
and where T can be obtained from U using uneven coercion .
The last bullet, non-standard coercion, is what &[T; n] &[T; n] &[T; n] &[T; n] to force &[T] . Remarkably, this describes only one level of links; this does not apply to &&[T; n] &&[T; n] &&[T; n] &&[T; n] β &[T] case (for which we also need to force cast to Deref ).
Back to your inoperative example:
let arr: &[i32] = &&&[1, 2, 3, 4, 5];
Alleged coercion - &&&[i32; 5] &&&[i32; 5] &&&[i32; 5] &&&[i32; 5] β &[i32] . We can understand how this coercion should work:
&[i32; 5] &[i32; 5] &[i32; 5] &[i32; 5] forces &[i32] to size;&&[i32; 5] &&[i32; 5] &&[i32; 5] &&[i32; 5] forces to &[i32; 5] &[i32; 5] &[i32; 5] &[i32; 5] Deref ;- therefore,
&&[i32; 5] &&[i32; 5] &&[i32; 5] &&[i32; 5] leads to &[i32] transitivity . &&&[i32; 5] &&&[i32; 5] &&&[i32; 5] &&&[i32; 5] forces &&[i32; 5] &&[i32; 5] &&[i32; 5] &&[i32; 5] Deref ;- therefore,
&&&[i32; 5] &&&[i32; 5] &&&[i32; 5] &&&[i32; 5] leads to &[i32] transitivity .
But this is not so. The above quote hints at why: the transition case says: "Please note that this is not yet fully supported." As far as I can tell, according to issue No. 18602 , βnot fully supportedβ is a hedge; it would be more accurate to say "not implemented." So, at the moment, coercion through transitivity is generally impossible. Obviously, this problem is not a priority, perhaps because dimensional arrays are not very common. (I suspect this may become a more common complaint when constant generics land, as this may make arrays more useful.)
So why does arr.first() work? Well, the "auto-detection rules" used to find methods invoked with . (dot) operator is an extension of coercion rules. Autoderef is like manually dereferencing any number of times until you get something (which can be cast to) using this method. This means that you donβt need transitivity to search for method calls through autoderef (which RFC 401 calls "pushing").
further reading
RFC # 401 describes the alleged semantics of most coercions. This RFC was merged more than 4 years ago. Since then, much has changed, but it is still not fully implemented (tracking issue # 18469 ), so RFC 401 does not accurately describe any past, present or future version of Rust. However, RFC 401 also allows the use of &&&[i32; 5] &&&[i32; 5] &&&[i32; 5] &&&[i32; 5] to &[i32] and almost the same logic.
Rustonomicon also has a chapter on coercion and seems to agree with the guide.