Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhelpful "overflow evaluating the requirement" error for infinitely recursive generators #46415

Closed
Popog opened this issue Dec 1, 2017 · 8 comments
Labels
A-coroutines Area: Coroutines A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Popog
Copy link

Popog commented Dec 1, 2017

Obviously this shouldn't actually work, due to the state type being infinitely sized (at least not without become/TCO for generators), but it should generate an error similar to recursive types.

playground link

Program:

#![feature(generators, conservative_impl_trait, generator_trait)]

use std::ops::{Generator, GeneratorState};

fn foo() -> impl Generator<Yield = (), Return = ()> {
    || {
        let mut gen = foo();
        
        let mut r = gen.resume();
        while let GeneratorState::Yielded(v) = r {
            yield v;
            r = gen.resume();
        }
    }
}

fn main() {
    foo();
}

Output:

   Compiling playground v0.0.1 (file:///playground)

thread 'rustc' has overflowed its stack
fatal runtime error: stack overflow
error: Could not compile `playground`.

To learn more, run the command again with --verbose.

Expected (something like):

   Compiling playground v0.0.1 (file:///playground)
error[E0072]: recursive type `Foo` has infinite size
 --> src/main.rs:1:1
  |
1 | struct Foo(Foo);
  | ^^^^^^^^^^^----^
  | |          |
  | |          recursive without indirection
  | recursive type has infinite size
  |
  = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable

error: aborting due to previous error

error: Could not compile `playground`.

To learn more, run the command again with --verbose.
@estebank estebank added A-coroutines Area: Coroutines C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 1, 2017
@afonsolage
Copy link

Got the same error, using the futures-await crate. Here is a demo project to reproduce the issue, using the mentioned crate.

@shisoft
Copy link

shisoft commented Jan 21, 2018

Getting the same error, by adapting my project using futures-await.

@shisoft
Copy link

shisoft commented Jan 28, 2018

After updated to the latest nightly rust. The error message have been changed.
This reminds me that it is not related to generator at all. The overflow was caused by recursive type inference.
For the futures-await case, just change your #[async] to #[async(boxed)] to make the return value a concrete type instead.
In the generator case, try this one

#![feature(generators, conservative_impl_trait, generator_trait)]

use std::ops::{Generator, GeneratorState};

fn foo() -> Box<Generator<Yield = (), Return = ()>> {
    Box::new(|| {
        let mut gen = foo();
        
        let mut r = gen.resume();
        while let GeneratorState::Yielded(v) = r {
            yield v;
            r = gen.resume();
        }
    })
}

It compiled with no error.

@Zoxc
Copy link
Contributor

Zoxc commented Jan 28, 2018

This now gives the following error, which is still not particularly great.

error[E0275]: overflow evaluating the requirement `impl std::ops::Generator`
  |
  = help: consider adding a `#![recursion_limit="128"]` attribute to your crate

error: aborting due to previous error

@Zoxc
Copy link
Contributor

Zoxc commented Jan 28, 2018

Recursive closures also give a similar error:

error[E0275]: overflow evaluating the requirement `impl std::ops::Fn<()>`
#![feature(conservative_impl_trait)]

fn foo() -> impl Fn() {
    let t = foo();
    move || {
        t();
    }
}

fn main() {
    (foo())();
}

@jakubadamw
Copy link
Contributor

So this is no longer an ICE. The I-ICE label could be dropped.

@jonhoo
Copy link
Contributor

jonhoo commented Sep 4, 2019

I'm currently running into this while porting mysql_async to std::future (and thereby async fn) in blackbeam/mysql_async#71. The compiler is also here generating the relatively unhelpful error message:

    Checking mysql_async v0.21.0-alpha.1 (/home/jon/dev/others/mysql_async)
error[E0275]: overflow evaluating the requirement `impl core::future::future::Future`
  |
  = help: consider adding a `#![recursion_limit="2048"]` attribute to your crate

error: aborting due to previous error

Is there a way to get information about which async fn is causing the issue?

For completeness, if I increase the recursion limit the way it suggests up to 8192, rustc eventually crashes with

hread 'rustc' has overflowed its stack
fatal runtime error: stack overflow
error: Could not compile `mysql_async`.

jonhoo added a commit to jonhoo/mysql_async that referenced this issue Sep 6, 2019
blackbeam pushed a commit to blackbeam/mysql_async that referenced this issue Sep 20, 2019
* Add rustfmt.toml for 2018 edition fmt

* Part-way there

* Closer to upstream tokio

* No more MyFuture

* Port tests

* More stuff to async fn

* Use ? in tests over unwrap

* Workaround for rust-lang/rust#46415

* All tests pass

* async/await is only on nightly for now

* Only nightly on circle as well

* CI is hard

* Prep for async named pipes

* Don't fail tests if local infiles aren't supported

* No more workaround for taiki-e/pin-project#68

* Attempt at windows support

* PollEvented in tokio_net::util

* Avoid compilation error in Transaction::new

* Fix compilation error in tls::connect_async()

* Fix benches. Add SSL env var for tests.

* Test SSL during CI

* Bump dependencies
@jonas-schievink jonas-schievink added A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. and removed I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ C-bug Category: This is a bug. labels Jan 23, 2020
@jonas-schievink jonas-schievink changed the title "'rustc' has overflowed its stack" error for infinitely recursive generators Unhelpful "overflow evaluating the requirement" error for infinitely recursive generators Jan 23, 2020
@compiler-errors
Copy link
Member

This code:

#![feature(generators, generator_trait)]

use std::ops::{Generator, GeneratorState};

fn foo() -> impl Generator<Yield = (), Return = ()> {
    || {
        let mut gen = Box::pin(foo());
        let mut r = gen.as_mut().resume(());
        while let GeneratorState::Yielded(v) = r {
            yield v;
            r = gen.as_mut().resume(());
        }
    }
}

fn main() {
    foo();
}

Now errors with "recursive opaque type":

error[[E0720]](https://doc.rust-lang.org/nightly/error-index.html#E0720): cannot resolve opaque type
  --> src/main.rs:5:13
   |
5  |   fn foo() -> impl Generator<Yield = (), Return = ()> {
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type
6  | /     || {
7  | |         let mut gen = Box::pin(foo());
8  | |         let mut r = gen.as_mut().resume(());
9  | |         while let GeneratorState::Yielded(v) = r {
...  |
12 | |         }
13 | |     }
   | |_____- returning here with type `[generator@src/main.rs:6:5: 6:7]`

I personally consider this sufficient. Drilling down the generator any further to explain why it's recursive (i.e. explain its upvars) would be nice, but I don't think it's necessarily required. I'll open a new PR for that.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 21, 2023
…losure, r=TaKO8Ki

Label closure captures/generator locals that make opaque types recursive

cc rust-lang#46415 (comment)
compiler-errors added a commit to compiler-errors/rust that referenced this issue Jan 22, 2023
…losure, r=TaKO8Ki

Label closure captures/generator locals that make opaque types recursive

cc rust-lang#46415 (comment)
compiler-errors added a commit to compiler-errors/rust that referenced this issue Jan 22, 2023
…losure, r=TaKO8Ki

Label closure captures/generator locals that make opaque types recursive

cc rust-lang#46415 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-coroutines Area: Coroutines A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants