rust icon indicating copy to clipboard operation
rust copied to clipboard

Reference to trivial block coerces more than reference to a value

Open QuineDot opened this issue 3 years ago • 2 comments
trafficstars

I tried this code:

use core::fmt::Debug;
fn foo(_: &Box<dyn Debug>) {}

fn main() {
    foo(&{ Box::new(()) });
    foo(&( Box::new(()) ));
    foo(&  Box::new(())  );
}

I expected to see this happen: The same behavior from all three calls to foo. Based on my reading of RFC 401 and the reference, all three should compile; but independent of that, it seems that all three should behave the same.

Instead, this happened: The first call coerces successfully while the other two fail.

error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): mismatched types
 --> src/main.rs:6:9
  |
6 |     foo(&( Box::new(()) ));
  |     --- ^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `()`
  |     |
  |     arguments to this function are incorrect
  |
  = note: expected reference `&Box<(dyn Debug + 'static)>`
             found reference `&Box<()>`
note: function defined here
 --> src/main.rs:2:4
  |
2 | fn foo(_: &Box<dyn Debug>) {}
  |    ^^^ ------------------

error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): mismatched types
 --> src/main.rs:7:9
  |
7 |     foo(&  Box::new(())  );
  |     --- ^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `()`
  |     |
  |     arguments to this function are incorrect
  |
  = note: expected reference `&Box<(dyn Debug + 'static)>`
             found reference `&Box<()>`
note: function defined here
 --> src/main.rs:2:4
  |
2 | fn foo(_: &Box<dyn Debug>) {}
  |    ^^^ ------------------

For more information about this error, try `rustc --explain E0308`.

Meta

Playground (stable 1.63.0, Beta version: 1.64.0-beta.7 (2022-09-16 b31188e88b245f48b364), Nightly version: 1.66.0-nightly (2022-09-17 98ad6a5519651af36e24)).

@rustbot label +A-coercions

QuineDot avatar Sep 18 '22 09:09 QuineDot

Based on my reading of RFC 401 and the reference, all three should compile

@steffahn pointed out that this can't actually happen (without impractical levels of magic); I'll try to file an issue against the reference if someone doesn't beat me to it.

The different behavior based on the presence of {} is still surprising, but can probably also be considered an incorrect or incomplete documentation issue; I'll probably close this unless there is some indication that something deeper is actually going on. (There are a number of issues open around blocks influencing Deref coercion that I thought might be related.)

QuineDot avatar Sep 18 '22 12:09 QuineDot

I’ve added a short comment to an existing issue #1258; but feel free to open a new one if you think that’s more useful.

steffahn avatar Sep 18 '22 12:09 steffahn