Issue with capturing variables in an async block typed with with impl trait type alias

Hello,

In the code below, the pick3 function doesn't compile. I'm wondering if I'm missing something or if this is a limitation of the current compiler.

#![feature(type_alias_impl_trait)]
#![feature(async_closure)]
#![allow(dead_code, unused_imports)]

use std::fmt::Display;
use std::future::Future;

async fn pick1<T, I: Iterator<Item = T>>(input: &mut I) -> T {
    input.next().unwrap()
}

async fn pick2<T, I: Iterator<Item = T>>(input: &mut I) -> T {
    type __ReturnType<T> = T;

    let body = (async move || -> __ReturnType<T> { input.next().unwrap() })();

    return tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .expect("failed building the runtime")
        .block_on(body);
}

async fn pick3<'a, T, I: Iterator<Item = T>>(input: &'a mut I) -> T {
    type __FutureType<'a, T> = impl Future<Output = T> + 'a;

    let body: __FutureType<'a, T> = async move { input.next().unwrap() };

    return tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .expect("failed building the runtime")
        .block_on(body);
}
error: type parameter `I` is part of concrete type but not used in parameter list for the `impl Trait` type alias
  --> src\lib.rs:27:37
   |
27 |     let body: __FutureType<'a, T> = async move { input.next().unwrap() };
   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Rust Playground

Do you need __FutureType? Without it, letting the compiler infer the type of body, your example compiles fine on the playground.


Otherwise, this works, too. I renamed the parameters of __FutureType to make it clearer that they are different from the ones you use in your function:

async fn pick3<'a, T, I: Iterator<Item = T>>(input: &'a mut I) -> T {
    type __FutureType<'b, U, J: Iterator<Item = U> + 'b> = impl Future<Output = U> + 'b;

    let body: __FutureType<'a, T, I> = async move { input.next().unwrap() };

    return tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .expect("failed building the runtime")
        .block_on(body);
}

Playground.

2 Likes

Ah, I didn't realize that. Thank you, jofas.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.