Struct abi_stable::sabi_types::RMut [−][src]
#[repr(transparent)]pub struct RMut<'a, T> { /* fields omitted */ }
Expand description
Equivalent to &'a mut T
,
which allows a few more operations without causing Undefined Behavior.
Purpose
This type is used as the &mut self
parameter in abi_stable trait objects
because it can be soundly transmuted
to point to other smaller but compatible types, then back to the original type.
This crate is tested with miri to detect bugs in unsafe code,
which implements the Stacked Borrows model.
Because that model forbids &mut T
to &mut ()
to &mut T
transmutes
(when T
isn’t zero-sized),
it required defining RMut
to allow a mutable-reference-like type that can be transmuted.
Example
This example demonstrates how a simple &mut dyn Any
-like type can be implemented.
use abi_stable::{
marker_type::ErasedObject,
std_types::UTypeId,
RMut,
};
fn main(){
let mut value = WithTypeId::new(5u32);
let mut clone = value.clone();
let mut erased = value.erase();
assert_eq!(WithTypeId::downcast::<i32>(erased.reborrow()), None);
assert_eq!(WithTypeId::downcast::<bool>(erased.reborrow()), None);
assert_eq!(WithTypeId::downcast::<u32>(erased.reborrow()), Some(&mut clone));
}
// `#[repr(C))]` with a trailing `T` field is required for soundly transmuting from
// `RMut<'a, WithTypeId<T>>` to `RMut<'a, WithTypeId<ErasedObject>>`.
#[repr(C)]
#[derive(Debug, PartialEq, Clone)]
struct WithTypeId<T>{
type_id: UTypeId,
value: T,
}
impl<T> WithTypeId<T> {
pub fn new(value: T) -> Self
where
T: 'static
{
Self{
type_id: UTypeId::new::<T>(),
value,
}
}
pub fn erase(&mut self) -> RMut<'_, WithTypeId<ErasedObject>> {
unsafe{ RMut::new(self).transmute::<WithTypeId<ErasedObject>>() }
}
}
impl WithTypeId<ErasedObject> {
pub fn downcast<T>(this: RMut<'_, Self>) -> Option<&mut WithTypeId<T>>
where
T: 'static
{
if this.get().type_id == UTypeId::new::<T>() {
// safety: we checked that type parameter was `T`
unsafe{ Some(this.transmute_into_mut::<WithTypeId<T>>()) }
} else {
None
}
}
}
Type Prefix
A type parameter U
is considered a prefix of T
in all of these cases:
-
U
is a zero-sized type with an alignment equal or lower thanT
-
U
is a#[repr(transparent)]
wrapper overT
-
U
andT
are both#[repr(C)]
structs, in whichT
starts with the fields ofU
in the same order, andU
has an alignment equal to or lower thanT
.
Please note that it can be unsound to transmute a non-local type if it has private fields, since it may assume it was constructed in a particular way.
Implementations
Constructs this RMut from a mutable reference
Example
use abi_stable::RMut;
let mut foo = 3;
let mut rmut = RMut::new(&mut foo);
*rmut.get_mut() += 10;
assert_eq!(*rmut.get(), 13);
assert_eq!(foo, 13);
Constructs this RMut from a raw pointer.
Safety
You must ensure that the raw pointer is valid for the 'a
lifetime,
points to a fully initialized and aligned T
,
and that this is the only active pointer to that value.
Example
use abi_stable::RMut;
let mut foo = 3u32;
// safety:
// `&mut foo` is casted to a pointer to a compatible type (`u32` to `i32`),
// `rmut` is only used for the lifetime of foo,
// and is the only active pointer to `foo` while it's used.
let mut rmut = unsafe{ RMut::from_raw((&mut foo) as *mut u32 as *mut i32) };
*rmut.get_mut() -= 4;
assert_eq!(*rmut.get(), -1);
assert_eq!(foo, !0);
Reborrows this RMut
, with a shorter lifetime.
This allows passing an RMut
to functions multiple times,
but with a shorter lifetime argument.
Example
use abi_stable::RMut;
let mut foo = 3;
let mut rmut = RMut::new(&mut foo);
assert_eq!(mutate(rmut.reborrow()), 6);
assert_eq!(mutate(rmut.reborrow()), 12);
assert_eq!(mutate(rmut.reborrow()), 24);
// last use of rmut, so it can be moved instead of being reborrowed.
assert_eq!(mutate(rmut), 48);
fn mutate(mut rmut: RMut<'_, u32>) -> u32 {
*rmut.get_mut() *= 2;
rmut.get_copy()
}
Reborrows this RMut
into a shared reference.
Note that because the reference reborrows this RMut<'a, T>
its lifetime argument is strictly smaller.
To turn an RMut<'a, T>
into a &'a T
(with the same lifetime argument)
you can use into_ref
.
Example
use abi_stable::RMut;
let mut val = 89;
let rmut = RMut::new(&mut val);
assert_eq!(rmut.get(), &89);
Lifetimes
This demonstrates when into_ref
works, but get
doesn’t.
fn stuff<'a>(x: RMut<'a, i32>) -> &'a i32 {
x.into_ref()
}
This doesn’t compile, because get
reborrows foo
.
fn stuff<'a>(foo: RMut<'a, i32>) -> &'a i32 {
foo.get()
}
Copies the value that this RMut
points to.
Example
use abi_stable::RMut;
let mut val = "hello";
let mut rmut = RMut::new(&mut val);
*rmut.get_mut() = "world";
assert_eq!(rmut.get_copy(), "world");
Converts this RMut<'a, T>
into a &'a T
Example
use abi_stable::RMut;
let mut val = 89;
assert_eq!(mutate(RMut::new(&mut val)), &44);
fn mutate(mut rmut: RMut<'_, u32>) -> &u32 {
*rmut.get_mut() /= 2;
rmut.into_ref()
}
Reborrows this RMut
into a mutable reference.
Note that because the mutable reference reborrows this RMut<'a, T>
its lifetime argument is strictly smaller.
To turn an RMut<'a, T>
into a &'a mut T
(with the same lifetime argument)
you can use into_mut
.
Example
use abi_stable::RMut;
let mut val = 89;
let mut rmut = RMut::new(&mut val);
assert_eq!(rmut.get_mut(), &mut 89);
*rmut.get_mut() += 10;
assert_eq!(rmut.get_mut(), &mut 99);
Lifetimes
This demonstrates when into_mut
works, but get_mut
doesn’t.
fn stuff<'a>(x: RMut<'a, i32>) -> &'a mut i32 {
x.into_mut()
}
This doesn’t compile, because get_mut
reborrows foo
.
fn stuff<'a>(mut foo: RMut<'a, i32>) -> &'a mut i32 {
foo.get_mut()
}
Converts this RMut<'a, T>
into a &'a mut T
Example
use abi_stable::RMut;
let mut val = 13;
let rmut = RMut::new(&mut val);
assert_eq!(rmut.get(), &13);
*rmut.into_mut() += 8;
assert_eq!(val, 21);
Reborrows this RMut
as a const raw pointer.
Example
use abi_stable::RMut;
let mut val = 34;
let rmut = RMut::new(&mut val);
unsafe{
assert_eq!(*rmut.as_ptr(), 34);
}
Reborrows this RMut
as a mutable raw pointer.
Example
use abi_stable::RMut;
let mut val = 34;
let mut rmut = RMut::new(&mut val);
unsafe{
rmut.as_mut_ptr().write(7);
*rmut.as_mut_ptr() *= 2;
assert_eq!(val, 14);
}
Converts this RMut<'a, T>
into a *mut T
Example
use abi_stable::RMut;
let mut val = 89;
let rmut = RMut::new(&mut val);
unsafe{
let ptr = rmut.into_raw();
ptr.write(27);
*ptr += 2;
assert_eq!(val, 29);
}
Transmutes this RMut<'a, T>
to a *mut U
.
Example
use abi_stable::RMut;
let mut val = Direction::Up;
let rmut = RMut::new(&mut val);
assert_eq!(rmut.get(), &Direction::Up);
let ptr = rmut.transmute_into_raw::<u8>();
unsafe {
assert_eq!(*ptr, 2);
*ptr = 3;
}
assert_eq!(val, Direction::Down);
#[repr(u8)]
#[derive(Debug, PartialEq)]
enum Direction {
Left = 0,
Right = 1,
Up = 2,
Down = 3,
}
Transmutes this RMut<'a, T>
to a &'a mut U
.
Safety
Either of these must be the case:
-
RMut<'a, U>
was the original type of thisRMut<'a, T>
.
Example
use abi_stable::RMut;
let mut val = 13u8;
let rmut = RMut::new(&mut val);
assert_eq!(rmut.get(), &13);
unsafe{
*rmut.transmute_into_mut::<i8>() = -1;
}
assert_eq!(val, 255);
Transmutes this RMut<'a, T>
to a RMut<'a,U>
.
Safety
Either of these must be the case:
-
RMut<'a, U>
was the original type of thisRMut<'a, T>
.
Example
use abi_stable::RMut;
let mut val: [u32; 3] = [2, 3, 0];
let mut rmut = RMut::new(&mut val);
unsafe{
// safety:
// it's sound to transmute mutable references of arrays into shorter arrays.
//
// The `.reborrow()` prevents the `rmut` from being consumed.
compute_next(rmut.reborrow().transmute::<[u32; 2]>());
assert_eq!(rmut.get_copy(), [3, 5, 0]);
compute_next(rmut.reborrow().transmute::<[u32; 2]>());
assert_eq!(rmut.get_copy(), [5, 8, 0]);
// last use of `rmut`, so no need to reborrow
compute_next(rmut.transmute::<[u32; 2]>());
}
assert_eq!(val, [8, 13, 0]);
fn compute_next(rmut: RMut<'_, [u32; 2]>) {
let [v0, v1] = rmut.into_mut();
let next = *v0 + *v1;
*v0 = std::mem::replace(v1, next);
}
Reborrows this RMut<'a, T>
into an RRef<'_, T>
Example
use abi_stable::{RRef, RMut};
let mut val = 77;
let rmut = RMut::new(&mut val);
for _ in 0..10 {
assertion(rmut.as_rref());
}
fn assertion(rref: RRef<'_, u32>) {
assert_eq!(rref.get_copy(), 77);
}
Trait Implementations
type TransmutedPtr = RMut<'a, U>
type TransmutedPtr = RMut<'a, U>
The type of the pointer after it’s element type has been changed.
Transmutes the element type of this pointer.. Read more
type Kind = PK_MutReference
type Kind = PK_MutReference
The kind of the pointer.
type PtrTarget = T
type PtrTarget = T
What this pointer points to,
if the type implements std::ops::Deref
it must be the same as
<Self as Deref>::Target
. Read more
The kind of the pointer.
type StaticEquivalent = _static_RMut<'static, __GetStaticEquivalent<T>>
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
type IsNonZeroType = <NonNull<T> as __StableAbi>::IsNonZeroType
type IsNonZeroType = <NonNull<T> as __StableAbi>::IsNonZeroType
Whether this type has a single invalid bit-pattern. Read more
The layout of the type provided by implementors.
const
-equivalents of the associated types.
Auto Trait Implementations
impl<'a, T> RefUnwindSafe for RMut<'a, T> where
T: RefUnwindSafe,
impl<'a, T> !UnwindSafe for RMut<'a, T>
Blanket Implementations
Mutably borrows from an owned value. Read more
type ForSelf = WithMetadata_<T, T>
type ForSelf = WithMetadata_<T, T>
This is always WithMetadata_<Self, Self>
Compares the address of self
with the address of other
. Read more
Emulates the pipeline operator, allowing method syntax in more places. Read more
The same as piped
except that the function takes &Self
Useful for functions that take &Self
instead of Self
. Read more
The same as piped
, except that the function takes &mut Self
.
Useful for functions that take &mut Self
instead of Self
. Read more
Mutates self using a closure taking self by mutable reference, passing it along the method chain. Read more
Observes the value of self, passing it along unmodified. Useful in long method chains. Read more
Performs a conversion with Into
.
using the turbofish .into_::<_>()
syntax. Read more
Performs a reference to reference conversion with AsRef
,
using the turbofish .as_ref_::<_>()
syntax. Read more
Performs a mutable reference to mutable reference conversion with AsMut
,
using the turbofish .as_mut_::<_>()
syntax. Read more
unsafe fn transmute_element<T>(
self
) -> <Self as CanTransmuteElement<T>>::TransmutedPtr where
Self: CanTransmuteElement<T>,
unsafe fn transmute_element<T>(
self
) -> <Self as CanTransmuteElement<T>>::TransmutedPtr where
Self: CanTransmuteElement<T>,
Transmutes the element type of this pointer.. Read more
type Type = T
type Type = T
This is always Self
.
Converts a value back to the original type.
Converts a mutable reference back to the original type.
Converts a box back to the original type.
Converts an Arc back to the original type. Read more
Converts an Rc back to the original type. Read more
Converts a value back to the original type.
Converts a reference back to the original type.
Converts a mutable reference back to the original type.
Converts a box back to the original type.
Converts an Arc back to the original type.
Converts an Rc back to the original type.