Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimentation with trait objects in Yoke #743

Closed
wants to merge 7 commits into from

Conversation

sffc
Copy link
Member

@sffc sffc commented May 28, 2021

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 requires Sized, one cannot simply put the trait object as the Y type parameter in Yokeable.

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 (say R). We could use plain &dyn R, and we get Yokeable for free thanks to the auto-impl, but this approach does not allow us to set the lifetime parameter of R (needed for SerdeSeDataStruct<'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:

struct SerdeSeDataStructWrap<'a>(&'a dyn SerdeSeDataStruct<'a>);

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:

trait DynHelper {
    type Yokeable: for<'a> Yokeable<'a>;
    type Cart: StableDeref;

    fn attach<'de>(
        data: &'de <Self::Cart as Deref>::Target,
    ) -> <Self::Yokeable as Yokeable<'de>>::Output;

    fn make_cart(input: Box<Self>) -> Self::Cart;
}

With this helper trait, it is possible to transform from Yoke<Y, C> to Yoke<RWrap, Box<dyn R>> where Y: 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.

@sffc sffc requested a review from Manishearth May 28, 2021 06:07
@codecov-commenter
Copy link

Codecov Report

Merging #743 (223a1f2) into main (958ee68) will increase coverage by 0.06%.
The diff coverage is 90.90%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #743      +/-   ##
==========================================
+ Coverage   74.63%   74.69%   +0.06%     
==========================================
  Files         178      181       +3     
  Lines       10715    10765      +50     
==========================================
+ Hits         7997     8041      +44     
- Misses       2718     2724       +6     
Impacted Files Coverage Δ
utils/yoke/src/lib.rs 100.00% <ø> (ø)
utils/yoke/src/dyn_impls.rs 90.90% <90.90%> (ø)
experimental/provider_ppucd/src/parse_ppucd.rs 92.99% <0.00%> (-0.14%) ⬇️
utils/yoke/src/yokeable.rs 75.00% <0.00%> (ø)
utils/yoke/src/yoke.rs 100.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 958ee68...223a1f2. Read the comment docs.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 4a567d273e8be141de4b0894202e5a2b983f539b-PR-743

  • 30 of 33 (90.91%) changed or added relevant lines in 1 file are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+0.06%) to 74.787%

Changes Missing Coverage Covered Lines Changed/Added Lines %
utils/yoke/src/dyn_impls.rs 30 33 90.91%
Files with Coverage Reduction New Missed Lines %
experimental/provider_ppucd/src/parse_ppucd.rs 1 93.0%
Totals Coverage Status
Change from base Build 958ee68fa4f88fd740bb02927674871f1565dba2: 0.06%
Covered Lines: 8169
Relevant Lines: 10923

💛 - Coveralls

@sffc
Copy link
Member Author

sffc commented Jun 3, 2021

Subsumed by #745

@sffc sffc closed this Jun 3, 2021
@sffc sffc deleted the yoke-dyn branch June 3, 2021 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants