Почему это принудительное приведение к сбою завершается неудачно, когда выражение помещается в блок? - PullRequest
0 голосов
/ 24 декабря 2018

String реализует Deref<Target = str>, что означает, что компилируется следующий код:

fn save(who: &str) {
    println!("I'll save you, {}!", who);
}

save(&String::from("Madoka"));

Если я создаю пользовательский тип, который также реализует Deref<Target = str>, то это тоже работает:

struct Madoka;

impl Deref for Madoka {
    type Target = str;
    fn deref(&self) -> &Self::Target {
        "Madoka"
    }
}

save(&Madoka);

Теперь давайте попробуем привести к другому типу - скажем, u32.Кажется, это также работает:

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

struct Homura;

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

reset(&Homura);

Но когда я заключаю выражение в блок, оно больше не компилируется:

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`

Странно то, что эквивалентвыражение с &str прекрасно компилируется:

save(&{ Madoka });  // OK

Почему первое выражение не компилируется, а второе успешно?

Playground

...