-
Couldn't load subscription status.
- Fork 13.9k
Description
Consider the following code (playpen)
pub trait Data {
type Elem;
}
pub struct ViewRepr<A>(A);
impl<'a, A> Data for ViewRepr<&'a A> {
type Elem = A;
}
pub struct ArrayBase<D: Data> {
ptr: *mut D::Elem,
// ptr: *mut f32,
d: D,
}
pub fn cast_array_view<'shorter, 'longer: 'shorter>(
input: ArrayBase<ViewRepr<&'longer f32>>
) -> ArrayBase<ViewRepr<&'shorter f32>> {
input
}cast_array_view fails to compile with the first definition of ptr, and succeeds with the second, despite the two functions being apparently identical.
I think the reason this is happening is most likely related to the fact that subtyping of *mut pointers is invariant on the type of their parameter, and structs containing *mut T pointers are invariant with respect to T. Since D::Elem is being stored behind a *mut pointer rustc has decided that ArrayBase is invariant with respect to D, instead of D::Elem.
PS: Thanks to /u/Patryk27 on reddit for looking at this and pointing me in the direction of the variance docs.