What I was originally going for was "the longest `'a`

such that `Super: 'a`

holds". But I'm now realizing that this doesn't work. For `struct Foo<'a>(&'a mut i32, &'static mut i32);`

, the lifetime of `Foo<'a>`

is `'a`

, but it must remain borrowed for `'static`

.

# Revised design

Here's what I think we have to do instead. First, we redefine `Reborrow`

like so:

```
#[lang = "reborrow"]
#[marker]
pub trait Reborrow<'a> {}
impl<'a, T: Copy> Reborrow<'a> for T { }
impl<'a, T: ?Sized> Reborrow<'a> for &'a mut T { }
impl<'short, 'long: 'short, T: Reborrow<'short>> Reborrow<'long> for T { }
```

- A type can implement
`Reborrow<'a>`

iff the types of all its fields implement`Reborrow<'a>`

. - Other requirements are unchanged.

## New semantics

For any two types `Super`

and `Sub`

, such that `Super`

is a supertype of `Sub`

:

```
fn foo(arg: Sub) {
let local: Super = arg;
// HERE
}
```

At the point marked `HERE`

:

- If
`Sub`

implements`Copy`

,`arg`

remains fully accessible. - If
`Sub`

implements neither`Copy`

nor`Reborrow`

,`arg`

is permanently inaccessible. **New:**if`Sub`

implements`Reborrow`

(lifetime does not matter) but not`Copy`

, and`Super: Reborrow<'a>`

(pick the shortest`'a`

for which this holds),`arg`

is inaccessible for`'a`

.

Because `Reborrow`

's semantics are defined in terms of subtyping, we get proper handling of invariance "for free".