Рассмотрим следующий код:
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
}
Прочитав Rust Reference, я обнаружил, что
Возможные места принуждения:
- Операторы let, в которых указан явный тип.
[...]
- Аргументы для вызовов функций
Так что let baz: i32 = &foo; тоже должно работать, поскольку это оператор let с явно заданным типом.
Почему он отказывается компилироваться?

Случаи 1 и 3 — это не принуждение, а просто определение этих операторов. Например,
// 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
Итак, у -&foo есть тип i32. То же самое и с !&foo. Аннотации типов в строках bar и bad ничего не делают.
Между тем, строка 2 не является разрешенным приведением: нигде в списке приведений, на которые вы ссылаетесь, не сказано, что &T можно принудить к T; для этого требуется копирование (разыменование) или клонирование.