Skip to content

Exponential slowdown in catching an overflow error. #91949

Closed
@steffahn

Description

@steffahn

This code is not expected to compile successfully:

fn main() {
    recurse(std::iter::empty());
}

struct Wrapped<T>(T);

struct IteratorOfWrapped<T, I: Iterator<Item = T>>(I);

impl<T, I: Iterator<Item = T>> Iterator for IteratorOfWrapped<T, I> {
    type Item = Wrapped<T>;
    fn next(&mut self) -> Option<Wrapped<T>> {
        self.0.next().map(Wrapped)
    }
}

fn recurse<T>(elements: T) -> Vec<char>
where
    T: Iterator<Item = ()>,
{
    recurse(IteratorOfWrapped(elements).map(|t| t.0))
}

This can't compile successfully because recurse<T> calls recurse<Map<IteratorOfWrapped<(), T>, [closure@<source>:22:51: 22:58]>> recursively, which then calls recurse<Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), T>, [closure@<source>:22:51: 22:58]>>, [closure@<source>:22:51: 22:58]>>, and so on...

However up to stable 1.55, the code failed to compile quickly with the default recursion limit. On the compiler explorer, you can see it even handling #![recursion_limit = "800"] without timeout. However, go to 1.56 and it no longer reaches a compilation error in time with #![recursion_limit = "30"]. Still just as slow on nightly (rustc 1.59.0-nightly (6bda5b331 2021-12-12)).

@rustbot label: regression-from-stable-to-stable, perf-regression, I-compiletime, T-compiler, E-needs-bisection

Comes from: https://users.rust-lang.org/t/compiler-hanging/68804

Rough estimate on my machine: In the area of recursion_limit being 20-30, the time more-than doubles for each increase of the recursion limit by 2 or 3, so it really is exponential AFAICT.

Metadata

Metadata

Assignees

No one assigned

    Labels

    E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-compiletimeIssue: Problems and improvements with respect to compile times.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.perf-regressionPerformance regression.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions