Skip to content

compilation does not terminate using async closures #135780

Closed
@nikomatsakis

Description

@nikomatsakis

The following code:

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=efa07d177105d0c3aecf5bc64a9bf8b3

use std::ops::AsyncFnMut;
use std::pin::Pin;

trait Db {}

impl Db for () { }

struct Env<'db> {
    db: &'db ()
}

#[derive(Debug)]
enum SymPerm<'db> {
    Dummy(&'db ()),
    Apply(Box<SymPerm<'db>>, Box<SymPerm<'db>>)
}

pub struct ToChain<'env, 'db> {
    db: &'db dyn crate::Db,
    env: &'env Env<'db>,
}

impl<'env, 'db> ToChain<'env, 'db> {
    fn perm_pairs<'l>(
        &'l self,
        perm: &'l SymPerm<'db>,
        yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>),
    ) -> Pin<Box<dyn std::future::Future<Output = ()> + 'l>> {
        Box::pin(async move {
            match perm {
                SymPerm::Dummy(_) => {
                    yield_chain(perm).await
                }
                SymPerm::Apply(l, r) => {
                    self.perm_pairs(l, &mut async |left_pair| {
                        self.perm_pairs(r, yield_chain)
                            .await
                    })
                    .await
                }
            }
        })
    }
}

#[tokio::main]
async fn main() {
    let pair = SymPerm::Apply(
        Box::new(SymPerm::Dummy(&())),
        Box::new(SymPerm::Dummy(&()))
    );
    ToChain { db: &(), env: &Env { db: &() } }.perm_pairs(
        &pair,
        &mut async |p| {
            eprintln!("{p:?}");
        }
    ).await;
}

causes compilation to enter into an infinite loop. This was reduced from my dada project (run cargo build on the tip of this branch).

Many many thanks to @lqd for helping me minimize this.

cc @compiler-errors @rust-lang/types

Metadata

Metadata

Labels

A-async-closures`async || {}`A-closuresArea: Closures (`|…| { … }`)A-monomorphizationArea: MonomorphizationC-bugCategory: This is a bug.I-hangIssue: The compiler never terminates, due to infinite loops, deadlock, livelock, etc.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions