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

Cannot state a infered lifetime in a closure #38081

Closed
nikonthethird opened this issue Nov 30, 2016 · 2 comments
Closed

Cannot state a infered lifetime in a closure #38081

nikonthethird opened this issue Nov 30, 2016 · 2 comments
Labels
A-closures Area: closures (`|args| { .. }`) A-lifetimes Area: lifetime related

Comments

@nikonthethird
Copy link

nikonthethird commented Nov 30, 2016

How is it possible to explicitly state the type of the variable x inside the closure:

#[allow(unused_variables)]
fn main() {

    let slice1: &[i32] = &[1, 2, 3, 4, 5][..];
    
    // This works.
    let slice2 = (|x| x)(slice1);
    
    // This does not.
    //let slice3 = (|x: &[i32]| x)(slice1);
}

My expectation is that the commented line should work, as it merely adds a type annotation. However, the compiler displays the following:

rustc 1.13.0 (2c6933acc 2016-11-07)
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
 --> <anon>:9:31
  |
9 |     let slice3 = (|x: &[i32]| x)(slice1);
  |                               ^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 9:30...
 --> <anon>:9:31
  |
9 |     let slice3 = (|x: &[i32]| x)(slice1);
  |                               ^
note: ...so that expression is assignable (expected &[i32], found &[i32])
 --> <anon>:9:31
  |
9 |     let slice3 = (|x: &[i32]| x)(slice1);
  |                               ^
note: but, the lifetime must be valid for the call at 9:17...
 --> <anon>:9:18
  |
9 |     let slice3 = (|x: &[i32]| x)(slice1);
  |                  ^^^^^^^^^^^^^^^^^^^^^^^
note: ...so type `extern "rust-call" fn(&[closure@<anon>:9:18: 9:33], (&[i32],)) -> &[i32] {<[closure@<anon>:9:18: 9:33] as std::ops::Fn<(&[i32],)>>::call}` of expression is valid during the expression
 --> <anon>:9:18
  |
9 |     let slice3 = (|x: &[i32]| x)(slice1);
  |                  ^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

It this not possible?

Link to Rust Playground: https://is.gd/KYIYfk

@ilammy
Copy link
Contributor

ilammy commented Nov 30, 2016

Well, it seems that rustc needs an explicit lifetime spec for the reference. I don't know how to introduce a lifetime variable in the function body, but this does work:

fn main() {
    let slice1: &[i32] = &[1, 2, 3, 4, 5][..];

    let slice2 = (|x| x)(slice1);

    fun(slice1)
}

fn fun<'a>(slice1: &'a [i32]) {
    let slice3 = (|x: &'a [i32]| x)(slice1);
}

@steveklabnik steveklabnik added A-closures Area: closures (`|args| { .. }`) A-lifetimes Area: lifetime related labels Nov 30, 2016
@steveklabnik
Copy link
Member

You cannot do this today, you have to do what @ilammy mentioned.

rust-lang/rfcs#1650 would give you the ability to do this, or at least, pave the way for the syntax to exist. (the thread itself seems to be slightly conflicted about it). Closing in favor of that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: closures (`|args| { .. }`) A-lifetimes Area: lifetime related
Projects
None yet
Development

No branches or pull requests

3 participants