From eb75ded7934759aac55ff999f36059e2a6a16e9c Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 2 Mar 2021 18:22:04 +0100 Subject: [PATCH] README: Add lifetime-preserving builder example using slice::from_ref (#381) It isn't too uncommon to pass a single builder element into another builder, and `slice::from_ref` fits perfectly while preserving lifetime of the builder without calling `.build()`. We have used this successfully in our codebase to uncover and prevent numerous use-after-free bugs, and thought it's worth to share on the front page. --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b76b0d..fe21754 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ let queue_info = [vk::DeviceQueueCreateInfo::builder() .queue_priorities(&priorities) .build()]; -// We don't need to call build here because builders implement `Deref`. +// We don't need to call `.build()` here because builders implement `Deref`. let device_create_info = vk::DeviceCreateInfo::builder() .queue_create_infos(&queue_info) .enabled_extension_names(&device_extension_names_raw) @@ -89,6 +89,18 @@ let device: Device = instance .unwrap(); ``` +To not lose this lifetime single items can be "cast" to a slice of length _one_ with `std::slice::from_ref` while still taking advantage of `Deref`: + +```rust +let queue_info = vk::DeviceQueueCreateInfo::builder() + .queue_family_index(queue_family_index) + .queue_priorities(&priorities); + +let device_create_info = vk::DeviceCreateInfo::builder() + .queue_create_infos(std::slice::from_ref(&queue_info)) + ...; +``` + Builders have an explicit lifetime, and are marked as `#[repr(transparent)]`. ```rust #[repr(transparent)]