@@ -56,6 +56,7 @@ mod def {
56
56
/// [`I::Validity`](invariant::Validity).
57
57
// SAFETY: `PtrInner<'a, T>` is covariant over `'a` and `T`.
58
58
ptr : PtrInner < ' a , T > ,
59
+ _variance : PhantomData < <I :: Aliasing as Aliasing >:: Variance < ' a , T > > ,
59
60
_invariants : PhantomData < I > ,
60
61
}
61
62
@@ -93,7 +94,7 @@ mod def {
93
94
let ptr = unsafe { PtrInner :: new ( ptr) } ;
94
95
// SAFETY: The caller has promised (in 6 - 8) to satisfy all safety
95
96
// invariants of `Ptr`.
96
- Self { ptr, _invariants : PhantomData }
97
+ Self { ptr, _variance : PhantomData , _invariants : PhantomData }
97
98
}
98
99
99
100
/// Constructs a new `Ptr` from a [`PtrInner`].
@@ -111,7 +112,7 @@ mod def {
111
112
pub ( super ) const unsafe fn from_inner ( ptr : PtrInner < ' a , T > ) -> Ptr < ' a , T , I > {
112
113
// SAFETY: The caller has promised to satisfy all safety invariants
113
114
// of `Ptr`.
114
- Self { ptr, _invariants : PhantomData }
115
+ Self { ptr, _variance : PhantomData , _invariants : PhantomData }
115
116
}
116
117
117
118
/// Converts this `Ptr<T>` to a [`PtrInner<T>`].
@@ -152,6 +153,12 @@ pub mod invariant {
152
153
/// Is `Self` [`Exclusive`]?
153
154
#[ doc( hidden) ]
154
155
const IS_EXCLUSIVE : bool ;
156
+
157
+ /// A type which has the correct variance over `'a` and `T` for this
158
+ /// aliasing invariant. `Ptr` stores a `<I::Aliasing as
159
+ /// Aliasing>::Variance<'a, T>` to inherit this variance.
160
+ #[ doc( hidden) ]
161
+ type Variance < ' a , T : ' a + ?Sized > ;
155
162
}
156
163
157
164
/// The alignment invariant of a [`Ptr`][super::Ptr].
@@ -172,6 +179,16 @@ pub mod invariant {
172
179
pub enum Any { }
173
180
impl Aliasing for Any {
174
181
const IS_EXCLUSIVE : bool = false ;
182
+ // SAFETY: Since we don't know what aliasing model this is, we have to
183
+ // be conservative. Invariance is strictly more restrictive than any
184
+ // other variance model, so this can never cause soundness issues.
185
+ //
186
+ // `fn() -> T` and `fn(T) -> ()` are covariant and contravariant in `T`,
187
+ // respectively. [1] Thus, `fn(T) -> T` is invariant in `T`. Thus,
188
+ // `fn(&'a T) -> &'a T` is invariant in `'a` and `T`.
189
+ //
190
+ // [1] https://doc.rust-lang.org/1.81.0/reference/subtyping.html#variance
191
+ type Variance < ' a , T : ' a + ?Sized > = fn ( & ' a T ) -> & ' a T ;
175
192
}
176
193
impl Alignment for Any { }
177
194
impl Validity for Any { }
@@ -188,6 +205,7 @@ pub mod invariant {
188
205
pub enum Shared { }
189
206
impl Aliasing for Shared {
190
207
const IS_EXCLUSIVE : bool = false ;
208
+ type Variance < ' a , T : ' a + ?Sized > = & ' a T ;
191
209
}
192
210
impl Reference for Shared { }
193
211
@@ -199,6 +217,7 @@ pub mod invariant {
199
217
pub enum Exclusive { }
200
218
impl Aliasing for Exclusive {
201
219
const IS_EXCLUSIVE : bool = true ;
220
+ type Variance < ' a , T : ' a + ?Sized > = & ' a mut T ;
202
221
}
203
222
impl Reference for Exclusive { }
204
223
0 commit comments