0

In Rust, why is this correct:

trait T {}
struct S;
impl T for S {}

let a = Box::new(S{});
let b: Box<dyn T> = a;

but this isn't:

let c = Some(Box::new(S{}));
let d: Option<Box<dyn T>> = c;

this isn't:

let e: Option<Box<dyn T>> = c.map(|x| x);

but then this is:

let d: Option<Box<dyn T>> = c.map(|x| x as _);

?

I'm trying to understand which language/compiler features dictate this behavior, and, especially, why adding as _ without any type changes it.

Michał Trybus
  • 11,526
  • 3
  • 30
  • 42
  • The feature you are seeking is called as coercion, what is happening here is called as [unsized coercion](https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md). It doesn't work for the `Option>` case because `CoerceUnsized` is [not implemented](https://doc.rust-lang.org/std/ops/trait.CoerceUnsized.html#implementors) for that. – Ömer Erden Nov 28 '22 at 11:30
  • @ÖmerErden yes, this SO question, specifically the answer https://stackoverflow.com/a/34982266/308392 explain why there is no *coersion* here, thanks. Perhaps I still need a while to digest why the closure return type is not inferred without `as _` in the second part of the question, but that's a separate topic. – Michał Trybus Nov 28 '22 at 12:04
  • Yes this is a good question but from a glance the difference I can see is: _[Type coercions](https://doc.rust-lang.org/reference/type-coercions.html) are implicit operations_ while `as` brings an explicit type conversion. Since `= c.map(|x| x);` is basically same with `= c`; I expect it shouldn't work already. But I am not sure as well, why it would work with explicit casting especially with wildcard. Please ping me if you can find an answer(note that this one also works `c.map(|x| -> Box { x })`) – Ömer Erden Nov 28 '22 at 12:56
  • My wild guess would be that `|x| x` is a closure generic over just one implicit type parameter (type of x), so is defined to return the same type as it takes. Perhaps somehow `as _` introduces explicit cast to some unknown type, introducing another implicit type parameter? – Michał Trybus Nov 28 '22 at 13:15

0 Answers0