Open
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.