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.
I was starting with this function (which does compile on nightly):
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):
But the compiler is currently unhappy with the lifetimes. I'm getting the following.
It works without the lifetimes (i.e. after removing parametrization over 'a and replacing all occurrences of 'a with 'static), like this:
Meta
Current behavior only since #67844 was fixed (after
nightly-2020-02-14). Before that, this code triggered an ICE.