I'm trying to make the impl AsRef<[u8; 3]>
to work in function parameters.
Playgrounds repro: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e99007b0571ed2f088b3e38a6692ccdf
Here is the MPE:
fn print_bytes_3(bytes: impl AsRef<[u8; 3]>)
{
println!("{:?}", bytes.as_ref());
}
pub fn main() {
let a: [u8; 3] = [1, 2, 3];
print_bytes_3(a);
}
Above code fails to compile with this error message:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `[u8; 3]: AsRef<[u8; 3]>` is not satisfied
--> src/main.rs:8:19
|
8 | print_bytes_3(a);
| ------------- ^ the trait `AsRef<[u8; 3]>` is not implemented for `[u8; 3]`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `AsRef<T>`:
[T; N]
[T]
note: required by a bound in `print_bytes_3`
--> src/main.rs:1:30
|
1 | fn print_bytes_3(bytes: impl AsRef<[u8; 3]>)
| ^^^^^^^^^^^^^^ required by this bound in `print_bytes_3`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
AsRef
documentation writes that the trait implements for a generic fixed-size array:
impl<T, const N: usize> AsRef<[T]> for [T; N]
If I'm understanding it correctly, it seems the compiler fails to determine which implementation of AsRef
to use.
Following the error message, it's conflicting with other trait implementation, which is impl<T> AsRef<[T]> for [T]
:
= help: the following other types implement trait `AsRef<T>`:
[T; N]
[T]
After some tweaks, this code works:
fn print_bytes_3(bytes: &[u8; 3])
{
println!("{:?}", bytes);
}
pub fn main() {
let a: [u8; 3] = [1, 2, 3];
print_bytes_3(&a);
}
However, I still want to take advantage of what AsRef
gives: impl AsRef<[u8; 3]>
in my function parameter as it can accept both owned and borrowed type without specifying &
.
Is there a way to resolve this ambiguity that the compiler cannot determine? Or let me know if I'm doing something wrong (I'm new to Rust).
The problem is that you want a
&[u8;3]
but the implementationAsRef<[u8;3]>
does not exist for arrays, you're pointing to theAsRef<[u8]>
definition instead. Your code runs if you just remove the;3
from your function declaration:If you want to take only a fixed size you should just take an array, if their elements implement
Copy
so does the array: