Skip to content

GAT: Surprising lifetime mismatch / mismatched types (depending on GAT being Sized) #92798

Open
@JanBeh

Description

@JanBeh

I tried this code:

#![feature(generic_associated_types)]

trait Machine {
    type Datum<'a>;
}

trait MaybeStringMap
where
    Self: Sized, // comment-out to make code compile
{
}

trait HasStringMap: Machine {
    fn new_string_map<'a, I>(&self, entries: I) -> ()
    where
        I: IntoIterator<Item = Self::Datum<'a>>,
        <Self as Machine>::Datum<'static>: MaybeStringMap,
    {
        let mut _x = entries.into_iter();
        let _ = _x.next(); // or comment-out here to make code compile
    }
}

(Playground)

I expected the code to be valid.

Instead, I got the following compiler error:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/lib.rs:20:20
   |
20 |         let _ = _x.next(); // or comment-out here to make code compile
   |                    ^^^^ lifetime mismatch
   |
   = note: expected type `<<Self as Machine>::Datum<'a> as Sized>`
              found type `<<Self as Machine>::Datum<'static> as Sized>`
note: the lifetime `'a` as defined here...
  --> src/lib.rs:14:23
   |
14 |     fn new_string_map<'a, I>(&self, entries: I) -> ()
   |                       ^^
   = note: ...does not necessarily outlive the static lifetime

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

Meta

On Playground with version:

1.60.0-nightly (2022-01-10 89b9f7b284aacc5f8613)

But error also happens on my local machine with:
rustc --version --verbose:

rustc 1.59.0-nightly (cfa4ac66c 2022-01-06)

Further info

Maybe this bug is solved by #92191?

@QuineDot provided the following example, which might also serve as an additional test case:

#![feature(generic_associated_types)]

trait StandaloneGat {
    type Datum<'a>;
}

trait MaybeSized {}
trait DefinitelySized: MaybeSized + Sized {}

trait Example: StandaloneGat {
    // Works
    fn maybe_sized<'a, I>(&self, into: I) -> Self::Datum<'a>
    where
        I: Into<Self::Datum<'a>>,
        Self::Datum<'static>: MaybeSized,
    {
        into.into()
    }

    // Fails    
    fn definitely_sized<'a, I>(&self, into: I) -> Self::Datum<'a>
    where
        I: Into<Self::Datum<'a>>,
        Self::Datum<'static>: Sized,
    {
        into.into() // or self.maybe_sized()
    }
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/lib.rs:23:12
   |
23 |         I: Into<Self::Datum<'a>>,
   |            ^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
   |
   = note: expected type `<<Self as StandaloneGat>::Datum<'a> as Sized>`
              found type `<<Self as StandaloneGat>::Datum<'static> as Sized>`
note: the lifetime `'a` as defined here...
  --> src/lib.rs:21:25
   |
21 |     fn definitely_sized<'a, I>(&self, into: I) -> Self::Datum<'a>
   |                         ^^
   = note: ...does not necessarily outlive the static lifetime

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)A-lifetimesArea: Lifetimes / regionsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.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