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

Suboptimal interaction between lifetime oriented and value oriented type system in the presence of closures. #125250

Open
gl-yziquel opened this issue May 18, 2024 · 1 comment
Labels
A-lifetimes Area: lifetime related C-discussion Category: Discussion or questions that doesn't represent real issues. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-lang Relevant to the language 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

@gl-yziquel
Copy link

This code compiles with the comments and does not compile without the comments.

fn main() {
    fn subparsing_lifetime<'s, 'r>(args: &'s Vec<&'s str>) -> (&'r ()/*, &'s ()*/) { unreachable!() }
    let closure = |args| subparsing_lifetime(&args);
}

It runs in the compiler error "cannot return value referencing function parameter".

This highlights, to me, suboptimal interaction between the lifetime oriented type system and the value oriented type system.

The typing guarantees that the function parameter is not referenced in the values.

Moreover, there are use cases, bumpalo arenas, for instance, where it is perfectly legitimate to have lifetimes shared between arguments and returned values, with no dependencies between one and the other.

So this code should compile if uncommented.

One of the interest I have in rust is precisely the ability to share lifetimes between independent references.

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 18, 2024
@workingjubilee
Copy link
Contributor

Hmm, this doesn't compile:

fn main() {
    fn subparsing_lifetime<'arg, 'new>(in_function: &'arg Vec<&'arg str>) -> (&'new (), &'arg ()) {
        unreachable!()
    }
    let closure = |in_closure| subparsing_lifetime(&in_closure);
}

But this does:

fn main() {
    fn subparsing_lifetime<'vec, 'str, 'new>(in_function: &'vec Vec<&'str str>) -> (&'new (), &'str ()) {
        unreachable!()
    }
    let closure = |in_closure| subparsing_lifetime(&in_closure);
}

Interestingly, so does this:

fn accepts_vec_of_str<'arg, 'new>(arg: &'arg Vec<&'arg str>) -> (&'new (), &'arg ()) {
    fn subparsing_lifetime<'arg, 'new>(in_function: &'arg Vec<&'arg str>) -> (&'new (), &'arg ()) {
        unreachable!()
    }
    let closure = |in_closure: &'arg Vec<&'arg str>| subparsing_lifetime(&in_closure);

    closure(arg)
}

@jieyouxu jieyouxu added T-lang Relevant to the language team, which will review and decide on the PR/issue. C-discussion Category: Discussion or questions that doesn't represent real issues. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-types Relevant to the types team, which will review and decide on the PR/issue. A-lifetimes Area: lifetime related and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: lifetime related C-discussion Category: Discussion or questions that doesn't represent real issues. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-lang Relevant to the language 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