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

Add projection utilities to Yoke #833

Merged
merged 17 commits into from
Jul 2, 2021

Conversation

Manishearth
Copy link
Member

Fixes #829

Discovered another compiler bug in the process 🙃 (rust-lang/rust#86702)

I also figured out a better workaround for rust-lang/rust#84937 and used it here: there's a separate version of this function with explicit capturing that can be used until we can use closures here.

Fallible try_ versions of this can be added if necessary.

@Manishearth Manishearth requested a review from a team as a code owner June 28, 2021 21:58
@Manishearth Manishearth requested a review from sffc June 28, 2021 21:58
@Manishearth
Copy link
Member Author

The ICE is due to rust-lang/rust#86703 .

utils/yoke/src/yoke.rs Outdated Show resolved Hide resolved
utils/yoke/src/yoke.rs Outdated Show resolved Hide resolved
utils/yoke/src/yoke.rs Outdated Show resolved Hide resolved
utils/yoke/src/yoke.rs Outdated Show resolved Hide resolved
Comment on lines 586 to 588
/// - `P` ends up borrowing data from `Y` (or elsewhere) that did _not_ come from the cart,
/// for example `P` could borrow owned data from a `Cow`.
/// - Borrowed data from `Y` escapes with the wrong lifetime
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this list complete? I'm struggling to convince myself it is. Here's a proof sketch that feels right but which I'm not willing to bet on:

If Yoke<Y> is destroyed, it must not invalidate Yoke<P>. The yoked data will still be alive, because of CloneableCart, so it remains to check that we don't keep any of the underlying bookkeeping data that Y would be entitled to destroy. We can't hold onto any data that lives only for 'y (the lifetime of the Y object) so data owned by Y is out. So we can only copy data from Y, so it remains to check that copying non-'static data is ok, which reduces to checking if copying references is ok.

If the reference has the special for<'a> yoke lifetime, that means it's attached to the cart, so it can be copied, since it's the same yoke lifetime on both sides. If the reference has some other lifetime, like if we were converting Y<'static, 'b> -> P<'static>, then we can only copy it if P can express 'b separately from the yoke lifetime, since the borrowed content is not yoked.

Now, the part I'm not sure on is that I've referred to "the" yoke lifetime, but one could conceive of multiple yoke lifetimes being active simultaneously? Like can you wind up in a situation where you have something silly like

struct NestedYokeable<'y> {
  inner: Box<Yoke<NestedYokeable<'y>, Cart>>,
  ref: &'y i32,
}

Could you sneak yoked content intended for the outer yoke into the inner yoke, thus breaking the guarantee we otherwise get from CloneableCart? Can a value of this type even be constructed safely?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you sneak in other lifetimes they're like adding more existential parameters, essentially.

Note that the Yokeable used in a Yoke must be 'static, you can only sneak in other lifetimes via the cart. Yokes only have one "the" yoke lifetime because of Yokeable, all other lifetimes are in the cart and would constrain both sides in an acceptable way.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you could do

y.project(|y, _| y.inner.as_ref().clone())

but that's fine, since the lifetimes match up anyways (since you've cloned).

I think I'm pretty convinced this is correct. Huzzah.

mcy
mcy previously approved these changes Jun 29, 2021
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some bikeshedding.

utils/yoke/src/yoke.rs Show resolved Hide resolved
utils/yoke/src/yoke.rs Outdated Show resolved Hide resolved
@Manishearth Manishearth requested a review from sffc June 30, 2021 20:52
sffc
sffc previously approved these changes Jul 2, 2021
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! (Although we will need to fix the coverage CI before this is mergeable)

@Manishearth
Copy link
Member Author

Yeah the only fix is to ignore that doctest, which I did

@Manishearth Manishearth requested a review from sffc July 2, 2021 15:54
@codecov-commenter
Copy link

Codecov Report

Merging #833 (b2f2e84) into main (67bd340) will decrease coverage by 0.08%.
The diff coverage is 13.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #833      +/-   ##
==========================================
- Coverage   74.80%   74.71%   -0.09%     
==========================================
  Files         198      198              
  Lines       12762    12777      +15     
==========================================
  Hits         9546     9546              
- Misses       3216     3231      +15     
Impacted Files Coverage Δ
provider/core/src/data_provider/test.rs 88.68% <0.00%> (-1.23%) ⬇️
provider/core/src/hello_world.rs 76.56% <0.00%> (-3.77%) ⬇️
provider/core/src/marker/macros.rs 72.72% <0.00%> (-27.28%) ⬇️
utils/yoke/src/lib.rs 100.00% <ø> (ø)
utils/yoke/src/trait_hack.rs 0.00% <ø> (ø)
utils/yoke/src/yoke.rs 88.88% <ø> (ø)
utils/yoke/src/yokeable.rs 81.81% <ø> (ø)
utils/yoke/src/zero_copy_from.rs 88.23% <ø> (ø)
provider/core/src/serde.rs 44.44% <66.66%> (-2.62%) ⬇️
provider/core/src/dynutil.rs 38.88% <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 67bd340...b2f2e84. Read the comment docs.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 0660b94ac44c19e2bb9274e1eef7c053647cd2f4-PR-833

  • 2 of 15 (13.33%) changed or added relevant lines in 4 files are covered.
  • 2 unchanged lines in 1 file lost coverage.
  • Overall coverage decreased (-0.09%) to 74.789%

Changes Missing Coverage Covered Lines Changed/Added Lines %
provider/core/src/serde.rs 2 3 66.67%
provider/core/src/data_provider/test.rs 0 3 0.0%
provider/core/src/hello_world.rs 0 3 0.0%
provider/core/src/marker/macros.rs 0 6 0.0%
Files with Coverage Reduction New Missed Lines %
provider/core/src/serde.rs 2 44.44%
Totals Coverage Status
Change from base Build 67bd340dd7cb6e1a958ceb36f8f1d4e73c63742e: -0.09%
Covered Lines: 9674
Relevant Lines: 12935

💛 - Coveralls

@Manishearth Manishearth merged commit 0d428d3 into unicode-org:main Jul 2, 2021
@Manishearth Manishearth deleted the yoke-project branch July 2, 2021 16:12
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.

Add projection functions to Yoke
5 participants