rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.38k stars 12.45k forks source link

Compiler hang on resursive trait bound when async fn in trait #117999

Open danjl1100 opened 9 months ago

danjl1100 commented 9 months ago

Code

pub trait HasError {
    type Error;
}

pub trait Foo: HasError {
    // removing `async` emits E0275 instead of hanging until OOM
    async fn foo() -> Result<(), Self::Error>;
}

pub struct MyStruct<'a> {
    _inner: &'a (),
}

impl<'a> HasError for MyStruct<'a>
where
    Self: HasError<Error = ()>,
{
    type Error = ();
}

impl<'a> Foo for MyStruct<'a> {
    async fn foo() -> Result<(), ()> {
        loop {}
    }
}

Playground, with more comments

Meta

rustc --version --verbose:

rustc 1.76.0-nightly (6b771f6b5 2023-11-15)
binary: rustc
commit-hash: 6b771f6b5a6c8b03b6322a9c77ac77cb346148f0
commit-date: 2023-11-15
host: x86_64-unknown-linux-gnu
release: 1.76.0-nightly
LLVM version: 17.0.5

FWIW, also fails on stable 1.70 and 1.60, sometimes with error output about the recursion limit, but always hangs in the versions I tried.

Error output

<no output given by cargo, hangs until OOM killed>

Using -Ztrait-solver=next

Fixed when using -Ztrait-solver=next on nightly (2023-11-15 shown above), as it reports an error correctly. Posting this issue because I'm not sure how soon that "next" trait solver will become the default (e.g. for stable).

$ RUSTFLAGS="-Ztrait-solver=next" cargo c
+ command cargo c
    Checking ice_117999 v0.1.0 (/home/user/ice_117999)
error[E0275]: overflow evaluating the requirement `<impl Future<Output = Result<(), ()>> as Future>::Output == Result<(), <MyStruct<'a> as HasError>::Error>`
  --> src/lib.rs:38:5
   |
38 |     async fn foo() -> Result<(), ()> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`ice_117999`)
note: required by a bound in `Foo::{opaque#0}`
  --> src/lib.rs:18:5
   |
18 |     async fn foo() -> Result<(), Self::Error>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`

For more information about this error, try `rustc --explain E0275`.
error: could not compile `ice_117999` (lib) due to previous error

Backtrace - not available, since rustc hangs until OOM killed

Jules-Bertholet commented 9 months ago

@rustbot label A-traits -I-ICE I-hang I-compilemem

rustbot commented 9 months ago

Error: Label fixed-by-next-solver can only be set by Rust team members

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.

rustbot commented 9 months ago

Error: Label fixed-by-next-solver can only be set by Rust team members

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.