Skip to content

Specialization: allow some projection when typechecking an impl #32483

Closed

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.

Activity

  1. aturon commented on Mar 25, 2016

    @aturon
    ContributorAuthor
  2. arielb1 commented on Mar 25, 2016

    @arielb1
    Contributor

    I had the idea of checking the associated type itself rather than normalize(<Self as Trait>::Type) for wf for other reasons.

    Maybe just add where-clauses for the projection. We would also have to fix the bug where ambiguous projections result in no normalization (to avoid the associated type variant of #29859).

  3. oli-obk commented on Jan 25, 2020

    @oli-obk
    Contributor

    Status: No change, except in diagnostics

    error[E0277]: the trait bound `<T as Foo>::TypeB: Bar<u8>` is not satisfied
      --> src/lib.rs:17:5
       |
    5  |     type TypeB: Bar<Self::TypeA>;
       |          ----- associated type defined here
    ...
    15 | impl<T> Foo for T {
       | ------------------ help: consider further restricting the associated type: `where <T as Foo>::TypeB: Bar<u8>`
       | |
       | in this `impl` item
    16 |     type TypeA = u8;
    17 |     default type TypeB = ImplsBar;
       |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar<u8>` is not implemented for `<T as Foo>::TypeB`
    
  4. added
    requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.
    on Jan 25, 2020
  5. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Apr 5, 2023
  6. removed
    requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.
    on Jan 4, 2026
  7. added a commit that references this issue on Aug 5, 2026
    95dff17
  8. added a commit that references this issue on Aug 5, 2026
    0e88174
  9. added 3 commits that reference this issue on Aug 5, 2026
    500d840
    fbb1428
    b3209f1
  10. added a commit that references this issue on Aug 5, 2026
    502ed0f
  11. added a commit that references this issue on Aug 10, 2026
    0276053
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationA-trait-systemArea: Trait systemC-bugCategory: This is a bug.T-compilerRelevant to the compiler 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