trait Output {
    fn write(&mut self, text: &str);
}
struct DummyOutput {}
impl Output for DummyOutput {
    fn write(&mut self, text: &str) {
        // self does not need to be mut in this reproducer,
        // but it would in the real version
        println!("{}", text);
    }
}
enum EncoderOutput<'a, T> {
    Owned(T),
    Borrowed(&'a mut T),
}
impl<'a, T> AsMut<T> for EncoderOutput<'a, T> {
    fn as_mut(&mut self) -> &mut T {
        match self {
            EncoderOutput::Owned(ref mut o) => o,
            EncoderOutput::Borrowed(b) => b,
        }
    }
}
struct Encoder<'a, O: Output> {
    output: EncoderOutput<'a, O>,
}
impl<'a, O: Output> Encoder<'a, O> {
    // here's the idea:
    // every child instance will have a borrowed output,
    // and always only one level of indirection, i.e.:
    // - root: "&mut O" or "O"
    // - child1: "&mut O"
    // - child2: "&mut O"
    // but never:
    // - childN: "&mut &mut O"
    fn child(&'a mut self) -> Self {
        Encoder {
            output: EncoderOutput::Borrowed(self.output.as_mut()),
        }
    }
}
fn main() {
    let mut enc1 = Encoder {
        output: EncoderOutput::Owned(DummyOutput {}),
    };
    {
        // I know this borrows mutably from enc1
        let mut enc2 = enc1.child();
        // so this will obviously not work:
        // enc1.output.as_mut().write("bar 2b");
        // but this does work:
        enc2.output.as_mut().write("bar 2a");
    } // but then the borrow "enc2" should be dropped here?
    // so why does this fail with:
    // "cannot borrow [...] as mutable more than once"
    enc1.output.as_mut().write("bar 3");
}
error[E0499]: cannot borrow `enc1.output` as mutable more than once at a time
  --> src/main.rs:68:5
   |
57 |         let mut enc2 = enc1.child();
   |                        ---- first mutable borrow occurs here
...
68 |     enc1.output.as_mut().write("bar 3");
   |     ^^^^^^^^^^^
   |     |
   |     second mutable borrow occurs here
   |     first borrow later used here
My instinct tells me this fails because the lifetime of the borrow in the Encoder returned by child() has the same lifetime as the "parent" - but I don't see a way to decouple the lifetimes, even though the returned value should clearly have a smaller-or-equal lifetime than the parent, since it can be dropped beforehand.
I did try a version without the EncoderOutput first as well, just having a &mut O directly in Encoder, but the problem was the same.
My line of thought why this should work: When the scope in main() ends, enc2 is dropped, and the implicit Drop impl for it runs, which cleans up the EncoderOutput::Borrowed and the reference within, thus leaving no other &mut ref to enc1, and enc1 can be mutably borrowed again.
Where am I going wrong with this?
 
     
    