Skip to content

Deref coercions don't work on blocks when the target is sized #57749

Open
@lambda-fairy

Description

@lambda-fairy

As seen on StackOverflow.

Consider the following code:

use std::ops::Deref;

fn main() {
    fn save(who: &str) {
        println!("I'll save you, {}!", who);
    }
    
    struct Madoka;
    
    impl Deref for Madoka {
        type Target = str;
        fn deref(&self) -> &Self::Target {
            "Madoka"
        }
    }
    
    save(&{ Madoka });

    fn reset(how: &u32) {
        println!("Reset {} times", how);
    }

    struct Homura;

    impl Deref for Homura {
        type Target = u32;
        fn deref(&self) -> &Self::Target {
            &42
        }
    }

    // Uncomment this to get a type error
    // reset(&{ Homura });
}

The following expressions do compile:

  • reset(&Homura)
  • reset(&&{ Homura })
  • reset({ &Homura })

But this doesn't:

  • reset(&{ Homura })
error[E0308]: mismatched types
  --> src/main.rs:17:14
   |
17 |     reset(&{ Homura });
   |              ^^^^^^ expected u32, found struct `main::Homura`
   |
   = note: expected type `u32`
              found type `main::Homura`

Is there are particular reason for this discrepancy?

I found two similar issues #26978 and #32122 but they don't seem to cover this particular case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coercionsArea: implicit and explicit `expr as Type` coercionsC-bugCategory: This is a bug.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions