2

I have two Rust traits, and one automatically implements the other:

trait A {
  fn something(&self);
}
trait B {}
impl A for dyn B {
  fn something(&self) {
    println!("hello from B")
  }
}

Now I receive a dynamic implementation of B, and I need to return a dynamic implementation of A:

fn downcast(b: Box<dyn B>) -> Box<dyn A> {...}

How can I implement downcast?

Some things I've tried:

  1. I tried to let Rust figure it out statically:
fn downcast(b: Box<dyn B>) -> Box<dyn A> {
  b
}

This gives something like

error[E0308]: mismatched types
expected trait `A`, found trait `B`
  1. I tried the same static thing using as or an intermediate variable.

  2. I tried dynamically casting using Any and downcast_ref, but I couldn't get the magic right.

mwlon
  • 798
  • 5
  • 19
  • Do you actually need a `Box` or would `&dyn A` be acceptable? – loganfsmyth Aug 20 '21 at 01:46
  • Don't think its possible, but you can add a `downcast` method to `B` that returns `self as &dyn A`. – Colonel Thirty Two Aug 20 '21 at 01:46
  • 2
    Question was closed, but here's a possible solution: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=44a12f2bfd6ebcf2fcc36912b7c50915. If you can make `Box` implement your trait, then an extra layer of indirection will save you. I'll post it as an answer if my reopen vote goes through. – Silvio Mayolo Aug 20 '21 at 01:57
  • Tl;dr the dupe: `Box` does not contain a pointer to the vtable of `dyn A`. – trent Aug 20 '21 at 01:57
  • Also see https://stackoverflow.com/questions/28632968/why-doesnt-rust-support-trait-object-upcasting for the case where `A` is a supertrait of `B` (note this is properly upcasting, not downcasting) – trent Aug 20 '21 at 02:04

0 Answers0