Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error[E0275]: overflow evaluating the requirement <RefTFamily<T> as LifetimizedOutputFamily>::Output<'a> == _ #130728

Open
JohnScience opened this issue Sep 23, 2024 · 1 comment
Labels
A-GATs Area: Generic associated types (GATs) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@JohnScience
Copy link
Contributor

I was trying to implement a generic SelfBorrowingClosure based on https://users.rust-lang.org/t/why-closure-cannot-return-a-reference-to-data-moved-into-closure/72655/6 but got a problem compiling the following piece of code:

pub trait LifetimizedOutputFamily {
    type Output<'a>
    where 
        Self::Output<'a>: 'a;
}

pub struct RefTFamily<T>(core::marker::PhantomData<*const T>);

impl<T> LifetimizedOutputFamily for RefTFamily<T>
{
    type Output<'a> = &'a T
    where
        T: 'a;
}

pub struct SelfBorrowingClosure<State, F, OutputFam>
where
    OutputFam: LifetimizedOutputFamily,
    F: Fn(&'_ State) -> <OutputFam as LifetimizedOutputFamily>::Output<'_>,
{
    pub state: State,
    pub call: F,
    pub output_family: core::marker::PhantomData<*const OutputFam>,
}

impl<State, F, OutputFam> SelfBorrowingClosure<State, F, OutputFam>
where
    OutputFam: LifetimizedOutputFamily,
    F: Fn(&'_ State) -> <OutputFam as LifetimizedOutputFamily>::Output<'_>,
{
    pub fn new(state: State, call: F) -> Self {
        Self {
            state,
            call,
            output_family: core::marker::PhantomData,
        }
    }

    pub fn call(&self) -> <OutputFam as LifetimizedOutputFamily>::Output<'_> {
        (self.call)(&self.state)
    }
}

Minimal Reproducible Example (MRE):

pub trait LifetimizedOutputFamily {
    type Output<'a>
    where 
        Self::Output<'a>: 'a;
}

pub struct RefTFamily<T>(core::marker::PhantomData<*const T>);

impl<T> LifetimizedOutputFamily for RefTFamily<T>
{
    type Output<'a> = &'a T
    where
        T: 'a;
}

Error:

error[E0275]: overflow evaluating the requirement `<RefTFamily<T> as LifetimizedOutputFamily>::Output<'a> == _`
  --> src\lib.rs:11:5
   |
11 |     type Output<'a> = &'a T
   |     ^^^^^^^^^^^^^^^

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 23, 2024
@JohnScience
Copy link
Contributor Author

JohnScience commented Sep 23, 2024

I can do that for a concrete type:

mod workaround {
    pub struct SelfBorrowingClosureReturningStdFmtArguments<
        State,
        F : Fn(&'_ State) -> std::fmt::Arguments<'_>
    > {
        pub state: State,
        pub closure: F,
    }

    impl<State, F> SelfBorrowingClosureReturningStdFmtArguments<State, F>
    where
        F : Fn(&'_ State) -> std::fmt::Arguments<'_>,
    {
        pub fn new(state: State, closure: F) -> Self {
            Self { state, closure }
        }

        pub fn call (self: &'_ SelfBorrowingClosureReturningStdFmtArguments<State, F>)
            -> std::fmt::Arguments<'_>
        {
            (self.closure)(&self.state)
        }
    }
}

However, even my adhoc workaround didn't help me:

I ended up creating a simple lib for what I wanted to do: https://crates.io/crates/display_with

@fmease fmease added the A-GATs Area: Generic associated types (GATs) label Sep 24, 2024
@saethlin saethlin added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue. C-bug Category: This is a bug. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-GATs Area: Generic associated types (GATs) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants