Sure enough.
And as we're talking about 2-phase lifetimes, let me propose something that should "fix" this (with a change to Index
):
- 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.
- 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
- 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>;
}
- BONUS: profit even more, because now you can have a single unified
Index
/IndexMut
implementation (for backwards compat, forward both toIndex2Φ
) and "everything" works.