2

I have a library that needs things to implement a specific trait (TQDispatch).

In my main project I have a vector of objects that all implement a different trait (Device) which I need for dynamic dispatch.

The device trait is declared

pub trait Device: TQDispatch{..}

My expectation is that I can take an item from the list of Device implementers and get at its TQDispatch-ness so that I can pass it to the library. Given that anything that implements Device also implements TQDispatch, this seems like it should be possible.

I can cast the original 'real' object to either, but I cannot find how to cast between the two traits.

Clarification: These are Arc<dyn Device> in my project vector and I need them to be Arc<dyn TQDispatch> for the library.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
pm100
  • 48,078
  • 23
  • 82
  • 145
  • Perhaps take a look at [this](https://users.rust-lang.org/t/casting-traitobject-to-super-trait/33524) – Gurwinder Singh Aug 24 '20 at 06:46
  • [Here a simple sample](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f0f4e9c85bbdf7089a00530e6dc03cff) – Gurwinder Singh Aug 24 '20 at 06:53
  • 1
    [The top answer to the other question applied here](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=88e561769deb807e054420768439794e). You can do a little better on nightly with [specialization](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9a2c31b7a5dd05e1f943ebd61e87f146). It's not impossible that [built-in supertrait coercions](https://github.com/rust-lang/rust/pull/60900) will be implemented in the future, but I wouldn't personally hold my breath for it. – trent Aug 24 '20 at 14:01
  • 1
    @trentcl can you get something to work with `min_specialization`? The full `specialization` feature is unlikely to be stable any time soon. – Peter Hall Aug 24 '20 at 14:49
  • @PeterHall Hmm... I don't really understand `min_specialization`. For that matter, I don't really understand `specialization`, either -- I thought the `default` was required but I guess it isn't? [Removing `default` and changing the feature name seems to work](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=c396a0434f283d3fc97cf1fd3cff2d7c), but only when the upcasting method is the only thing in the trait (which probably makes this not very useful). – trent Aug 24 '20 at 15:04

1 Answers1

1

I can cast the original 'real' object to either, but I cannot find how to cast between the 2 traits.

You need to implement an explicit conversion in the "sub-trait".

Rust is not an inheritance-based language, so

pub trait Device: TQDispatch{..}

means "Device requires TQDispatch", not "Device extends TQDispatch".

If you want an Arc output, you will also need to create a brand new Arc for that, because dyn Device and dyn TQDispatch are different values entirely.

Masklinn
  • 34,759
  • 3
  • 38
  • 57