Consider a function
fn clear_non_empty<T>(collection: &mut Vec<T>) {
if !collection.is_empty() {
collection.clear()
}
}
it compiles just fine, and if I try to generalize it for some collection
trait IsEmpty {
fn is_empty(&self) -> bool;
}
trait Clear {
fn clear(&mut self);
}
fn clear_non_empty<'a, Collection: Clear + IsEmpty>(collection: &'a mut Collection) {
if !collection.is_empty() {
collection.clear()
}
}
I also have no problems. But if I change traits to
trait IsEmpty {
fn is_empty(self) -> bool;
}
trait Clear {
fn clear(self);
}
fn clear_non_empty<'a, Collection>(collection: &'a mut Collection)
where
&'a mut Collection: Clear,
&'a Collection: IsEmpty,
{
if !collection.is_empty() {
collection.clear()
}
}
I'm getting
error[E0502]: cannot borrow `*collection` as mutable because it is also borrowed as immutable
--> src/lib.rs:15:9
|
9 | fn clear_non_empty<'a, Collection>(collection: &'a mut Collection)
| -- lifetime `'a` defined here
...
14 | if !collection.is_empty() {
| ---------------------
| |
| immutable borrow occurs here
| argument requires that `*collection` is borrowed for `'a`
15 | collection.clear()
| ^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
For more information about this error, try `rustc --explain E0502`.
which I do not understand, why traits with methods accepting references to self work and traits implemented for references with methods accepting self do not?