Derive Macro vasi::VirtualAddressSpaceIndependent
#[derive(VirtualAddressSpaceIndependent)]
{
// Attributes available to this derive:
#[unsafe_assume_virtual_address_space_independent]
}
Expand description
Implement vasi::VirtualAddressSpaceIndependent
for the annotated type.
Requires all fields to implement vasi::VirtualAddressSpaceIndependent
.
An empty struct fails becase Rust doesn’t consider fieldless structs to be FFI-safe:
use vasi::VirtualAddressSpaceIndependent;
#[derive(VirtualAddressSpaceIndependent)]
#[repr(C)]
struct Foo {}
FFI-safe structs containing only VirtualAddressSpaceIndependent
fields qualify:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct Foo {
x: i32,
}
#[repr(transparent)]
is OK too.
use vasi::VirtualAddressSpaceIndependent;
#[repr(transparent)]
#[derive(VirtualAddressSpaceIndependent)]
struct Foo {
x: i32,
}
A struct containing a reference doesn’t qualify:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct Foo<'a> {
x: &'a i32,
}
A struct containing a [Box] doesn’t qualify:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct Foo {
x: Box<i32>,
}
A struct containing a pointer doesn’t qualify:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct Foo {
x: *const i32,
}
A field can be allow-listed with the attribute unsafe_assume_virtual_address_space_independent
:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct Foo {
// SAFETY: we ensure the pointer isn't dereferenced
// outside of its original virtual address space.
#[unsafe_assume_virtual_address_space_independent]
x: *const i32,
}
A union containing only VirtualAddressSpaceIndependent
fields qualifies:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
union Foo {
x: i32,
y: i32,
}
A union containing a non-vasi member doesn’t qualify:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct Foo {
x: i32,
y: *const i32,
}
An enum containing only VirtualAddressSpaceIndependent
variants qualifies:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
enum Foo {
Bar(i32),
Baz(i32),
}
An enum containing a non-vasi variant doesn’t qualify:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
enum Foo {
Bar(i32),
Baz(*const i32),
}
A generic type conditionally implements VirtualAddressSpaceIndependent, if its type parameters do (as the derive macros in the std crate behave).
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct MyWrapper<T> {
val: T,
}
static_assertions::assert_impl_all!(MyWrapper<i32>: vasi::VirtualAddressSpaceIndependent);
static_assertions::assert_not_impl_all!(MyWrapper<* const i32>: vasi::VirtualAddressSpaceIndependent);
Generic type with existing bounds are also supported.
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct MyWrapper<T: Copy> {
val: T,
}
static_assertions::assert_impl_all!(MyWrapper<i32>: vasi::VirtualAddressSpaceIndependent);
static_assertions::assert_not_impl_all!(MyWrapper<* const i32>: vasi::VirtualAddressSpaceIndependent);
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct MyWrapper2<T> where T: Copy {
val: T,
}
static_assertions::assert_impl_all!(MyWrapper2<i32>: vasi::VirtualAddressSpaceIndependent);
static_assertions::assert_not_impl_all!(MyWrapper2<* const i32>: vasi::VirtualAddressSpaceIndependent);
As with e.g. Copy and Clone, a field that is dependent on a type parameter but still isn’t VirtualAddressSpaceIndependent will cause the macro not to compile:
use vasi::VirtualAddressSpaceIndependent;
#[repr(C)]
#[derive(VirtualAddressSpaceIndependent)]
struct MyWrapper<T> {
val: *const T,
}