String
implements Deref<Target = str>
, which means that the following code compiles:
fn save(who: &str) {
println!("I'll save you, {}!", who);
}
save(&String::from("Madoka"));
If I create a custom type that also implements Deref<Target = str>
, then that works too:
struct Madoka;
impl Deref for Madoka {
type Target = str;
fn deref(&self) -> &Self::Target {
"Madoka"
}
}
save(&Madoka);
Now, let's try coercing to another type -- say, u32
. It seems to work as well:
fn reset(how: &u32) {
println!("Reset {} times", how);
}
struct Homura;
impl Deref for Homura {
type Target = u32;
fn deref(&self) -> &Self::Target {
&42
}
}
reset(&Homura);
But when I wrap the expression in a block, it no longer compiles:
reset(&{ Homura });
error[E0308]: mismatched types
--> src/main.rs:17:14
|
17 | reset(&{ Homura });
| ^^^^^^ expected u32, found struct `main::Homura`
|
= note: expected type `u32`
found type `main::Homura`
The weird thing is that the equivalent expression with &str
compiles just fine:
save(&{ Madoka }); // OK
Why does the first expression fail to compile, but the second succeed?