-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Make VaListImpl<'f> invariant over the 'f lifetime #62639
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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