Skip to content

Misleading/incorrect? closure/generator type that references itself error #105401

Closed
@cynecx

Description

@cynecx

I tried this code:

#![feature(type_alias_impl_trait)]
#![feature(closure_lifetime_binder)]

use core::future::Future;

trait AsyncFn<I, R>: FnMut(I) -> Self::Fut {
    type Fut: Future<Output = R>;
}

impl<F, I, R, Fut> AsyncFn<I, R> for F
where
    Fut: Future<Output = R>,
    F: FnMut(I) -> Fut,
{
    type Fut = Fut;
}

async fn call<C, R, F>(mut ctx: C, mut f: F) -> Result<R, ()>
where
    F: for<'a> AsyncFn<&'a mut C, Result<R, ()>>
{
    loop {
        match f(&mut ctx).await {
            Ok(val) => return Ok(val),
            Err(_) => continue,
        }
    }
}

trait Cap<'a> {}
impl<T> Cap<'_> for T {}

fn works(ctx: &mut usize) {
    let mut inner = 0;
    
    type Ret<'a, 'b: 'a> = impl Future<Output = Result<usize, ()>> + 'a + Cap<'b>;
    
    let callback = for<'a, 'b> |c: &'a mut &'b mut usize| -> Ret<'a, 'b> {
        inner += 1;
        async move { let _c = c; Ok(1usize) }
    };
    call(ctx, callback);
}

fn doesnt_work_but_should(ctx: &mut usize) {
    let mut inner = 0;
    
    type Ret<'a, 'b: 'a> = impl Future<Output = Result<usize, ()>> + 'a + Cap<'b>;
    
    call(ctx, for<'a, 'b> |c: &'a mut &'b mut usize| -> Ret<'a, 'b> {
        inner += 1;
        async move { let _c = c; Ok(1usize) }
    });
}

I expected to see this happen: I believe this should compile just fine but I am not 100% sure.

Instead, this happened: rustc produces the following:

Compiling playground v0.0.1 (/playground)
error[[E0644]](https://doc.rust-lang.org/nightly/error-index.html#E0644): closure/generator type that references itself
  --> src/lib.rs:50:15
   |
50 |       call(ctx, for<'a, 'b> |c: &'a mut &'b mut usize| -> Ret<'a, 'b> {
   |  _______________^
51 | |         inner += 1;
52 | |         async move { let _c = c; Ok(1usize) }
53 | |     });
   | |_____^ cyclic type of infinite size
   |
   = note: closures cannot capture themselves or take themselves as argument;
           this error may be the result of a recent compiler bug-fix,
           see issue #46062 <https://github.com/rust-lang/rust/issues/46062>
           for more information

For more information about this error, try `rustc --explain E0644`.
error: could not compile `playground` due to previous error

Permalink to the playground

rustc --version --verbose:

1.67.0-nightly (2022-12-05 e1d819583f0bf13b016b)

Metadata

Metadata

Labels

A-closuresArea: Closures (`|…| { … }`)C-bugCategory: This is a bug.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`requires-nightlyThis issue requires a nightly compiler in some way.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions