Skip to content

Seemingly equivalent GAT trait implementations behave differently #90713

Open
@petrosagg

Description

@petrosagg

The following code fails to compile:

#![feature(generic_associated_types)]

use std::ops::Deref;

trait GetOutput {
    type Output<'a>
    where
        Self: 'a;

    fn output<'a>(&'a self) -> Self::Output<'a>;
}

impl<T, D> GetOutput for T
where
    T: Deref<Target = D>,
    D: GetOutput,
{
    type Output<'a>
    where
        Self: 'a,
        D: 'a,
    = D::Output<'a>;

    fn output<'a>(&'a self) -> Self::Output<'a> {
        self.deref().output()
    }
}

But this equivalent (I think) code compiles just fine:

#![feature(generic_associated_types)]

use std::ops::Deref;

trait GetOutput {
    type Output<'a>
    where
        Self: 'a;

    fn output<'a>(&'a self) -> Self::Output<'a>;
}

impl<T> GetOutput for T
where
    T: Deref,
    T::Target: GetOutput,
{
    type Output<'a>
    where
        Self: 'a,
        <Self as Deref>::Target: 'a,
    = <<Self as Deref>::Target as GetOutput>::Output<'a>;

    fn output<'a>(&'a self) -> Self::Output<'a> {
        self.deref().output()
    }
}

There might be a subtle difference between the two implementation but I can't see any. This is a simplified example from this question in the Rust subreddit: https://www.reddit.com/r/rust/comments/qp8dwl/hey_rustaceans_got_an_easy_question_ask_here/hjsfjgs/

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)GATs-triagedIssues using the `generic_associated_types` feature that have been triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions