Description
Spawned off of #55637 (comment)
Update: I had updated this description with a demo. But reading over it now, I don't know why I thought the "demo" had anything to do with this bug as described. That is, I believe demo is showing a bug, but not necessarily this bug...
Nonetheless, I'm not going to spawn off yet another bug quite yet. Instead, I am just going to mark the demo as wrong-headed and try to spend some time exploring _
itself later.
Potentially wrong-headed demo
Here's a demo of the problem (play):
#![allow(dead_code, unused_mut)]
type Pair<T> = (T, T);
fn static_to_a_to_static_through_tyvar<'a>(x: &'a u32, s: &'static u32) -> &'static u32 {
let (mut y, mut _z): Pair<&u32> = (s, x);
// I should be able to add the call to `swap` below at whim based
// on the above type annotation, which should coerce both `s` and
// `x` to `&'1 u32` (and then `'1` should be inferred to be `'a`).
// ::std::mem::swap(&mut y, &mut _z);
// Likewise, the same rules that caused `y` and `_z` to have the
// same `&'1 u32` type should likewise cause a borrow-check error
// at this attempt to return a `&'static u32`.
y
}
fn main() {
static_to_a_to_static_through_tyvar(&3, &4);
}
Under AST-borrowck, it errors.
Under NLL migration mode, it errors.
- Update: no, it was accepted there (just like NLL below).
Under #![feature(nll)]
, is is accepted (play), and should not be.
More details below:
PR #55637 fixes #55552 by ignoring occurrences of _
that it finds as it descends through the type.
A potential problem is that type variables can be repeated, e.g. in a type Foo<T> = (T, T)
and an annotation like Foo<_>
The problem then becomes: Is there some way that could lead to a scenario where one of the occurrences of the type variables gets unified with something that has a lifetime constraint like 'a
, and the other occurrence of the type variable is unchecked (due to #55637) but ends up missing a case where it should have imposed that constraint on an expression whose type has a different incompatible lifetime...