Skip to content

rustc does not terminate after 1.57.0 #93137

Description

@dingelish

I tried this code:

#![recursion_limit="256"]
use futures_util::{Future, future, TryFutureExt};
use std::path::Path;

struct Foo;

fn orz<T>(path: T) -> impl Future<Output = Result<String, ()>>
where
    T: AsRef<Path> + Send + 'static,
{
    std::future::ready(Ok("".into()))
}

fn zoo<T>(arg: T) -> impl Future<Output = Result<Foo, ()>>
where T: AsRef<Path> + Send + 'static
{
    orz(arg).map_err(|_| ()).and_then(|line| {
        let result = Ok(Foo{});
        std::future::ready(result)
    })
}

fn root() ->  impl Future<Output = Result<Foo, ()>> {
    future::err(())
        // more zoo more time
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
        .or_else(|_| zoo(""))
}

fn main() {
    println!("Hello, world!");
    root();
}

I expected to see this happen: it compiles successfully

Instead, this happened: rustc takes long time to compile as the number of or_else(|_| zoo("")) increases. looks like exponential time. 1.56.1 successfully compiles it.

Meta

rustc --version --verbose:

rustc 1.58.0 (02072b482 2022-01-11)
binary: rustc
commit-hash: 02072b482a8b5357f7fb5e5637444ae30e423c40
commit-date: 2022-01-11
host: x86_64-unknown-linux-gnu
release: 1.58.0
LLVM version: 13.0.0
Backtrace

<backtrace>

no backtrace

Activity

  1. Aaron1011 commented on Jan 20, 2022

    @Aaron1011
    Contributor

    This should compile in a reasonable amount of time on the latest nightly.

  2. dingelish commented on Jan 20, 2022

    @dingelish
    ContributorAuthor

    This should compile in a reasonable amount of time on the latest nightly.

    thanks @Aaron1011 ! confirmed latest nightly fixed this. could i have some background? how's the fix looks like? thanks!

  3. Aaron1011 commented on Jan 20, 2022

    @Aaron1011
    Contributor

    @dingelish: In the past, we used to aggressively cache the results of trait evaluation and projection. However, this turned out to interact badly with incremental compilation, and could lead to ICEs. As a result, some of this caching logic was removed in PRs like #88945

    While our performance benchmarks showed only small to moderate performance regressions, it turned out that the caching was needed to prevent exponential blowup in some cases that were not covered by our benchmark. I re-added some of the caching logic in PRs like #89831 (in a modified and potentially less effective form, to be compatible with incremental compilation). This appears to have fixed the exponential blowup.

    See #89195 and rust-lang/rustc-perf#1124 for more context

  4. dingelish commented on Jan 20, 2022

    @dingelish
    ContributorAuthor

    thanks for the explaination! it's pretty clear. thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions