I am curious why trait resolution fails in the below case. Is it that the From trait can only be invoked with a precise type, and &[u8;100]
is not quite &[u8]
? That's my presumption.
This type of behavior can be confusing when there is a lot of Rust advice out there to let automatic conversion do the work, e.g. from Rust by Example:
// Arrays can be automatically borrowed as slices println!("borrow the whole array as a slice"); analyze_slice(&xs);
Also the std::array
docs don't really help out the confused user:
Arrays coerce to slices (
[T]
), so a slice method may be called on an array. Indeed, this provides most of the API for working with arrays. Slices have a dynamic size and do not coerce to arrays.
This is made more confusing to me because there's no explicit conversion method from a std::array to a std::slice (something like Vec's to_slice
method). You have to do something "slicey enough", which just seems mysterious.
Any advice on how to explain this to a Rust newbie? Is there a clear way to write this code so a future reader could understand it best? Is &BYTES[..]
really the best way to make a [u8;X]
into a &[u8]
? If so, could rustc help out by recommending that in this situation?
Here's a concrete example of what I'm talking about.
use bytes; // 0.5.4
fn look_at_slice(slice: &[u8]) {
// empty
}
fn main() {
let BYTES = [0u8;100];
// automatic conversion to slice works here
look_at_slice(&BYTES);
// automatic conversion to slice fails.
bytes::BytesMut::from(&BYTES);
// "slicey enough" behavior fixes the method resolution
bytes::BytesMut::from(&BYTES[..]);
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `bytes::bytes_mut::BytesMut: std::convert::From<&[u8; 100]>` is not satisfied
--> src/main.rs:14:5
|
14 | bytes::BytesMut::from(&BYTES);
| ^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<&[u8; 100]>` is not implemented for `bytes::bytes_mut::BytesMut`
|
= help: the following implementations were found:
<bytes::bytes_mut::BytesMut as std::convert::From<&'a [u8]>>
<bytes::bytes_mut::BytesMut as std::convert::From<&'a str>>
= note: required by `std::convert::From::from`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.