Skip to content

Mixing async functions and &mut leads to overflow evaluating requirement #55809

Closed
@agrif

Description

@agrif

Code:

#![feature(async_await, await_macro, futures_api)]

// Consider this a stand-in for tokio::io::AsyncRead
trait Foo { }
impl Foo for () { }
impl<'a, T> Foo for &'a mut T where T: Foo { }

// Consider this a stand-in for tokio::io::read
async fn foo_async<T>(_v: T) -> u8 where T: Foo {
    0
}

// this should just act exactly like foo_async...
async fn bad<T>(v: T) -> u8 where T: Foo {
    await!(foo_async(v))
}

// let's see if it is!
async fn async_main() {
    let mut v = ();
    
    // compiler error:
    let _ = await!(bad(&mut v));
    // totally fine:
    let _ = await!(foo_async(&mut v));
    // also totally fine:
    let _ = await!(bad(v));
}

fn main() {
    let _ = async_main();
}

Playground.

This fails to compile:

Compiling playground v0.0.1 (/playground)
error[E0275]: overflow evaluating the requirement `[static generator@src/main.rs:9:49: 11:2 {}]: std::marker::Freeze`
  |
  = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
  = note: required because of the requirements on the impl of `std::marker::Freeze` for `[static generator@src/main.rs:9:49: 11:2 {}]`
[ ... line repeated many, many times ... ]
  = note: required because it appears within the type `impl std::future::Future`
  = note: required because it appears within the type `impl std::future::Future`
  = note: required because it appears within the type `{impl std::future::Future, ()}`
  = note: required because it appears within the type `[static generator@src/main.rs:14:42: 16:2 v:&mut () {impl std::future::Future, ()}]`
  = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:14:42: 16:2 v:&mut () {impl std::future::Future, ()}]>`
  = note: required because it appears within the type `impl std::future::Future`
  = note: required because it appears within the type `impl std::future::Future`
  = note: required because it appears within the type `for<'r, 's> {(), impl std::future::Future, impl std::future::Future, impl std::future::Future}`
  = note: required because it appears within the type `[static generator@src/main.rs:19:23: 28:2 for<'r, 's> {(), impl std::future::Future, impl std::future::Future, impl std::future::Future}]`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.
error: Could not compile `playground`.

This might be related to #50674, except that the code that triggers it seems more likely to be valid. I ran into this bug when trying to use tokio to read data and pass it off to serde. At the very least, the error message is extremely confusing.

Slightly modifying this code will occasionally trigger another compiler error (something about DeBruijn indices) but I have lost the exact code that triggers it.

Metadata

Metadata

Assignees

Labels

A-async-awaitArea: Async & AwaitA-coroutinesArea: CoroutinesAsyncAwait-PolishAsync-await issues that are part of the "polish" areaE-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions