rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.35k stars 12.59k forks source link

Incorrect / Inconsistent behavior of deref coercion with {} #23014

Open theemathas opened 9 years ago

theemathas commented 9 years ago

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)});
}

playpen

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.

steveklabnik commented 9 years ago

Whoah, &{}? I haven't seen that, though I guess it makes some degree of sense...

steveklabnik commented 8 years ago

Triage; no change.

jturner314 commented 6 years ago

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.

Spoonbender commented 2 years ago

Triage: issue still reproduces on 2021 edition, tested on rustc 1.59.0 (9d1b2106e 2022-02-23)

theemathas commented 2 years ago

Related or duplicate of #26978, apparently.

pwnorbitals commented 2 years ago

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)

Noratrieb commented 4 months ago

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 things