Order of operands to equality expression matters when inferring a AsRef implementation
5d23c37
Opened by Jake Goulding at
This may be related to or the same as #23673, but I wanted to file it anyway as it seems to have a slightly different flavor.
#![feature(convert)]
struct Container {
i: u8,
b: bool,
}
impl AsRef<u8> for Container {
fn as_ref(&self) -> &u8 {
&self.i
}
}
// A second implementation to make the `as_ref` ambiguous without further information
impl AsRef<bool> for Container {
fn as_ref(&self) -> &bool {
&self.b
}
}
fn main() {
let c = Container { i: 42, b: true };
// Succeeds
&42u8 == c.as_ref();
// Fails
c.as_ref() == &42u8;
}
Fails with
type annotations required: cannot resolve `Container : core::convert::AsRef<_>` [E0283]
However, if you flip the order of the arguments to the equality operator, then the code compiles and the correct type is inferred. It seems as if both forms should work the same.
Originally from this Stack Overflow question
I've seen what (appears to be) a similar issue when trying to use
as_ref()in a pattern guard expression.Eliza Weisman at 2015-04-12 17:03:46
Still repros.
Brian Anderson at 2016-12-01 17:40:37
Triage: still reproduces
error[E0283]: type annotations needed for `Container` --> src/main.rs:28:7 | 22 | let c = Container { i: 42, b: true }; | - consider giving `c` a type ... 28 | c.as_ref() == &42u8; | ^^^^^^ cannot infer type for struct `Container` | = note: cannot resolve `Container: std::convert::AsRef<_>`Steve Klabnik at 2019-12-25 16:15:54