On Mon, Nov 04, 2013 at 09:00:03AM -0800, Felix S Klock II wrote:
> I've skimmed over section 3.3 of [Altidor et al (PLDI
> 2011)](http://people.cs.umass.edu/~jaltidor/variance_pldi11.pdf).  I
> do not immediately see a simple example of a region parameter that
> will be bivariant *and* useful, but I haven't thought that hard
> about it yet.

I don't think there is a particular use case for such a lifetime
parameter today. I would imagine a lint might be useful to detect such
unnecessary lifetimes, actually.

> I don't mind keeping the enum the way it is, but I'd appreciate it
> if you either explicitly noted whether `Bivariant` is here just to
> keep a nice variance lattice, or if there is a concrete case for
> *region* variance that having it addresses.

It's an interesting point. The primary reason to have bivariant in
there is because it completes the lattice. I was thinking in
particular that we might want to arbitrarily assign all lifetimes that
come out as bivariant to contravariant so as to accommodate #5922.

In particular, if you create a struct like:

    struct VecIterator<'v, T> {
        start: *T, end: *T
    }

then you wind up with `'v` being bivariant in this patch, which means
that there is no particular subtyping relation. What you probably
wanted though was contravariant -- that is, you wanted this to act *as
thought* `start` and `end` had types `&'v T`.

That said, I feel nervous relying on such an ad-hoc rule; it feels
kind of unpredictable, since it's relying on an unstated relationship
between `start` and `'v`. Also, it's not clear to me why `start` and
`end` can't be given the types `&'v T` anyhow, and transmuted to
unsafe pointers as needed. (Shades of @erickt's proposal to assign
lifetimes to unsafe pointers)