use std::ops::Deref;
pub struct B;
impl B {
fn foo(&self) -> &Self {
&*self
}
}
impl Deref for B {
type Target = i32;
fn deref(&self) -> &Self::Target {
&1
}
}
pub fn bar(b: &B) {
let c: &i32 = b.foo(); // I expect this an error (type mismatch).
let d: &B = b.foo();
}
What you are seeing here is deref coercion. Because of the Deref
implementation, any &B
can be converted to a &i32
. The foo()
function is something of a red herring, since it isn't directly interacting with the coercion, and a similar effect can be seen with the following code:
let a: &i32 = &B;
All that is happening in your example is that the coercion above is being applied to the return value of foo()
.
3 Likes
Note that if you don't want deref coercion then a trait like AsRef
might be more appropriate, or even just a normal function if it's not meaningful to use it generically.
2 Likes