-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Make VaListImpl<'f> invariant over the 'f lifetime #62639
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
Conversation
5ca1928
to
d84e340
Compare
@bors r+ |
📌 Commit d84e340 has been approved by |
Make VaListImpl<'f> invariant over the 'f lifetime After doing some research on variance and going back to look at `VaList` and `VaListImpl`, I realized that `VaList<'a, 'f>` is invariant over the `'f` lifetime (and covariant over `'a`), but `VaListImpl<'f>` isn't invariant but probably should be. This patch makes `VaListImpl<'f>` invariant over `'f`. r? @eddyb cc @dlrobertson
⌛ Testing commit d84e340 with merge b389cbb9c657ecc5c6810bbb432d266f58698318... |
💔 Test failed - checks-azure |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
d84e340
to
0c981e0
Compare
Fixed, the test needed a |
@bors r+ |
📌 Commit 0c981e0 has been approved by |
Make VaListImpl<'f> invariant over the 'f lifetime After doing some research on variance and going back to look at `VaList` and `VaListImpl`, I realized that `VaList<'a, 'f>` is invariant over the `'f` lifetime (and covariant over `'a`), but `VaListImpl<'f>` isn't invariant but probably should be. This patch makes `VaListImpl<'f>` invariant over `'f`. r? @eddyb cc @dlrobertson
Rollup of 14 pull requests Successful merges: - #62103 (Add debug assertions to write_bytes and copy*) - #62405 (Remove never_type feature requirement for exhaustive patterns) - #62491 (Fix Pin urls in Option documentation) - #62533 (Add missing links for CannotReallocInPlace type) - #62634 (Less unsafe in the array example of MaybeUninit docs) - #62639 (Make VaListImpl<'f> invariant over the 'f lifetime) - #62646 (Tweak wording in feature gate errors) - #62662 (add spaces in front of trait requirements in libcore/cell.rs) - #62668 (Fix #62660) - #62673 (miri validation: better error messages for dangling references) - #62680 (Actually call `visit_block_entry` in `DataflowResultsConsumer`) - #62685 (Add info about undefined behavior to as_ref suggestions) - #62689 (Fix typo in RawWaker::new documentation) - #62698 (SGX target: don't pretend to be GNU/Linux to LLVM) Failed merges: r? @ghost
@ahomescu nice work! |
…ubilee use `cfg_select!` to select the right `VaListImpl` definition tracking issue: rust-lang#44930 Just a bit of cleanup really. We could use `PhantomInvariantLifetime<'f>` (rust-lang#135806) to make it more precise what that `PhantomData<&'f mut &'f c_void>` marker is doing. I'm not sure how ready that feature is though, `@jhpratt` are these types good to use internally? --- Some research into the lifetimes of `VaList` and `VaListImpl`: It's easy to see why the lifetime of these types should not be extended, a `VaList` or `VaListImpl` escaping its function is a bad idea. I don't currently see why coercing the lifetime to a shorter lifetime is problematic though, but probably I just don't understand variance well enough to see it. The history does not provide much explanation: - immunant@0814087 original implementation - immunant@b9ea653 adds `VaListImpl<'f>`, but it is only covariant in `'f` - rust-lang#62639 makes `VaListImpl<'f>` invariant over `'f` (because `VaList<'a, 'f>` is already invariant over `'f`, but I think that is just an implementation detail?) Beyond that I don't see how the lifetime situation can be simplified significantly, e.g. this function really needs `'copy` to be unconstrained. ```rust /// Copies the `va_list` at the current location. pub unsafe fn with_copy<F, R>(&self, f: F) -> R where F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R, { let mut ap = self.clone(); let ret = f(ap.as_va_list()); // SAFETY: the caller must uphold the safety contract for `va_end`. unsafe { va_end(&mut ap); } ret } ``` `@rustbot` label +F-c_variadic r? `@workingjubilee`
Rollup merge of #141361 - folkertdev:varargs-cfg, r=workingjubilee use `cfg_select!` to select the right `VaListImpl` definition tracking issue: #44930 Just a bit of cleanup really. We could use `PhantomInvariantLifetime<'f>` (#135806) to make it more precise what that `PhantomData<&'f mut &'f c_void>` marker is doing. I'm not sure how ready that feature is though, `@jhpratt` are these types good to use internally? --- Some research into the lifetimes of `VaList` and `VaListImpl`: It's easy to see why the lifetime of these types should not be extended, a `VaList` or `VaListImpl` escaping its function is a bad idea. I don't currently see why coercing the lifetime to a shorter lifetime is problematic though, but probably I just don't understand variance well enough to see it. The history does not provide much explanation: - immunant@0814087 original implementation - immunant@b9ea653 adds `VaListImpl<'f>`, but it is only covariant in `'f` - #62639 makes `VaListImpl<'f>` invariant over `'f` (because `VaList<'a, 'f>` is already invariant over `'f`, but I think that is just an implementation detail?) Beyond that I don't see how the lifetime situation can be simplified significantly, e.g. this function really needs `'copy` to be unconstrained. ```rust /// Copies the `va_list` at the current location. pub unsafe fn with_copy<F, R>(&self, f: F) -> R where F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R, { let mut ap = self.clone(); let ret = f(ap.as_va_list()); // SAFETY: the caller must uphold the safety contract for `va_end`. unsafe { va_end(&mut ap); } ret } ``` `@rustbot` label +F-c_variadic r? `@workingjubilee`
…ubilee use `cfg_select!` to select the right `VaListImpl` definition tracking issue: rust-lang#44930 Just a bit of cleanup really. We could use `PhantomInvariantLifetime<'f>` (rust-lang#135806) to make it more precise what that `PhantomData<&'f mut &'f c_void>` marker is doing. I'm not sure how ready that feature is though, `@jhpratt` are these types good to use internally? --- Some research into the lifetimes of `VaList` and `VaListImpl`: It's easy to see why the lifetime of these types should not be extended, a `VaList` or `VaListImpl` escaping its function is a bad idea. I don't currently see why coercing the lifetime to a shorter lifetime is problematic though, but probably I just don't understand variance well enough to see it. The history does not provide much explanation: - immunant@0814087 original implementation - immunant@b9ea653 adds `VaListImpl<'f>`, but it is only covariant in `'f` - rust-lang#62639 makes `VaListImpl<'f>` invariant over `'f` (because `VaList<'a, 'f>` is already invariant over `'f`, but I think that is just an implementation detail?) Beyond that I don't see how the lifetime situation can be simplified significantly, e.g. this function really needs `'copy` to be unconstrained. ```rust /// Copies the `va_list` at the current location. pub unsafe fn with_copy<F, R>(&self, f: F) -> R where F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R, { let mut ap = self.clone(); let ret = f(ap.as_va_list()); // SAFETY: the caller must uphold the safety contract for `va_end`. unsafe { va_end(&mut ap); } ret } ``` `@rustbot` label +F-c_variadic r? `@workingjubilee`
After doing some research on variance and going back to look at
VaList
andVaListImpl
, I realized thatVaList<'a, 'f>
is invariant over the'f
lifetime (and covariant over'a
), butVaListImpl<'f>
isn't invariant but probably should be. This patch makesVaListImpl<'f>
invariant over'f
.r? @eddyb
cc @dlrobertson