Incorrect / Inconsistent behavior of deref coercion with {}
In this code, the commented-out lines fail to compile.
struct Foo;
fn f(_: &Foo) {}
fn g(_: &&Foo) {}
fn main() {
let x: &Foo = &Box::new(Foo);
f(x);
f(&Box::new(Foo));
f(&(Box::new(Foo)));
//f(&{Box::new(Foo)});
let y: &Foo = &Box::new(Foo);
g(&y);
//g(&&Box::new(Foo));
//g(&(&Box::new(Foo)));
g(&{&Box::new(Foo)});
}
I believe that, among other things, f(&{Box::new(Foo)}); should compile since &{Box::new(Foo)} has type &Box<Foo>, which is deref-coercible to &Foo.
Additionally, the behavior is so inconsistent that it is basically impossible to predict whether the other lines will compile without trying them.
Whoah,
&{}? I haven't seen that, though I guess it makes some degree of sense...Steve Klabnik at 2015-03-04 21:37:15
Triage; no change.
Steve Klabnik at 2016-03-24 21:20:18
I came across this today while writing a macro. Until this bug gets fixed, if you're in a situation where you need deref coercion of
&{ expr }to work correctly, a workaround is to add an extra
&*, like this:&*&{ expr }which will then coerce correctly.
Jim Turner at 2017-12-06 21:54:38
Triage: issue still reproduces on 2021 edition, tested on
rustc 1.59.0 (9d1b2106e 2022-02-23)Maayan Hanin at 2022-03-21 12:12:28
Related or duplicate of #26978, apparently.
Tim (Theemathas) Chirananthavat at 2022-03-21 13:36:50
Got bitten by this today with
func(&mut unsafe { *(ptr as *mut _) }), struggling to understand why a move was triggered. Needed to unnecessarily expand the unsafe block (not too bad but this was surprising)Chris de Claverie at 2022-05-25 12:14:37
quoting @compiler-errors about the first example:
it has to do with how "expectations" are propagated around blocks and how we derive expectations due to
&operators https://github.com/rust-lang/rust/blob/ef15976387ad9c1cdceaabf469e0cf35f5852f6d/compiler/rustc_hir_typeck/src/expr.rs#L428 fixing this will liekly unfortunately break other thingsnora at 2024-05-11 06:27:05