Skip to content

Specialization: allow some projection when typechecking an impl #32483

Open
@aturon

Description

@aturon

The following example currently fails to compile:

pub trait Foo {
    type TypeA;
    type TypeB: Bar<Self::TypeA>;
}

pub trait Bar<T> {
}

pub struct ImplsBar;
impl<T> Bar<T> for ImplsBar {
}

impl<T> Foo for T {
    type TypeA = u8;
    default type TypeB = ImplsBar;
}

with message:

<anon>:15:9: 15:12 error: the trait `Bar<u8>` is not implemented for the type `<T as Foo>::TypeB` [E0277]
<anon>:15 impl<T> Foo for T {

The problem seems to be that the type checker is using a projection of TypeB to actually check the impl's definition of TypeB against its bounds. But because it's marked default, the item cannot be projected.

In general, we should loosen up the rules on projections when checking an impl -- but doing so soundly is tricky. It clearly doesn't work to just allow all projections to go through (a la "trans mode"), because in general items could be replaced in more specialized impls. But it does seem reasonable to allow projecting the current item being impled (for any trait ref covered by the impl), because any specialization of that item will be rechecked under its own constraints.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationA-trait-systemArea: Trait systemC-bugCategory: This is a bug.F-associated_type_defaults`#![feature(associated_type_defaults)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions