Some Name
Some Name

Reputation: 9521

Trait bound is not satisfied when using associated type

I'm trying to design a road-tracking application and came up with the following traits structure (available on playground):

pub trait Source: Sized {
    type Path: Path<Source = Self>;
}

pub trait Destination<S: Source>{ }

pub trait Path {
    type Source: Source;
    type Destination: Destination<Self::Source>;
}

The thing is it fails to compile with the error

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `<<Self as Source>::Path as Path>::Destination: Destination<Self>` is not satisfied
 --> src/lib.rs:2:16
  |
2 |     type Path: Path<Source = Self>;
  |                ^^^^^^^^^^^^^^^^^^^ the trait `Destination<Self>` is not implemented for `<<Self as Source>::Path as Path>::Destination`
...
7 | pub trait Path {
  |           ---- required by a bound in this
8 |     type Source: Source;
9 |     type Destination: Destination<Self::Source>;
  |                       ------------------------- required by this bound in `Path`
  |
help: consider further restricting the associated type
  |
1 | pub trait Source: Sized where <<Self as Source>::Path as Path>::Destination: Destination<Self> {
  |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

This is not clear. I specified the associated type bound as type Path: Path<Source = Self>; which imply a bound on the associated type specified in the error message.

But that should prohibit from implementing with wrong types, not declare it the way it is. Is there a way to fix that?

Upvotes: 0

Views: 963

Answers (1)

Some Name
Some Name

Reputation: 9521

I found a way to fix it by specifying one more associated type, but the reason for the original error is unclear. Here is the working example:

pub trait Source: Sized {
    type Path: Path<Source=Self, Destination=Self::Destination>;
    type Destination: Destination<Self>; // Added associated type
}

pub trait Destination<S: Source>{ }

pub trait Path {
    type Source: Source;
    type Destination: Destination<Self::Source>;
}

Upvotes: 1

Related Questions