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 ) ]
2722pub 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