-1

Send is a marker trait, and does not have any impact on memory layout. That said, the mechanics of the Any type remain slightly mysterious to me.

Is the following code sound and does it do what I want: the cast type will always downcast correctly to the original concrete type:

let what_i_have: Box<dyn Any + Send> = Box::new(69);
let ptr = Box::into_raw(what_i_have);
let what_i_want: Box<dyn Any> = unsafe { Box::from_raw(ptr as *mut dyn Any) };

I've played around with this, and it "seems to work fine". Is it?

As a bonus question, can I do this without the unsafe block?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
cmyr
  • 2,235
  • 21
  • 30

1 Answers1

4

Yes, you can do this safely by assigning the value:

use std::any::Any;

fn main() {
    let what_i_have: Box<dyn Any + Send> = Box::new(69);
    let what_i_want: Box<dyn Any> = what_i_have;
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • great, thanks, for some reason I assumed the casting would have to happen "inside" the box? – cmyr Jan 28 '20 at 16:29
  • 1
    @cmyr I think [`CoerceUnsized`](https://doc.rust-lang.org/nightly/std/ops/trait.CoerceUnsized.html) is the magic trick that allows such coercions to work. ([`Box` implements `CoerceUnsized>`](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=facb415279ab73a6a08f82ef48d846b0).) – Francis Gagné Jan 28 '20 at 17:30
  • Yep. I’ve been trying to find reasonable links that discuss that trait to add to the “see also” – Shepmaster Jan 28 '20 at 17:34