safe transmute: use Assume struct to provide analysis options
This was left as a TODO in #92268, and brings the trait more in line with what was defined in MCP411. `Assume::visibility` has been renamed to `Assume::safety`, as library safety is what's actually being assumed; visibility is just the mechanism by which it is currently checked (this may change). ref: https://github.com/rust-lang/compiler-team/issues/411 ref: https://github.com/rust-lang/rust/issues/99571
This commit is contained in:
parent
e0dc8d7801
commit
f46fffc276
77 changed files with 1321 additions and 721 deletions
|
|
@ -93,6 +93,7 @@
|
|||
#![warn(missing_debug_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
#![allow(explicit_outlives_requirements)]
|
||||
#![allow(incomplete_features)]
|
||||
//
|
||||
// Library features:
|
||||
#![feature(const_align_offset)]
|
||||
|
|
@ -160,6 +161,7 @@
|
|||
//
|
||||
// Language features:
|
||||
#![feature(abi_unadjusted)]
|
||||
#![feature(adt_const_params)]
|
||||
#![feature(allow_internal_unsafe)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(associated_type_bounds)]
|
||||
|
|
|
|||
|
|
@ -4,25 +4,20 @@
|
|||
/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`,
|
||||
/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
#[lang = "transmute_trait"]
|
||||
#[cfg_attr(not(bootstrap), lang = "transmute_trait")]
|
||||
#[rustc_on_unimplemented(
|
||||
message = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`.",
|
||||
label = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`."
|
||||
)]
|
||||
pub unsafe trait BikeshedIntrinsicFrom<
|
||||
Src,
|
||||
Context,
|
||||
const ASSUME_ALIGNMENT: bool,
|
||||
const ASSUME_LIFETIMES: bool,
|
||||
const ASSUME_VALIDITY: bool,
|
||||
const ASSUME_VISIBILITY: bool,
|
||||
> where
|
||||
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
|
||||
where
|
||||
Src: ?Sized,
|
||||
{
|
||||
}
|
||||
|
||||
/// What transmutation safety conditions shall the compiler assume that *you* are checking?
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
#[cfg_attr(not(bootstrap), lang = "transmute_opts")]
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct Assume {
|
||||
/// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that
|
||||
|
|
@ -33,11 +28,80 @@ pub struct Assume {
|
|||
/// that violates Rust's memory model.
|
||||
pub lifetimes: bool,
|
||||
|
||||
/// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the
|
||||
/// type and field privacy of the destination type (and sometimes of the source type, too).
|
||||
pub safety: bool,
|
||||
|
||||
/// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid
|
||||
/// instance of the destination type.
|
||||
pub validity: bool,
|
||||
|
||||
/// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the
|
||||
/// type and field privacy of the destination type (and sometimes of the source type, too).
|
||||
pub visibility: bool,
|
||||
}
|
||||
|
||||
impl Assume {
|
||||
/// Do not assume that *you* have ensured any safety properties are met.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
pub const NOTHING: Self =
|
||||
Self { alignment: false, lifetimes: false, safety: false, validity: false };
|
||||
|
||||
/// Assume only that alignment conditions are met.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING };
|
||||
|
||||
/// Assume only that lifetime conditions are met.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING };
|
||||
|
||||
/// Assume only that safety conditions are met.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING };
|
||||
|
||||
/// Assume only that dynamically-satisfiable validity conditions are met.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING };
|
||||
|
||||
/// Assume both `self` and `other_assumptions`.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
pub const fn and(self, other_assumptions: Self) -> Self {
|
||||
Self {
|
||||
alignment: self.alignment || other_assumptions.alignment,
|
||||
lifetimes: self.lifetimes || other_assumptions.lifetimes,
|
||||
safety: self.safety || other_assumptions.safety,
|
||||
validity: self.validity || other_assumptions.validity,
|
||||
}
|
||||
}
|
||||
|
||||
/// Assume `self`, excepting `other_assumptions`.
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
pub const fn but_not(self, other_assumptions: Self) -> Self {
|
||||
Self {
|
||||
alignment: self.alignment && !other_assumptions.alignment,
|
||||
lifetimes: self.lifetimes && !other_assumptions.lifetimes,
|
||||
safety: self.safety && !other_assumptions.safety,
|
||||
validity: self.validity && !other_assumptions.validity,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(jswrenn): This const op is not actually usable. Why?
|
||||
// https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
#[rustc_const_unstable(feature = "transmutability", issue = "99571")]
|
||||
impl const core::ops::Add for Assume {
|
||||
type Output = Assume;
|
||||
|
||||
fn add(self, other_assumptions: Assume) -> Assume {
|
||||
self.and(other_assumptions)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(jswrenn): This const op is not actually usable. Why?
|
||||
// https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
|
||||
#[unstable(feature = "transmutability", issue = "99571")]
|
||||
#[rustc_const_unstable(feature = "transmutability", issue = "99571")]
|
||||
impl const core::ops::Sub for Assume {
|
||||
type Output = Assume;
|
||||
|
||||
fn sub(self, other_assumptions: Assume) -> Assume {
|
||||
self.but_not(other_assumptions)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue