Skip to content

E0277 (bound not satisfied) for bound on generic associated types when combined with HRTB #88460

Open
@udoprog

Description

@udoprog

I tried this code:

#![feature(generic_associated_types)]

pub trait Marker {}

pub trait Trait {
    type Assoc<'a>;
}

fn test<T>(value: T)
where
    T: Trait,
    for<'a> T::Assoc<'a>: Marker,
{
}

impl Marker for () {}

struct Foo;

impl Trait for Foo {
    type Assoc<'a> = ();
}

fn main() {
    test(Foo);
}

I expected it to compile since T::Assoc<'a> to my understanding does implement Marker when T is Foo.

Instead we get this error:

error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
  --> test.rs:25:5
   |
25 |     test(Foo);
   |     ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
   |
note: required by a bound in `test`
  --> test.rs:12:27
   |
9  | fn test<T>(value: T)
   |    ---- required by a bound in this
...
12 |     for<'a> T::Assoc<'a>: Marker,
   |                           ^^^^^^ required by this bound in `test`

Alternatives

An option is lift the 'a bound to test, but that potentially causes other issues down the line like this (playground):

#![feature(generic_associated_types)]

pub trait Marker {
    fn borrow(&self) -> &Self;
}

pub trait Trait {
    type Assoc<'a>;

    fn assoc(&self) -> Self::Assoc<'_>;
}

fn test<'a, T>(value: T)
where
    T: 'a + Trait,
    T::Assoc<'a>: Marker,
{
    let assoc = value.assoc();
    assoc.borrow(); // the lifetime for this reborrow ends up being narrow.
}

impl Marker for () {
    fn borrow(&self) -> &Self {
        self
    }
}

struct Foo;

impl Trait for Foo {
    type Assoc<'a> = ();

    fn assoc(&self) -> Self::Assoc<'_> {
        ()
    }
}

fn main() {
    test(Foo);
}

Error:

error[E0597]: `value` does not live long enough
  --> test.rs:18:17
   |
13 | fn test<'a, T>(value: T)
   |         -- lifetime `'a` defined here
...
18 |     let assoc = value.assoc();
   |                 ^^^^^--------
   |                 |
   |                 borrowed value does not live long enough
   |                 argument requires that `value` is borrowed for `'a`
19 |     assoc.borrow();
20 | }
   | - `value` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `audio` due to previous error

Meta

rustc --version --verbose:

rustc 1.56.0-nightly (5eacec9ec 2021-08-28)
binary: rustc
commit-hash: 5eacec9ec7e112a0de1011519a57c45586d58414
commit-date: 2021-08-28
host: x86_64-pc-windows-msvc
release: 1.56.0-nightly
LLVM version: 13.0.0

I somewhat expected this to be addressed by #56556 #85499 given there there appears to be some overlap with the list of available bugs, ,but that doesn't seem to be the case as of 2021-08-28 nightly (assuming it's in there).

I also apologize if this is a duplicate. I tried my best to grok the existing set of issues to see if this was applicable to one of them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)GATs-triagedIssues using the `generic_associated_types` feature that have been triagedS-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions