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

**URL:** https://internals.rust-lang.org/t/accepting-nested-method-calls-with-an-mut-self-receiver/4588
**Category:** language design
**Created:** [January 10, 2017, 5:39pm UTC](https://internals.rust-lang.org/t/accepting-nested-method-calls-with-an-mut-self-receiver/4588 "2017-01-10T17:39:07Z")
**Posts on this page:** 1
**Showing post:** 24

<div class="post-metadata">

### Author: ![arielb1](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/arielb1/32/3044_2.png) [@arielb1](https://internals.rust-lang.org/u/arielb1)
#### Post date: [January 11, 2017, 12:39pm UTC](https://internals.rust-lang.org/t/accepting-nested-method-calls-with-an-mut-self-receiver/4588/24 "2017-01-11T12:39:19Z")

</div>

> [@nikomatsakis](#):
>
> To be more explicit, you mean that upgradable borrows (or "borrowing for the future", as I was calling it, though it occurs to me that "reservations" might be a clearer term) will still report an error for `vec[vec.len() - 1]`? I agree, that seems true. (And, more generally, will be true for any deref/index impl.)

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

```rust
&'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:

```rust
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:

```rust
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.

---

_[View the full topic](https://internals.rust-lang.org/t/accepting-nested-method-calls-with-an-mut-self-receiver/4588)._
