Skip to content

HRTB with GAT behaving differently in associated type bound vs where clause #90573

Open
@malthesr

Description

@malthesr

I tried this code:

#![feature(generic_associated_types)]

pub trait Iterable {
    type Iter<'a>: Iterator<Item = Self::Item<'a>>
    where
        Self: 'a;
    type Item<'a>
    where
        Self: 'a;

    fn iter(&self) -> Self::Iter<'_>;
}

trait Bar {
    type BarType;
    type BarItem<'a>;
}

trait Baz: Bar
where
    Self::BarType: for<'a> Iterable<Item<'a> = Self::BarItem<'a>>,
{
}

(Playground.)

I expected to see this happen: I had expected compilation to succeed.

Instead, this happened: Compilation fails with the error message below.

Error message
error[E0311]: the associated type `<Self as Bar>::BarType` may not live long enough
  --> src/lib.rs:19:1
   |
19 | / trait Baz: Bar
20 | | where
21 | |     Self::BarType: for<'a> Iterable<Item<'a> = Self::BarItem<'a>>,
22 | | {
23 | | }
   | |_^
   |
   = help: consider adding an explicit lifetime bound `<Self as Bar>::BarType: 'a`...
   = note: ...so that the type `<Self as Bar>::BarType` will meet its required lifetime bounds...
note: ...that is required by this bound
  --> src/lib.rs:21:37
   |
21 |     Self::BarType: for<'a> Iterable<Item<'a> = Self::BarItem<'a>>,
   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Everything seems to work fine if instead I provide the HRTB on an associated type instead, like so:

trait Foo {
    type FooType: for<'a> Iterable<Item<'a> = Self::FooItem<'a>>;
    type FooItem<'a>;
}

I was surprised by this difference, so I initially opened a question about this on the rust-lang users forum. There, people more knowledgeable than I suggested that this might be a GAT-related bug, with some uncertainty as to whether this is the same issue as in #89196.

Meta

rustc --version --verbose:

rustc 1.58.0-nightly (baba6687d 2021-11-03)
binary: rustc
commit-hash: baba6687df3e83fdb15cc6ec239b4a1c75a30505
commit-date: 2021-11-03
host: x86_64-unknown-linux-gnu
release: 1.58.0-nightly
LLVM version: 13.0.0

Activity

jackh726

jackh726 commented on Feb 7, 2022

@jackh726
Member

This really comes down to the difference between what we imply and what we just require. I know the lang team discussed this general distinction a bit for some other GATs thing.

Before I mark this a non-blocking, I'd like to think about the "future" here; particularly, are we allowed to eventually make where clauses "implied"?

added a commit that references this issue on Sep 13, 2022

Auto merge of rust-lang#96709 - jackh726:gats-stabilization, r=compil…

added a commit that references this issue on Jan 24, 2023

Auto merge of rust-lang#96709 - jackh726:gats-stabilization, r=compil…

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Jan 6, 2024
added
A-GATsArea: Generic associated types (GATs)
A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)
and removed
C-bugCategory: This is a bug.
on Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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)T-compilerRelevant to the compiler 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

        Participants

        @Enselic@fmease@malthesr@jackh726

        Issue actions

          HRTB with GAT behaving differently in associated type bound vs where clause · Issue #90573 · rust-lang/rust