Open
Description
This code fails to compile:
pub trait Append<T> {
type Appended;
}
pub trait Proc {
type Item;
type Tail;
fn process_item<P>(&mut self, partial: P)
where
P: Append<Self::Item>,
P::Appended: Append<Self::Tail>;
}
struct Read;
impl Proc for Read {
type Item = i32;
type Tail = i64;
fn process_item<P>(&mut self, partial: P)
where
P: Append<Self::Item>,
P::Appended: Append<Self::Tail>,
{
}
}
error[E0277]: the trait bound `P: Append<i32>` is not satisfied
--> src/lib.rs:19:5
|
19 | / fn process_item<P>(&mut self, partial: P)
20 | | where
21 | | P: Append<Self::Item>,
22 | | P::Appended: Append<Self::Tail>,
23 | | {
24 | |
25 | | }
| |_____^ the trait `Append<i32>` is not implemented for `P`
|
= help: consider adding a `where P: Append<i32>` bound
The error is confusing because Self::Item
is i32
. Furthermore, changing the bound on P
to the suggested bound (setting aside the fact that this is a trait impl so imposing additional bounds isn't necessarily appropriate) yields an even more confusing error:
error[E0277]: the trait bound `P: Append<i32>` is not satisfied
--> src/lib.rs:19:5
|
19 | / fn process_item<P>(&mut self, partial: P)
20 | | where
21 | | P: Append<i32>,
22 | | P::Appended: Append<Self::Tail>,
23 | | {
24 | |
25 | | }
| |_____^ the trait `Append<i32>` is not implemented for `P`
|
= help: consider adding a `where P: Append<i32>` bound
error[E0276]: impl has stricter requirements than trait
--> src/lib.rs:19:5
|
8 | / fn process_item<P>(&mut self, partial: P)
9 | | where
10 | | P: Append<Self::Item>,
11 | | P::Appended: Append<Self::Tail>;
| |________________________________________- definition of `process_item` from trait
...
19 | / fn process_item<P>(&mut self, partial: P)
20 | | where
21 | | P: Append<i32>,
22 | | P::Appended: Append<Self::Tail>,
23 | | {
24 | |
25 | | }
| |_____^ impl has extra requirement `P: Append<i32>`
error: aborting due to 2 previous errors
Adding an additional type parameter to the fn and using that as the bound on P::Appended
appears to work fine, and i think it is semantically equivalent (although applying the bound directly to the associated type is cleaner IMO):
pub trait Append<T> {
type Appended;
}
pub trait Proc {
type Item;
type Tail;
fn process_item<P, T>(&mut self, partial: P)
where
P: Append<Self::Item, Appended = T>,
T: Append<Self::Tail>;
}
struct Read;
impl Proc for Read {
type Item = i32;
type Tail = i64;
fn process_item<P, T>(&mut self, partial: P)
where
P: Append<i32, Appended = T>,
T: Append<Self::Tail>,
{
}
}
Should the original code compile? If not, the error message (and suggested fix) is monumentally unhelpful. Otherwise, if it should compile, this looks like a compiler bug.