Trait abi_stable::pointer_trait::CanTransmuteElement

source ·
pub unsafe trait CanTransmuteElement<T>: GetPointerKind {
    type TransmutedPtr: AsPtr<PtrTarget = T>;

    // Required method
    unsafe fn transmute_element_(self) -> Self::TransmutedPtr;
}
Expand description

Whether the pointer can be transmuted to an equivalent pointer with T as the referent type.

§Safety

Implementors of this trait must ensure that:

  • The memory layout of this type is the same regardless of the type of the referent.

  • The pointer type is either !Drop(no drop glue either), or it uses a vtable to Drop the referent and deallocate the memory correctly.

  • transmute_element_ must return a pointer to the same allocation as self, at the same offset, and with no reduced provenance (the range of addresses that are valid to dereference with pointers derived from the returned pointer).

§Example

use abi_stable::{
    pointer_trait::{
        PK_Reference,
        AsPtr, CanTransmuteElement, GetPointerKind, TransmuteElement,
    },
    sabi_types::StaticRef,
    std_types::{Tuple2, Tuple4},
};

fn main() {
    let reff = FooRef::new(&Tuple4::<u8, u16, u32, u64>(3, 5, 8, 13));
     
    // safety: `Tuple2<u8, u16>` is a compatible prefix of `Tuple4<u8, u16, u32, u64>`
    let smaller = unsafe{ reff.transmute_element::<Tuple2<u8, u16>>() };
    assert_eq!(smaller.get(), &Tuple2(3u8, 5u16));
}


#[derive(Debug, Copy, Clone)]
#[repr(transparent)]
struct FooRef<T>(StaticRef<T>);

impl<T: 'static> FooRef<T> {
    pub const fn new(reff: &'static T) -> Self {
        Self(StaticRef::new(reff))
    }
    pub fn get(self) -> &'static T {
        self.0.get()
    }
}

unsafe impl<T: 'static> GetPointerKind for FooRef<T> {
    type PtrTarget = T;
    type Kind = PK_Reference;
}

unsafe impl<T, U> CanTransmuteElement<U> for FooRef<T>
where
    T: 'static,
    U: 'static,
{
    type TransmutedPtr = FooRef<U>;
     
    unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
        FooRef(self.0.transmute_element_())
    }
}

unsafe impl<T: 'static> AsPtr for FooRef<T> {
    fn as_ptr(&self) -> *const T {
        self.0.as_ptr()
    }
}



Required Associated Types§

source

type TransmutedPtr: AsPtr<PtrTarget = T>

The type of the pointer after it’s element type has been changed.

Required Methods§

source

unsafe fn transmute_element_(self) -> Self::TransmutedPtr

Transmutes the element type of this pointer..

§Safety

Callers must ensure that it is valid to convert from a pointer to Self::Referent to a pointer to T .

For example:

It is undefined behavior to create unaligned references , therefore transmuting from &u8 to &u16 is UB if the caller does not ensure that the reference is aligned to a multiple of 2 address.

§Example
use abi_stable::{
    pointer_trait::TransmuteElement,
    std_types::RBox,
};

let signed:RBox<u32>=unsafe{
    RBox::new(1_i32)
        .transmute_element::<u32>()
};

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<'a, T: 'a, O: 'a> CanTransmuteElement<O> for &'a T

source§

impl<'a, T: 'a, O: 'a> CanTransmuteElement<O> for &'a mut T

Implementors§

source§

impl<'a, T, U> CanTransmuteElement<U> for RMut<'a, T>
where U: 'a,

source§

impl<'a, T, U> CanTransmuteElement<U> for RRef<'a, T>
where U: 'a,

source§

impl<T, O> CanTransmuteElement<O> for RArc<T>

source§

impl<T, O> CanTransmuteElement<O> for RBox<T>

source§

impl<T, O, Inline> CanTransmuteElement<O> for RSmallBox<T, Inline>

source§

impl<T, U> CanTransmuteElement<U> for StaticRef<T>