Accepting nested method calls with an `&mut self` receiver

Sure enough.

And as we're talking about 2-phase lifetimes, let me propose something that should "fix" this (with a change to Index):

  1. Add the possibility of "not-yet-active" lifetimes (ATM every lifetime has been active at some point). Find some hopefully-unhacky way of integrating this with lifetime inference.
  2. Add a Ref2Φ<'immut, 'mutbl, T> where T: 'immut, 'immut: 'mutbl reference type. Note that
&'a T ~ Ref2Φ<'a, 'empty, T>
&'a mut T ~ Ref2Φ<'a, 'a, T>

Where the equivalence/coercion/whatever can't be made to an eqty because you can't dispatch on lifetimes, but they should be at least coercions. 3) Make all borrows biphase. A borrowck conflict happens when the immutable segment of one Ref2Φ conflicts with the mutable segment of another. Reborrowing works like usual. 4) PROFIT:

Vec::push(&mut v, Vec::len(&v)) // this works regardless of the desugaring
Vec::deref_mut(&mut v)[0] = Vec::len(&v); // still does not work
  1. BONUS: make Ref2Φ and NYA lifetimes user-accessible (bikeshed about the syntax until you get tired), and define:
trait Deref2Φ : Deref {
    fn deref2Φ<'immut, #[may_dangle] 'mutbl>(self: Ref2Φ<'immut, 'mutbl, Self>)
        -> Ref2Φ<'immut, 'mutbl, Self::Target>;
}

trait Index2Φ<Idx: ?Sized> : Index<Idx> {
    fn index2Φ<'immut, #[may_dangle] 'mutbl>(self: Ref2Φ<'immut, 'mutbl, Self>,
                                             index: Idx)
        -> Ref2Φ<'immut, 'mutbl, Self::Output>;
}
  1. BONUS: profit even more, because now you can have a single unified Index/IndexMut implementation (for backwards compat, forward both to Index2Φ) and "everything" works.
1 Like