Skip to content

Commit e73f92b

Browse files
committed
Add documented test for using structs after temporarily being part of a mutable pointer chain
This test is based on the trybuild failure test where the root structure is still being alive and used when one of its pointer-chain members is being accessed, violating mutable borrow rules. Note that this pattern still doesn't apply mutable borrow rules to *longer pointer chains where multiple structs* are pushed to the same *root struct*, resulting in those structs now referencing each other via `pNext` even after the root struct goes out of scope. This is implicitly handled - though not explicitly documented - by all Vulkan function calls remaining `unsafe` and by `push()` asserting that incoming structures have `pNext` set to `NULL`. Unless those structs were pushed into each other manually while preserving existing `pNext` pointers via `unsafe` `extend()`, which commonly isn't even possible for arbitrary extension structures that are not a root structure themselves (i.e. no other structure lists the extension structure in a `structextends`).
1 parent e377fb5 commit e73f92b

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

ash/src/vk.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,25 @@ mod tests {
328328
assert_eq!(chain, chain2);
329329
}
330330

331+
#[test]
332+
fn test_use_struct_after_pointer_chain() {
333+
// The negative case of this test, where `pdev_props` stays alive by being
334+
// used at the end of this function while `api` is invalidly accessed first
335+
// (resulting in an immutable borrow while mutably borrowed error), exists in
336+
// `tests/fail/long_lived_root_struct_borrow.rs`. This test demonstrates the expected usage
337+
// pattern of dropping `pdev_props` so that `api` no longer becomes mutably borrowed and the
338+
// properties read from Vulkan can now be accessed by the caller.
339+
340+
let mut layers = vec![];
341+
let mut api =
342+
vk::PhysicalDeviceLayeredApiPropertiesListKHR::default().layered_apis(&mut layers);
343+
let _pdev_props = vk::PhysicalDeviceProperties2::default().push(&mut api);
344+
345+
// Access to either variable is allowed because `pdev_props` is no longer used
346+
dbg!(&api);
347+
dbg!(&layers);
348+
}
349+
331350
#[test]
332351
fn test_debug_flags() {
333352
assert_eq!(

0 commit comments

Comments
 (0)