With the following test:
#[test]
fn test_from_raw() {
let _ = <vk::Instance as vk::Handle>::from_raw(20);
}
and the command to run miri test: MIRIFLAGS="-Zmiri-tree-borrows -Zmiri-backtrace=full" cargo +nightly miri nextest run --all-targets --all-features -j20 --no-fail-fast -E'test(test_from_raw)' (with miri and cargo-nextest set up), I end up with the following error:
test vk::tests::test_from_raw ...
stderr ───
error: unsupported operation: integer-to-pointer casts and `ptr::with_exposed_provenance` are not supported with `-Zmiri-strict-provenance`
--> ash/src/vk/macros.rs:142:22
|
142 | Self(x as _)
| ^^^^^^ integer-to-pointer casts and `ptr::with_exposed_provenance` are not supported with `-Zmiri-strict-provenance`
I am writing Vulkan layers in Rust, use vk::Handle::from_raw extensively, and use miri with tree borrows to catch UB for my unsafe code. Therefore, I am wondering if the upstream is willing to accept a PR that removes the integer to pointer casting in vk::Handle::from_raw.
I have 2 different proposals with different drawbacks:
-
Change the definition of a handle type, e.g. vk::Instance to struct Instance(usize). The disadvantage is that:
- The implementation of
null(e.g. ash::vk::Instance::null) has to change. We either change the method from a const fn to a non const fn with Self(::core::ptr::null_mut::<u8>() as usize), or we use Self(0). Dropping const will break the API slightly, while using 0 is not great because it is not guaranteed that C++'s nullptr or C's NULL is 0.
- While
usize should be the same size as *mut u8 on platforms supported by Vulkan, so that ABI should be kept. However, I am not sure if this is strongly guaranteed by Rust.
-
Use ::core::ptr::with_addr to implement Handle::from_raw, i.e., ::core::ptr::dangling_mut::<u8>().with_addr(x). However, with_addr is not introduced until Rust 1.84.0, so we either need to change MSRV or use crates like rustversion for conditional compilation based on the Rust version which adds new dependencies and complicates code.
With the following test:
and the command to run miri test:
MIRIFLAGS="-Zmiri-tree-borrows -Zmiri-backtrace=full" cargo +nightly miri nextest run --all-targets --all-features -j20 --no-fail-fast -E'test(test_from_raw)'(with miri and cargo-nextest set up), I end up with the following error:I am writing Vulkan layers in Rust, use
vk::Handle::from_rawextensively, and use miri with tree borrows to catch UB for my unsafe code. Therefore, I am wondering if the upstream is willing to accept a PR that removes the integer to pointer casting invk::Handle::from_raw.I have 2 different proposals with different drawbacks:
Change the definition of a handle type, e.g.
vk::Instancetostruct Instance(usize). The disadvantage is that:null(e.g.ash::vk::Instance::null) has to change. We either change the method from aconst fnto a non constfnwithSelf(::core::ptr::null_mut::<u8>() as usize), or we useSelf(0). Droppingconstwill break the API slightly, while using 0 is not great because it is not guaranteed that C++'snullptror C'sNULLis 0.usizeshould be the same size as*mut u8on platforms supported by Vulkan, so that ABI should be kept. However, I am not sure if this is strongly guaranteed by Rust.Use
::core::ptr::with_addrto implementHandle::from_raw, i.e.,::core::ptr::dangling_mut::<u8>().with_addr(x). However,with_addris not introduced until Rust 1.84.0, so we either need to change MSRV or use crates likerustversionfor conditional compilation based on the Rust version which adds new dependencies and complicates code.