The compiler complains about borrowing as mutable twice even though the return value is thrown away

This is actually the interesting part, because stripping the presented code from all lifetime annotations actually makes the code compile:

trait Trait1 {
    fn f(&mut self);
}

struct S1;
impl Trait1 for S1 {
    fn f(&mut self) { }
}

trait Trait2<T: Trait1> {
    fn field(&mut self) -> &mut T;
    
    fn do_something(&mut self) {
        self.field().f();
        self.field().f();
    }
}

struct S2(S1);
impl Trait2<S1> for S2 {
    fn field(&mut self) -> &mut S1 {
        &mut self.0
    }
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s

When it comes to lifetimes, the usage is also important. If I see a lifetime attached to &(mut) self, my instinct tells me something might be wrong with the calling code, instead. Having some example code that causes the compiler to complain about missing lifetime specification would be needed to investigate further.

See my adventure with lifetime inference problems:

In the end, it turned out that using for<'a> instead of attaching 'a to &(mut) self was the way to go about it. See also: