Skip to content

Associated type behind a *mut unecessarily results in invariant subtyping #68375

Open
@gmorenz

Description

@gmorenz

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-type-systemArea: Type systemT-langRelevant to the language team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions