diff options
| author | bors <bors@rust-lang.org> | 2022-09-04 07:55:44 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-09-04 07:55:44 +0000 |
| commit | 8521a8c92da6c0c845d4f6394e903651a227946a (patch) | |
| tree | 18fff039f86b368a19865a2c5a563987ef4185d3 /library/core | |
| parent | c2d140bd36e7fcdc894b7c342fd81a63fdd66373 (diff) | |
| parent | fbcc038a224e58f7d3aca25c7f2321f11ce5513d (diff) | |
| download | rust-8521a8c92da6c0c845d4f6394e903651a227946a.tar.gz rust-8521a8c92da6c0c845d4f6394e903651a227946a.zip | |
Auto merge of #100726 - jswrenn:transmute, r=oli-obk
safe transmute: use `Assume` struct to provide analysis options
This task was left as a TODO in #92268; resolving it brings [`BikeshedIntrinsicFrom`](https://doc.rust-lang.org/nightly/core/mem/trait.BikeshedIntrinsicFrom.html) more in line with the API defined in [MCP411](https://github.com/rust-lang/compiler-team/issues/411).
**Before:**
```rust
pub unsafe trait BikeshedIntrinsicFrom<
Src,
Context,
const ASSUME_ALIGNMENT: bool,
const ASSUME_LIFETIMES: bool,
const ASSUME_VALIDITY: bool,
const ASSUME_VISIBILITY: bool,
> where
Src: ?Sized,
{}
```
**After:**
```rust
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
where
Src: ?Sized,
{}
```
`Assume::visibility` has also been renamed to `Assume::safety`, as library safety invariants are what's actually being assumed; visibility is just the mechanism by which it is currently checked (and that may change).
r? `@oli-obk`
---
Related:
- https://github.com/rust-lang/compiler-team/issues/411
- https://github.com/rust-lang/rust/issues/99571
Diffstat (limited to 'library/core')
| -rw-r--r-- | library/core/src/lib.rs | 2 | ||||
| -rw-r--r-- | library/core/src/mem/transmutability.rs | 88 |
2 files changed, 78 insertions, 12 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index bf75796f1fc..9d857eb63da 100644 --- a/library/core/src/lib.rs +++ b/library/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/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index b4fabedad78..87a37863105 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/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<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) + } } |
