@@ -56,6 +56,7 @@ mod def {
5656 /// [`I::Validity`](invariant::Validity).
5757 // SAFETY: `PtrInner<'a, T>` is covariant over `'a` and `T`.
5858 ptr : PtrInner < ' a , T > ,
59+ _variance : PhantomData < <I :: Aliasing as Aliasing >:: Variance < ' a , T > > ,
5960 _invariants : PhantomData < I > ,
6061 }
6162
@@ -93,7 +94,7 @@ mod def {
9394 let ptr = unsafe { PtrInner :: new ( ptr) } ;
9495 // SAFETY: The caller has promised (in 6 - 8) to satisfy all safety
9596 // invariants of `Ptr`.
96- Self { ptr, _invariants : PhantomData }
97+ Self { ptr, _variance : PhantomData , _invariants : PhantomData }
9798 }
9899
99100 /// Constructs a new `Ptr` from a [`PtrInner`].
@@ -111,7 +112,7 @@ mod def {
111112 pub ( super ) const unsafe fn from_inner ( ptr : PtrInner < ' a , T > ) -> Ptr < ' a , T , I > {
112113 // SAFETY: The caller has promised to satisfy all safety invariants
113114 // of `Ptr`.
114- Self { ptr, _invariants : PhantomData }
115+ Self { ptr, _variance : PhantomData , _invariants : PhantomData }
115116 }
116117
117118 /// Converts this `Ptr<T>` to a [`PtrInner<T>`].
@@ -152,6 +153,12 @@ pub mod invariant {
152153 /// Is `Self` [`Exclusive`]?
153154 #[ doc( hidden) ]
154155 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 > ;
155162 }
156163
157164 /// The alignment invariant of a [`Ptr`][super::Ptr].
@@ -172,6 +179,16 @@ pub mod invariant {
172179 pub enum Any { }
173180 impl Aliasing for Any {
174181 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 ;
175192 }
176193 impl Alignment for Any { }
177194 impl Validity for Any { }
@@ -188,6 +205,7 @@ pub mod invariant {
188205 pub enum Shared { }
189206 impl Aliasing for Shared {
190207 const IS_EXCLUSIVE : bool = false ;
208+ type Variance < ' a , T : ' a + ?Sized > = & ' a T ;
191209 }
192210 impl Reference for Shared { }
193211
@@ -199,6 +217,7 @@ pub mod invariant {
199217 pub enum Exclusive { }
200218 impl Aliasing for Exclusive {
201219 const IS_EXCLUSIVE : bool = true ;
220+ type Variance < ' a , T : ' a + ?Sized > = & ' a mut T ;
202221 }
203222 impl Reference for Exclusive { }
204223
0 commit comments