Skip to content

Associated type equality in trait bounds not properly matched #37883

Description

@sebcrozet

I might be missing something but I believe the following (playpen) should compile but does not:

use std::ops::Mul;


fn main() {
}


trait Ring { }
trait Real: Ring { }

trait Module: Sized + Mul<<Self as Module>::Ring, Output = Self> {
    type Ring: Ring;
}

trait EuclideanSpace {
    type Coordinates: Module<Ring = Self::Real>;
    type Real:        Real;
}


pub trait Translation<E: EuclideanSpace> {
    fn to_vector(&self) -> E::Coordinates;

    fn powf(&self, n: <E::Coordinates as Module>::Ring) -> E::Coordinates {
        self.to_vector() * n
    }
}

In self.to_vector() * n, the compiler seems to understand that <E::Coordinates as Module>::Ring> is the same thing as E::Real but fails to applies the Mul<<Self as Module>::Ring, Output = Self> trait from Module.

Activity

  1. added a commit that references this issue on Dec 4, 2016
  2. Twey commented on Mar 16, 2017

    @Twey
    Contributor

    Smaller test case (Playground):

    pub trait Foo<T> { }
    pub trait Bar: Foo<<Self as Bar>::Quux> { type Quux; }
    pub trait Arthur { type Wibble: Bar<Quux=()>; }
    pub fn assert_is_foo<A: Foo<()>>() { }
    pub fn assert_is_bar<B: Bar<Quux=()>>() { }
    
    pub fn test<A: Arthur>() {
        let _: <A::Wibble as Bar>::Quux = ();
        assert_is_bar::<A::Wibble>();
        assert_is_foo::<A::Wibble>(); // the trait bound `<A as Arthur>::Wibble: Foo<()>` is not satisfied
    }
    

    This code (in the body of test) knows that A::Wibble: Bar and that <A::Wibble as Bar>::Quux = (), but not that A::Wibble: Foo<()>.

  3. estebank commented on Nov 5, 2019

    @estebank
    Contributor

    Current output:

    error[E0277]: cannot multiply `<E as EuclideanSpace>::Real` to `<E as EuclideanSpace>::Coordinates`
      --> src/main.rs:25:26
       |
    24 |     fn powf(&self, n: <E::Coordinates as Module>::Ring) -> E::Coordinates {
       |                                                                          - help: consider further restricting the associated type: `where <E as EuclideanSpace>::Coordinates: std::ops::Mul<<E as EuclideanSpace>::Real>`
    25 |         self.to_vector() * n
       |                          ^ no implementation for `<E as EuclideanSpace>::Coordinates * <E as EuclideanSpace>::Real`
       |
       = help: the trait `std::ops::Mul<<E as EuclideanSpace>::Real>` is not implemented for `<E as EuclideanSpace>::Coordinates`
    
    error[E0308]: mismatched types
      --> src/main.rs:25:28
       |
    25 |         self.to_vector() * n
       |                            ^ expected Module::Ring, found EuclideanSpace::Real
       |
       = note: expected type `<<E as EuclideanSpace>::Coordinates as Module>::Ring`
                  found type `<E as EuclideanSpace>::Real`
    
    error[E0277]: the trait bound `<A as Arthur>::Wibble: Foo<()>` is not satisfied
      --> src/main.rs:10:5
       |
    4  | pub fn assert_is_foo<A: Foo<()>>() { }
       |        -------------    ------- required by this bound in `assert_is_foo`
    ...
    7  | pub fn test<A: Arthur>() {
       |                         - help: consider further restricting the associated type: `where <A as Arthur>::Wibble: Foo<()>`
    ...
    10 |     assert_is_foo::<A::Wibble>();
       |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<()>` is not implemented for `<A as Arthur>::Wibble`
    
  4. added
    E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.
    on Feb 2, 2021
  5. estebank commented on Feb 2, 2021

    @estebank
    Contributor

    This now compiles.

  6. added 2 commits that reference this issue on Feb 2, 2021
    5f1616d
    81c64b3
  7. added a commit that references this issue on Sep 6, 2022
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-associated-itemsArea: Associated items (types, constants & functions)A-lazy-normalizationArea: Lazy normalization (tracking issue: #60471)A-trait-systemArea: Trait systemC-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions