Experimentation with trait objects in Yoke #743
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
See #667
As discussed, I need a way to deal with trait objects in Yoke. There are two trait objects I care about right now:
dyn ErasedDataStruct + 'static
dyn SerdeSeDataStruct<'s> + 's
However, since
Yokeable
requiresSized
, one cannot simply put the trait object as theY
type parameter inYokeable
.Based on some discussions with @Manishearth, as well as additional experimentation, here's what I came up with.
First, we need a
Sized
type to represent the trait (sayR
). We could use plain&dyn R
, and we getYokeable
for free thanks to the auto-impl, but this approach does not allow us to set the lifetime parameter ofR
(needed forSerdeSeDataStruct<'s>
). I considered writing a general trait object wrapping struct, but this was too hard for the type system to figure out. So, I ended up writing a custom wrapper struct for each trait. I think this is fine, and it will scale, since we already need to write some boilerplate to support the two existing trait objects.For example:
Second, we need a way to transform from a normal Yoke to a trait object Yoke. @Manishearth suggested making Yoke implement the trait itself, and then boxing up the Yoke as the Cart of another Yoke. I took this idea and expressed it as a new trait, which I'm calling
DynHelper
:With this helper trait, it is possible to transform from
Yoke<Y, C>
toYoke<RWrap, Box<dyn R>>
whereY: R
.I managed to get pretty much everything working. However, I'm still hitting rust-lang/rust#85636. I tried one of the workarounds @Manishearth suggested, but haven't been able to get it to work with a trait that has its own type parameter, like
SerdeSeDataStruct<'s>
. Could you take a look? I left comments in the code to indicate what compiles and what doesn't compile.