Conflicts and type parameters

What if a lifetime parameter is used in multiple spots with different variances? For example:

#![allow(dead_code)]
fn main() {}

use std::cell::Cell;

struct TwoSpots<'a> {
    foo: &'a str,
    bar: Cell<&'a str>,
}

It's as you might expect:

  • If all the uses agree on a particular variance, the parameter has that variance.
  • Otherwise, the parameter defaults to invariant.

And what about this sort of situation?

#![allow(dead_code)]
fn main() {}

struct TypeParams<T, U> {
    t: Vec<T>,
    u: fn(U) -> (),
}

struct LifetimeParams<'a, 'b> {
    nested: TypeParams<&'a str, &'b str>,
}

fn lifetime_check<'a, 'b>(
    x: LifetimeParams<'static, 'b>
) -> LifetimeParams<'a, 'static> {
    x
}

T and U are also annotated with a variance, which is used if they're substituted with a type containing a lifetime parameter. For example:

#![allow(dead_code)]
fn main() {}

struct TypeParams<T, U> {
    t: Vec<T>,
    u: fn(U) -> (),
}

struct LifetimeParams<'a, 'b> {
    nested: TypeParams<&'a str, &'b str>,
}

fn lifetime_check<'a, 'b>(
    x: LifetimeParams<'static, 'b>
) -> LifetimeParams<'a, 'static> {
    x
}

Here, 'a is covariant and 'b is contravariant. Let's test those together:

#![allow(dead_code)]
fn main() {}

struct TypeParams<T, U> {
    t: Vec<T>,
    u: fn(U) -> (),
}

struct LifetimeParams<'a, 'b> {
    nested: TypeParams<&'a str, &'b str>,
}

fn lifetime_check<'a, 'b>(
    x: LifetimeParams<'static, 'b>
) -> LifetimeParams<'a, 'static> {
    x
}