From 9adce251f355383d6a568465c4a91a6c77e95b85 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Thu, 18 Aug 2022 19:39:14 +0000 Subject: [PATCH] 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 --- core/src/lib.rs | 2 + core/src/mem/transmutability.rs | 88 ++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index 24742bb49..3e54ca996 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -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)] diff --git a/core/src/mem/transmutability.rs b/core/src/mem/transmutability.rs index b4fabedad..87a378631 100644 --- a/core/src/mem/transmutability.rs +++ b/core/src/mem/transmutability.rs @@ -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 +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) + } }