Playground
The code:
trait FooElem: Sized {}
trait FooExt<T: FooElem>: Sized {
fn do_stuff(&mut self);
}
impl<T: FooElem, E: ExactSizeIterator<Item=T>> FooExt<T> for E {
fn do_stuff(&mut self) {
//empty
}
}
trait Bar {
fn barred(&mut self);
}
impl<T: FooElem> Bar for Vec<T> {
fn barred(&mut self) {
FooExt::do_stuff(&mut self.into_iter())
}
}
I get the error:
error[E0277]: the trait bound `&mut T: FooElem` is not satisfied
--> src/main.rs:21:9
|
21 | FooExt::do_stuff(&mut self.into_iter())
| ^^^^^^^^^^^^^^^^ the trait `FooElem` is not implemented for `&mut T`
|
= note: required because of the requirements on the impl of `FooExt<&mut T>` for `std::slice::IterMut<'_, T>`
note: required by `FooExt::do_stuff`
--> src/main.rs:6:5
|
6 | fn do_stuff(&mut self);
| ^^^^^^^^^^^^^^^^^^^^^^^
Any ideas to help?
The compiler tells you the problem:
The most literal solution is to require that a mutable reference implements the trait:
impl Bar for Vec<T>
where
for<'b> &'b mut T: FooElem,
{
Your 'a
is unneeded.
I'd also write it as
impl<I> FooExt<I::Item> for I
where
I: ExactSizeIterator,
I::Item: FooElem,
{
fn do_stuff(&mut self) {
//empty
}
}
Note that the type of self
is &mut Vec<T>
. Calling into_iter()
on that gets you an iterator over &mut T
items, just like if you'd called Vec::iter_mut()
. Then your FooExt
implementation is demanding that these &mut T
items must implement FooElem
, which they do not -- only T
does.
If you wanted to move the actual T
items out of the Vec
, then drain()
might work better.
1 Like
Yep. Or you could change your trait to accept self
:
trait FooElem {}
trait FooExt<T>
where
T: FooElem,
{
fn do_stuff(self);
}
impl<I> FooExt<I::Item> for I
where
I: ExactSizeIterator,
I::Item: FooElem,
{
fn do_stuff(self) {
//empty
}
}
trait Bar {
fn barred(self);
}
impl<T> Bar for Vec<T>
where
T: FooElem,
{
fn barred(self) {
FooExt::do_stuff(self.into_iter())
}
}
And implement your trait for both direct values as well as references to values.