Open
Description
I was starting with this function (which does compile on nightly):
#![feature(unboxed_closures)]
#![feature(type_alias_impl_trait)]
fn curry<'a, A: 'a, B, C, F: Fn(A, B) -> C> (f: &'a F)
-> impl Fn<(A,), Output = impl FnOnce(B) -> C + 'a> + 'a
{
move |a| move |b| f(a,b)
}
and wanted to give a name to its return type.
The straightforward approach seems to be (please correct me if the "right" way to do this is different):
#![feature(unboxed_closures)]
#![feature(type_alias_impl_trait)]
type Curried<'a, A: 'a, B, C, F: Fn(A, B) -> C>
= impl Fn<(A,), Output = impl FnOnce(B) -> C + 'a> + 'a;
fn curry<'a, A: 'a, B, C, F: Fn(A, B) -> C> (f: &'a F)
-> Curried<'a, A, B, C, F>
{
move |a| move |b| f(a,b)
}
But the compiler is currently unhappy with the lifetimes. I'm getting the following.
error: cannot infer an appropriate lifetime
--> src/main.rs:11:5
|
6 | = impl Fn<(A,), Output = impl FnOnce(B) -> C + 'a> + 'a;
| ------------------------ this return type evaluates to the `'static` lifetime...
...
11 | move |a| move |b| f(a,b)
| ^^^^^^^^^^^^^^^^^^^^^^^^ ...but this borrow...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 8:10
--> src/main.rs:8:10
|
8 | fn curry<'a, A: 'a, B, C, F: Fn(A, B) -> C> (f: &'a F)
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 8:10
|
9 | -> Curried<'a, A, B, C, F> + '_
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: cannot infer an appropriate lifetime
--> src/main.rs:11:14
|
6 | = impl Fn<(A,), Output = impl FnOnce(B) -> C + 'a> + 'a;
| ------------------------ this return type evaluates to the `'static` lifetime...
...
11 | move |a| move |b| f(a,b)
| ^^^^^^^^^^^^^^^ ...but this borrow...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 8:10
--> src/main.rs:8:10
|
8 | fn curry<'a, A: 'a, B, C, F: Fn(A, B) -> C> (f: &'a F)
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 8:10
|
9 | -> Curried<'a, A, B, C, F> + '_
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
It works without the lifetimes (i.e. after removing parametrization over 'a and replacing all occurrences of 'a with 'static), like this:
#![feature(unboxed_closures)]
#![feature(type_alias_impl_trait)]
type Curried<A: 'static, B, C, F: Fn(A, B) -> C>
= impl Fn<(A,), Output = impl FnOnce(B) -> C + 'static> + 'static;
fn curry<A: 'static, B, C, F: Fn(A, B) -> C> (f: &'static F)
-> Curried<A, B, C, F>
{
move |a| move |b| f(a,b)
}
use std::ops::Add;
fn main() {
let x = curry(&i32::add)(1)(2);
println!("{}", x); // prints "3"
}
Meta
Current behavior only since #67844 was fixed (after nightly-2020-02-14
). Before that, this code triggered an ICE.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Can do after stabilization