Skip to content

Commit ccfd77e

Browse files
Decouple next lifetime from itself in TaggedStructure::push() and ::extend() (#1005)
Right now `TaggedStructure::push()` is defined by #994 as: ```rs fn push<T: Extends<Self> + TaggedStructure<'a>>(mut self, next: &'a mut T) -> Self ``` This requires that the extending structure `next` has the same lifetime as the contents of the base structure `self: TaggedStructure<'a>` because of `next: &'a mut T`, _and `next` itself_ because of `T: TaggedStructure<'a>` which is unnecessarily restricting. Specifically, even after `self` is no longer live (i.e. it is no longer mutably borrowing `next`) `next` cannot be accessed because it is mutably borrowed within itself through the fixed/shared lifetime of `'a` as demonstrated by a new test in commit 4942dc3. The same restriction exists for `TaggedStructure::extend()`. This PR decouples lifetime `'a` for the contents of `self` and the borrow of `next` from a new lifetime `'b` for _the contents of `next`_ in `push()` and `extend()` to require that the _contents of `next`_ outlive the borrow of `next` rather than considering `next` to remain mutably borrowed within itself.
1 parent 4444630 commit ccfd77e

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

ash/src/vk.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub unsafe trait TaggedStructure<'a>: Sized {
8181
/// # Panics
8282
/// If `next` contains a pointer chain of its own, this function will panic. Call `unsafe`
8383
/// [`Self::extend()`] to insert this chain instead.
84-
fn push<T: Extends<Self> + TaggedStructure<'a>>(mut self, next: &'a mut T) -> Self {
84+
fn push<'b: 'a, T: Extends<Self> + TaggedStructure<'b>>(mut self, next: &'a mut T) -> Self {
8585
// SAFETY: All implementers of `TaggedStructure` are required to have the `BaseOutStructure` layout
8686
let slf_base = unsafe { &mut *<*mut _>::cast::<BaseOutStructure<'_>>(&mut self) };
8787
// SAFETY: All implementers of `T: TaggedStructure` are required to have the `BaseOutStructure` layout
@@ -110,7 +110,10 @@ pub unsafe trait TaggedStructure<'a>: Sized {
110110
///
111111
/// The last struct in this chain (i.e. the one where `p_next` is `NULL`) must be writable
112112
/// memory, as its `p_next` field will be updated with the value of `self.p_next`.
113-
unsafe fn extend<T: Extends<Self> + TaggedStructure<'a>>(mut self, next: &'a mut T) -> Self {
113+
unsafe fn extend<'b: 'a, T: Extends<Self> + TaggedStructure<'b>>(
114+
mut self,
115+
next: &'a mut T,
116+
) -> Self {
114117
// `next` here can contain a pointer chain. This means that we must correctly attach he head
115118
// to the root and the tail to the rest of the chain For example:
116119
//

0 commit comments

Comments
 (0)