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

impl Trait should be able to capture long-lived associated types even if the trait contains a lifetime #54385

Open
RalfJung opened this issue Sep 20, 2018 · 6 comments
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-lifetimes Area: Lifetimes / regions 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

@RalfJung
Copy link
Member

Basically, this should compile:

trait Trait<'foo> { type Assoc: 'static; }

fn test<'foo, T: Trait<'foo>>(x: T::Assoc) -> impl FnOnce() {
    move || { let _x = x; }
}

Thanks to @eddyb I can work around this, writing

trait Trait<'foo> { type Assoc: 'static; }

fn test<'foo, A: 'static, T: Trait<'foo, Assoc=A>>(x: T::Assoc) -> impl FnOnce() {
    move || { let _x = x; }
}

but that is almost impossible to discover.

@eddyb
Copy link
Member

eddyb commented Sep 20, 2018

It doesn't compile right now because it contains <T as Trait<'foo>>::Assoc, which, despite being 'static, contains the lifetime 'foo, so for soundness reasons, the impl FnOnce() opaque type must also be parametrized over 'foo (to recover the concrete return type).

We could try some erasure scheme, but the "exporting" of the concrete type is already pretty complicated, and there's a huge risk here, of opening up a soundness hole.

cc @nikomatsakis @cramertj @oli-obk

@eddyb eddyb added the A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. label Sep 20, 2018
@Arnavion
Copy link

(Unexpected lifetime capture by impl-trait is #42940 )

@RalfJung
Copy link
Member Author

@Mark-Simulacrum AFAIK this bug here is specifically about associated types, unlike #42940. Why did you close?

@Mark-Simulacrum
Copy link
Member

I got the impression that the underlying bug is the same. But perhaps not. Reopening.

@Enselic Enselic added A-lifetimes Area: Lifetimes / regions T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Nov 24, 2023
@RalfJung RalfJung added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Apr 24, 2024
@RalfJung
Copy link
Member Author

This actually compiles with the 2024 edition. :)

@rust-lang/types I assume that means it can be closed?

@lcnr
Copy link
Contributor

lcnr commented Apr 24, 2024

the underlying cause still exists:

#![feature(precise_capturing)]
trait Trait<'foo> { type Assoc: 'static; }
fn test<'foo, T: Trait<'foo>>(x: T::Assoc) -> impl use<T> FnOnce() {
    move || { let _x = x; }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-lifetimes Area: Lifetimes / regions 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

6 participants