Skip to content

Associated type equality in trait bounds not properly matched #37883

@sebcrozet

Description

@sebcrozet
Contributor

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

added a commit that references this issue on Dec 4, 2016
Twey

Twey commented on Mar 16, 2017

@Twey

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<()>.

estebank

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`
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
estebank

estebank commented on Feb 2, 2021

@estebank
Contributor

This now compiles.

7 remaining items

Loading
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

      Participants

      @Twey@estebank@sebcrozet@Mark-Simulacrum@apasel422

      Issue actions

        Associated type equality in trait bounds not properly matched · Issue #37883 · rust-lang/rust