Skip to content

GATs unable to determine if item will live long enough when combined with HRTBs #88683

Closed
@Michael-F-Bryan

Description

@Michael-F-Bryan

(I'm not sure whether this is a diagnostics issue or a bug in the way Generic Associated Types are implemented)

Following this comment on the user forums, I was wondering if it's possible to create a trait which encapsulates the convention that (&foo).into_iter() is equivalent to foo.iter().

This is what I came up with:

#![feature(generic_associated_types)]

trait Iter {
    type Iterator<'a>: Iterator + 'a;
    type Item<'a>: 'a;

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

impl<I> Iter for I
where
    for<'a> &'a I: IntoIterator,
    for<'a> <&'a I as IntoIterator>::IntoIter: Iterator,
{
    type Iterator<'a> where I: 'a = <&'a I as IntoIterator>::IntoIter;
    type Item<'a> where I: 'a = <&'a I as IntoIterator>::Item;

    fn iter(&self) -> Self::Iterator<'_> {
        IntoIterator::into_iter(self)
    }
}

(playground)

Which generates this output:

   Compiling playground v0.0.1 (/playground)
error[E0309]: the parameter type `I` may not live long enough
  --> src/lib.rs:15:5
   |
15 |     type Iterator<'a> where I: 'a = <&'a I as IntoIterator>::IntoIter;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |     |                            |
   |     |                            help: consider adding a where clause: `, I: 'a`
   |     ...so that the type `I` will meet its required lifetime bounds

error[E0309]: the parameter type `I` may not live long enough
  --> src/lib.rs:16:5
   |
16 |     type Item<'a> where I: 'a = <&'a I as IntoIterator>::Item;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |     |                        |
   |     |                        help: consider adding a where clause: `, I: 'a`
   |     ...so that the type `I` will meet its required lifetime bounds

For more information about this error, try `rustc --explain E0309`.

Here I've already said type Iterator<'a> where I: 'a, yet it seems like the compiler isn't able to prove that I will live long enough so it suggests adding another I: 'a to the trait bound. I tried using type Iterator<'a> where I: 'a, I: 'a, ..., I: 'a like the compiler suggests

Meta

This was done on the playground using rustc version:

1.56.0-nightly (2021-09-01 50171c310cd15e1b2d37)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)C-bugCategory: This is a bug.F-generic_associated_types`#![feature(generic_associated_types)]` a.k.a. GATs

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions