Skip to content

Commit a634fb7

Browse files
committed
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](rust-lang/compiler-team#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: - rust-lang/compiler-team#411 - rust-lang/rust#99571
2 parents de5c180 + 9adce25 commit a634fb7

File tree

2 files changed

+78
-12
lines changed

2 files changed

+78
-12
lines changed

core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#![warn(missing_debug_implementations)]
9494
#![warn(missing_docs)]
9595
#![allow(explicit_outlives_requirements)]
96+
#![allow(incomplete_features)]
9697
//
9798
// Library features:
9899
#![feature(const_align_offset)]
@@ -160,6 +161,7 @@
160161
//
161162
// Language features:
162163
#![feature(abi_unadjusted)]
164+
#![feature(adt_const_params)]
163165
#![feature(allow_internal_unsafe)]
164166
#![feature(allow_internal_unstable)]
165167
#![feature(associated_type_bounds)]

core/src/mem/transmutability.rs

+76-12
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,20 @@
44
/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`,
55
/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
66
#[unstable(feature = "transmutability", issue = "99571")]
7-
#[lang = "transmute_trait"]
7+
#[cfg_attr(not(bootstrap), lang = "transmute_trait")]
88
#[rustc_on_unimplemented(
99
message = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`.",
1010
label = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`."
1111
)]
12-
pub unsafe trait BikeshedIntrinsicFrom<
13-
Src,
14-
Context,
15-
const ASSUME_ALIGNMENT: bool,
16-
const ASSUME_LIFETIMES: bool,
17-
const ASSUME_VALIDITY: bool,
18-
const ASSUME_VISIBILITY: bool,
19-
> where
12+
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
13+
where
2014
Src: ?Sized,
2115
{
2216
}
2317

2418
/// What transmutation safety conditions shall the compiler assume that *you* are checking?
2519
#[unstable(feature = "transmutability", issue = "99571")]
20+
#[cfg_attr(not(bootstrap), lang = "transmute_opts")]
2621
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
2722
pub struct Assume {
2823
/// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that
@@ -33,11 +28,80 @@ pub struct Assume {
3328
/// that violates Rust's memory model.
3429
pub lifetimes: bool,
3530

31+
/// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the
32+
/// type and field privacy of the destination type (and sometimes of the source type, too).
33+
pub safety: bool,
34+
3635
/// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid
3736
/// instance of the destination type.
3837
pub validity: bool,
38+
}
3939

40-
/// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the
41-
/// type and field privacy of the destination type (and sometimes of the source type, too).
42-
pub visibility: bool,
40+
impl Assume {
41+
/// Do not assume that *you* have ensured any safety properties are met.
42+
#[unstable(feature = "transmutability", issue = "99571")]
43+
pub const NOTHING: Self =
44+
Self { alignment: false, lifetimes: false, safety: false, validity: false };
45+
46+
/// Assume only that alignment conditions are met.
47+
#[unstable(feature = "transmutability", issue = "99571")]
48+
pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING };
49+
50+
/// Assume only that lifetime conditions are met.
51+
#[unstable(feature = "transmutability", issue = "99571")]
52+
pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING };
53+
54+
/// Assume only that safety conditions are met.
55+
#[unstable(feature = "transmutability", issue = "99571")]
56+
pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING };
57+
58+
/// Assume only that dynamically-satisfiable validity conditions are met.
59+
#[unstable(feature = "transmutability", issue = "99571")]
60+
pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING };
61+
62+
/// Assume both `self` and `other_assumptions`.
63+
#[unstable(feature = "transmutability", issue = "99571")]
64+
pub const fn and(self, other_assumptions: Self) -> Self {
65+
Self {
66+
alignment: self.alignment || other_assumptions.alignment,
67+
lifetimes: self.lifetimes || other_assumptions.lifetimes,
68+
safety: self.safety || other_assumptions.safety,
69+
validity: self.validity || other_assumptions.validity,
70+
}
71+
}
72+
73+
/// Assume `self`, excepting `other_assumptions`.
74+
#[unstable(feature = "transmutability", issue = "99571")]
75+
pub const fn but_not(self, other_assumptions: Self) -> Self {
76+
Self {
77+
alignment: self.alignment && !other_assumptions.alignment,
78+
lifetimes: self.lifetimes && !other_assumptions.lifetimes,
79+
safety: self.safety && !other_assumptions.safety,
80+
validity: self.validity && !other_assumptions.validity,
81+
}
82+
}
83+
}
84+
85+
// FIXME(jswrenn): This const op is not actually usable. Why?
86+
// https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
87+
#[unstable(feature = "transmutability", issue = "99571")]
88+
#[rustc_const_unstable(feature = "transmutability", issue = "99571")]
89+
impl const core::ops::Add for Assume {
90+
type Output = Assume;
91+
92+
fn add(self, other_assumptions: Assume) -> Assume {
93+
self.and(other_assumptions)
94+
}
95+
}
96+
97+
// FIXME(jswrenn): This const op is not actually usable. Why?
98+
// https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
99+
#[unstable(feature = "transmutability", issue = "99571")]
100+
#[rustc_const_unstable(feature = "transmutability", issue = "99571")]
101+
impl const core::ops::Sub for Assume {
102+
type Output = Assume;
103+
104+
fn sub(self, other_assumptions: Assume) -> Assume {
105+
self.but_not(other_assumptions)
106+
}
43107
}

0 commit comments

Comments
 (0)