Skip to content

Variance not computed for concrete GAT references in struct fields #132198

Open
@branchseer

Description

@branchseer

Similar to #114221 (comment).

I tried this code:

trait Foo {
    type Ref<'a>;
}

struct Bar;
impl Foo for Bar {
    type Ref<'a> = &'a u8;
}

struct Baz<'a>(<Bar as Foo>::Ref<'a>);

fn f<'a>(s: Baz<'static>) { let _: Baz<'a> = s; }

I expected to see this happen: lifetime check passes

Instead, this happened:

error: lifetime may not live long enough
  --> src/main.rs:12:36
   |
12 | fn f<'a>(s: Baz<'static>) { let _: Baz<'a> = s; }
   |      -- lifetime `'a` defined here ^^^^^^^ type annotation requires that `'a` must outlive `'static`
   |
   = note: requirement occurs because of the type `Baz<'_>`, which makes the generic argument `'_` invariant
   = note: the struct `Baz<'a>` is invariant over the parameter `'a`
   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

Although lifetime variance does get computed when the GAT type is directly referenced in the parameter type:

fn f<'a>(s: <Bar as Foo>::Ref<'static>) { let _: <Bar as Foo>::Ref<'a> = s; } // check passes

Edit:

Sames limitation on types:

trait Foo {
    type GAT<T>;
}

struct Bar;
impl Foo for Bar {
    type GAT<T> = T;
}


fn f<'a>(s: <Bar as Foo>::GAT<&'static ()>) { let _:  <Bar as Foo>::GAT<&'a ()> = s; } // this passes the check

struct Baz<T>(<Bar as Foo>::GAT<T>);
fn f1<'a>(s: Baz<&'static ()>) { let _: Baz<&'a ()> = s; } // but this doesn't

Meta

rustc --version --verbose:

rustc 1.84.0-nightly (c1db4dc24 2024-10-25)
binary: rustc
commit-hash: c1db4dc24267a707409c9bf2e67cf3c7323975c8
commit-date: 2024-10-25
host: aarch64-apple-darwin
release: 1.84.0-nightly
LLVM version: 19.1.1
Backtrace

<backtrace>

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)A-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)C-discussionCategory: Discussion or questions that doesn't represent real issues.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions