Skip to content

NLL: investigate ascription when a _ wildcard tyvar is repeated #55748

Closed
@pnkfelix

Description

@pnkfelix

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...

Metadata

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)NLL-soundWorking towards the "invalid code does not compile" goalP-highHigh priority

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions