Consider the following code:
fn main() {
let foo = 1;
let bar: i32 = -&foo; //ok, -1
let baz: i32 = &foo; //error, expected `i32`, found `&{integer}`
let bad: i32 = !&foo; //ok, -2
}
Reading through the Rust Reference I found that
Possible coercion sites are:
- let statements where an explicit type is given.
[...]
- Arguments for function calls
So let baz: i32 = &foo;
should also work since it's a let statement with an explicit type given.
Why does it refuse to be compiled?
Cases 1 and 3 are not coercion but are just how those operators are defined. For instance,
// https://doc.rust-lang.org/std/primitive.i32.html#impl-Neg-for-%26i32
impl Neg for &i32
type Output = <i32 as Neg>::Output // this is i32
And so -&foo
has type i32
. It's the same for !&foo
. The type annotations on the bar
and bad
lines are doing nothing.
Meanwhile, line 2 is not a permitted coercion: nowhere in the list of coercions you linked does it say that &T
can be coerced to T
; doing so requires copying (dereferencing) or cloning.