pub struct Assume {
pub alignment: bool,
pub lifetimes: bool,
pub safety: bool,
pub validity: bool,
}
transmutability
)Expand description
Configurable proof assumptions of TransmuteFrom
.
When false
, the respective proof obligation belongs to the compiler. When
true
, the onus of the safety proof belongs to the programmer.
Fields§
§alignment: bool
transmutability
)When false
, TransmuteFrom
is not implemented for transmutations
that might violate the alignment requirements of references; e.g.:
#![feature(transmutability)]
use core::mem::{align_of, TransmuteFrom};
assert_eq!(align_of::<[u8; 2]>(), 1);
assert_eq!(align_of::<u16>(), 2);
let src: &[u8; 2] = &[0xFF, 0xFF];
// SAFETY: No safety obligations.
let dst: &u16 = unsafe {
<_ as TransmuteFrom<_>>::transmute(src)
};
When true
, TransmuteFrom
assumes that you have ensured
that references in the transmuted value satisfy the alignment
requirements of their referent types; e.g.:
#![feature(pointer_is_aligned_to, transmutability)]
use core::mem::{align_of, Assume, TransmuteFrom};
let src: &[u8; 2] = &[0xFF, 0xFF];
let maybe_dst: Option<&u16> = if <*const _>::is_aligned_to(src, align_of::<u16>()) {
// SAFETY: We have checked above that the address of `src` satisfies the
// alignment requirements of `u16`.
Some(unsafe {
<_ as TransmuteFrom<_, { Assume::ALIGNMENT }>>::transmute(src)
})
} else {
None
};
assert!(matches!(maybe_dst, Some(&u16::MAX) | None));
lifetimes: bool
transmutability
)When false
, TransmuteFrom
is not implemented for transmutations
that extend the lifetimes of references.
When true
, TransmuteFrom
assumes that you have ensured that
references in the transmuted value do not outlive their referents.
safety: bool
transmutability
)When false
, TransmuteFrom
is not implemented for transmutations
that might violate the library safety invariants of the destination
type; e.g.:
#![feature(transmutability)]
use core::mem::TransmuteFrom;
let src: u8 = 3;
struct EvenU8 {
// SAFETY: `val` must be an even number.
val: u8,
}
// SAFETY: No safety obligations.
let dst: EvenU8 = unsafe {
<_ as TransmuteFrom<_>>::transmute(src)
};
When true
, TransmuteFrom
assumes that you have ensured
that undefined behavior does not arise from using the transmuted value;
e.g.:
#![feature(transmutability)]
use core::mem::{Assume, TransmuteFrom};
let src: u8 = 42;
struct EvenU8 {
// SAFETY: `val` must be an even number.
val: u8,
}
let maybe_dst: Option<EvenU8> = if src % 2 == 0 {
// SAFETY: We have checked above that the value of `src` is even.
Some(unsafe {
<_ as TransmuteFrom<_, { Assume::SAFETY }>>::transmute(src)
})
} else {
None
};
assert!(matches!(maybe_dst, Some(EvenU8 { val: 42 })));
validity: bool
transmutability
)When false
, TransmuteFrom
is not implemented for transmutations
that might violate the language-level bit-validity invariant of the
destination type; e.g.:
#![feature(transmutability)]
use core::mem::TransmuteFrom;
let src: u8 = 3;
// SAFETY: No safety obligations.
let dst: bool = unsafe {
<_ as TransmuteFrom<_>>::transmute(src)
};
When true
, TransmuteFrom
assumes that you have ensured
that the value being transmuted is a bit-valid instance of the
transmuted value; e.g.:
#![feature(transmutability)]
use core::mem::{Assume, TransmuteFrom};
let src: u8 = 1;
let maybe_dst: Option<bool> = if src == 0 || src == 1 {
// SAFETY: We have checked above that the value of `src` is a bit-valid
// instance of `bool`.
Some(unsafe {
<_ as TransmuteFrom<_, { Assume::VALIDITY }>>::transmute(src)
})
} else {
None
};
assert_eq!(maybe_dst, Some(true));
Implementations§
Source§impl Assume
impl Assume
Sourcepub const NOTHING: Assume = _
🔬This is a nightly-only experimental API. (transmutability
)
pub const NOTHING: Assume = _
transmutability
)With this, TransmuteFrom
does not assume you have ensured any safety
obligations are met, and relies only upon its own analysis to (dis)prove
transmutability.
Sourcepub const ALIGNMENT: Assume = _
🔬This is a nightly-only experimental API. (transmutability
)
pub const ALIGNMENT: Assume = _
transmutability
)With this, TransmuteFrom
assumes only that you have ensured that
references in the transmuted value satisfy the alignment requirements of
their referent types. See Assume::alignment
for examples.
Sourcepub const LIFETIMES: Assume = _
🔬This is a nightly-only experimental API. (transmutability
)
pub const LIFETIMES: Assume = _
transmutability
)With this, TransmuteFrom
assumes only that you have ensured that
references in the transmuted value do not outlive their referents. See
Assume::lifetimes
for examples.
Sourcepub const SAFETY: Assume = _
🔬This is a nightly-only experimental API. (transmutability
)
pub const SAFETY: Assume = _
transmutability
)With this, TransmuteFrom
assumes only that you have ensured that
undefined behavior does not arise from using the transmuted value. See
Assume::safety
for examples.
Sourcepub const VALIDITY: Assume = _
🔬This is a nightly-only experimental API. (transmutability
)
pub const VALIDITY: Assume = _
transmutability
)With this, TransmuteFrom
assumes only that you have ensured that the
value being transmuted is a bit-valid instance of the transmuted value.
See Assume::validity
for examples.
Sourcepub const fn and(self, other_assumptions: Assume) -> Assume
🔬This is a nightly-only experimental API. (transmutability
)
pub const fn and(self, other_assumptions: Assume) -> Assume
transmutability
)Combine the assumptions of self
and other_assumptions
.
This is especially useful for extending Assume
in generic contexts;
e.g.:
#![feature(
adt_const_params,
generic_const_exprs,
pointer_is_aligned_to,
transmutability,
)]
#![allow(incomplete_features)]
use core::mem::{align_of, Assume, TransmuteFrom};
/// Attempts to transmute `src` to `&Dst`.
///
/// Returns `None` if `src` violates the alignment requirements of `&Dst`.
///
/// # Safety
///
/// The caller guarantees that the obligations required by `ASSUME`, except
/// alignment, are satisfied.
unsafe fn try_transmute_ref<'a, Src, Dst, const ASSUME: Assume>(src: &'a Src) -> Option<&'a Dst>
where
&'a Dst: TransmuteFrom<&'a Src, { ASSUME.and(Assume::ALIGNMENT) }>,
{
if <*const _>::is_aligned_to(src, align_of::<Dst>()) {
// SAFETY: By the above dynamic check, we have ensured that the address
// of `src` satisfies the alignment requirements of `&Dst`. By contract
// on the caller, the safety obligations required by `ASSUME` have also
// been satisfied.
Some(unsafe {
<_ as TransmuteFrom<_, { ASSUME.and(Assume::ALIGNMENT) }>>::transmute(src)
})
} else {
None
}
}
let src: &[u8; 2] = &[0xFF, 0xFF];
// SAFETY: No safety obligations.
let maybe_dst: Option<&u16> = unsafe {
try_transmute_ref::<_, _, { Assume::NOTHING }>(src)
};
Sourcepub const fn but_not(self, other_assumptions: Assume) -> Assume
🔬This is a nightly-only experimental API. (transmutability
)
pub const fn but_not(self, other_assumptions: Assume) -> Assume
transmutability
)Remove other_assumptions
the obligations of self
; e.g.:
#![feature(transmutability)]
use core::mem::Assume;
let assumptions = Assume::ALIGNMENT.and(Assume::SAFETY);
let to_be_removed = Assume::SAFETY.and(Assume::VALIDITY);
assert_eq!(
assumptions.but_not(to_be_removed),
Assume::ALIGNMENT,
);