I'm using the new generic conversion traits in my code and experience reduced ergonomics. The code in question implements AsRef<str> for [Ascii] as you can see in the example.
Now I want to use v.as_ref() in assert_eq!() and expect that v.as_ref() returns a &str using the provided implementation because the second argument to assert_eq!() is of type &str.
There is no implementation of AsRef<String> for [Ascii] so in my opinion only one implementation of PartialEq comes into play: PartialEq<str> for &str.
The compiler doesn't follow my explanation and complains about required type annotations. How can I avoid the explicit annotation and why can't the compiler figure out the correct implementation of AsRef<_>?
Thanks
#![feature(convert)]
struct Ascii { chr: u8 }
impl AsRef<str> for [Ascii] {
fn as_ref(&self) -> &str {
unsafe { ::std::mem::transmute(self) }
}
}
fn main() {
let v = [Ascii { chr: 65 }, Ascii { chr: 66 }];
assert_eq!(v.as_ref(), "AB");
// Workaround: explicit type annotation.
//assert_eq!(AsRef::<str>::as_ref(&v[..]), "AB");
}
Playpen link: http://is.gd/ZcdqXZ
<anon>:15:18: 15:26 error: type annotations required:
cannot resolve `[Ascii] : core::convert::AsRef<_>` [E0283]
<anon>:15 assert_eq!(v.as_ref(), "AB");
^~~~~~~~
Look at the listed implementors of AsRef in the documentation in more detail and you find that there is another implementation that collides there: impl<T> AsRef<[T]> for [T]. So it can’t decide whether v.as_ref() should be of type &str or &[Ascii].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With