Skip to content

Compiler (effectively) hangs, regression from overflow error #93774

Open
@steffahn

Description

@steffahn
pub enum Either<L, R> {
    Left(L),
    Right(R),
}

pub trait HasItem<'a, _Constraint = &'a Self> {
    type Item;
}

pub type Item<'a, Self_> = <Self_ as HasItem<'a>>::Item;

pub trait LendingIterator: for<'a> HasItem<'a> {
    fn next(&mut self) -> Option<Item<'_, Self>>;
}

impl<'a, A: 'a, B: 'a> HasItem<'a> for Either<A, B>
where A: LendingIterator, B: LendingIterator,
 for<'b> B: HasItem<'b, Item = Item<'b, Self>>
{
    type Item = Item<'a, Self>;
}

impl<A, B> LendingIterator for Either<A, B>
where A: LendingIterator, B: LendingIterator,
 for<'b> B: HasItem<'b, Item = Item<'b, Self>>
{
    fn next(&mut self) -> Option<Item<'_, Self>> {
        match self {
            Either::Left(iter) => iter.next(),
            Either::Right(iter) => iter.next(),
        }
    }
}

hangs since 1.56
error on 1.55

error[E0275]: overflow evaluating the requirement `for<'b> <B as HasItem<'b>>::Item == <Either<A, B> as HasItem<'b>>::Item`
  --> <source>:16:24
   |
6  | pub trait HasItem<'a, _Constraint = &'a Self> {
   | --------------------------------------------- required by this bound in `HasItem`
...
16 | impl<'a, A: 'a, B: 'a> HasItem<'a> for Either<A, B>
   |                        ^^^^^^^^^^^
   |
note: required because of the requirements on the impl of `HasItem<'a>` for `Either<A, B>`
  --> <source>:16:24
   |
16 | impl<'a, A: 'a, B: 'a> HasItem<'a> for Either<A, B>
   |                        ^^^^^^^^^^^     ^^^^^^^^^^^^

error[E0275]: overflow evaluating the requirement `for<'b> <B as HasItem<'b>>::Item == <Either<A, B> as HasItem<'b>>::Item`
  --> <source>:23:12
   |
12 | pub trait LendingIterator: for<'a> HasItem<'a> {
   |                            ------------------- required by this bound in `LendingIterator`
...
23 | impl<A, B> LendingIterator for Either<A, B>
   |            ^^^^^^^^^^^^^^^
   |
note: required because of the requirements on the impl of `for<'a> HasItem<'a>` for `Either<A, B>`
  --> <source>:16:24
   |
16 | impl<'a, A: 'a, B: 'a> HasItem<'a> for Either<A, B>
   |                        ^^^^^^^^^^^     ^^^^^^^^^^^^

error[E0275]: overflow evaluating the requirement `for<'b> <B as HasItem<'b>>::Item == <Either<A, B> as HasItem<'b>>::Item`
  --> <source>:20:5
   |
20 |     type Item = Item<'a, Self>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: required because of the requirements on the impl of `HasItem<'a>` for `Either<A, B>`
  --> <source>:16:24
   |
16 | impl<'a, A: 'a, B: 'a> HasItem<'a> for Either<A, B>
   |                        ^^^^^^^^^^^     ^^^^^^^^^^^^

error[E0275]: overflow evaluating the requirement `for<'b> <B as HasItem<'b>>::Item == <Either<A, B> as HasItem<'b>>::Item`
  --> <source>:27:8
   |
27 |     fn next(&mut self) -> Option<Item<'_, Self>> {
   |        ^^^^
   |
note: required because of the requirements on the impl of `HasItem<'_>` for `Either<A, B>`
  --> <source>:16:24
   |
16 | impl<'a, A: 'a, B: 'a> HasItem<'a> for Either<A, B>
   |                        ^^^^^^^^^^^     ^^^^^^^^^^^^

error: aborting due to 4 previous errors

@rustbot label I-hang, regression-from-stable-to-stable, A-traits, A-lifetimes, E-needs-bisection, T-compiler


Edit:

“Hangs” means “runs for a wile on 100% CPU until I cancel it”. Who knows if it would ever terminate… actually, maybe I should test smaller recursion limits.

Note that this code example is not expected to compile successfully. Here’s a version that works / with the mistakes fixed. (The fixed version also works on some older Rust versions, including 1.55 and older.)


Edit2: Using smaller limits (like… around #![recursion_limit = "14"] it starts getting unbearably slow) reveals that this is apparently more like exponential-time slowdown rather than “actual” hanging.

@rustbot label -I-hang, +I-compiletime, +perf-regression

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lifetimesArea: Lifetimes / regionsA-trait-systemArea: Trait systemC-bugCategory: This is a bug.I-compiletimeIssue: Problems and improvements with respect to compile times.P-highHigh priorityT-typesRelevant to the types 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