Skip to content

Infinite "recursive requirements" compiler error #60603

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

Open
rosscanning opened this issue May 7, 2019 · 5 comments
Open

Infinite "recursive requirements" compiler error #60603

rosscanning opened this issue May 7, 2019 · 5 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-trait-system Area: Trait system C-bug Category: This is a bug. E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@rosscanning
Copy link

When compiling this program, the compiler fails with an infinitely recursive error message. The message makes no sense, as it contains types that aren't even in the program.

use std::ops::{Add, Sub};

struct Point2d<T> {
    pub x: T,
    pub y: T,
}

impl<'a, T> Sub<&'a Point2d<T>> for &'a Point2d<T>
where &'a T: Sub<&'a T, Output=T>,
{
    type Output = Point2d<T>;
    fn sub(self, other: &'a Point2d<T>) -> Self::Output { unimplemented!();  }
}

fn f1<'a, I>(x: &'a I)
where &'a I: Sub<Output=I> {   unimplemented!(); }

fn main() {
    let a = 123;
    f1(&a);
}

This code won't do anything, but it should compile (I think). Instead, the compiler emits an infinite series of error messages like:

error[E0275]: overflow evaluating the requirement `&hashbrown::set::HashSet<_, _>: std::ops::Sub`
  --> src\main.rs:28:5
   |
28 |     f1(&a);
   |     ^^
   |
   = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
   = note: required because of the requirements on the impl of `std::ops::Sub` for `&Point2d<hashbrown::set::HashSet<_, _>>`
   = note: required because of the requirements on the impl of `std::ops::Sub` for `&Point2d<Point2d<hashbrown::set::HashSet<_, _>>>`
   = note: required because of the requirements on the impl of `std::ops::Sub` for `&Point2d<Point2d<Point2d<hashbrown::set::HashSet<_, _>>>>`
   = note: required because of the requirements on the impl of `std::ops::Sub` for `&Point2d<Point2d<Point2d<Point2d<hashbrown::set::HashSet<_, _>>>>>`

This program doesn't even use HashSet.

rustc 1.36.0-nightly (d628c2e 2019-05-05)
binary: rustc
commit-hash: d628c2e
commit-date: 2019-05-05
host: x86_64-pc-windows-msvc
release: 1.36.0-nightly
LLVM version: 8.0

@jonas-schievink jonas-schievink added A-diagnostics Area: Messages for errors, warnings, and lints A-trait-system Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. I-nominated labels May 7, 2019
@jonas-schievink
Copy link
Contributor

Wat. Nominating. HashSet isn't even using the Add or Sub trait.

@jonas-schievink
Copy link
Contributor

In Rust 1.12.0 it displays BTreeSet instead:

error[E0275]: overflow evaluating the requirement `_: std::cmp::Ord`
  --> test.rs:20:5
   |
20 |     f1(&a);
   |     ^^
   |
   = note: consider adding a `#![recursion_limit="128"]` attribute to your crate
   = note: required because of the requirements on the impl of `std::ops::Sub` for `&std::collections::BTreeSet<_>`
   = note: required because ...
   ...

@nikomatsakis
Copy link
Contributor

The diagnostics are poor -- but the error is probably real. The trait solver is basically trying hard to find some type for T that it can use, and it's substituting with types from impls that it finds (including, I suppose, one for hashset). At least that's my guess. I'm going to mark this as P-medium.

triage: P-medium

@nikomatsakis nikomatsakis added P-medium Medium priority and removed I-nominated labels May 9, 2019
@oli-obk oli-obk added the E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. label May 24, 2019
@oli-obk
Copy link
Contributor

oli-obk commented May 24, 2019

Diagnostics triage: not really a diagnostics issue per se, but a trait solver issue. Marking as hard.

@dhardy
Copy link
Contributor

dhardy commented Feb 17, 2022

and it's substituting with types from impls that it finds

I have a simpler example of the same thing. This time it's obvious what's wrong: repeatedly taking a & reference does not make the type &mut. (Replacing f(&mut self) with f(&self) fixes.) But the error message is quite poor, to the point that it's unclear that trying to call data.f() is the issue. (This code also checks clean but fails to build, like #56711.)

use std::ops::Deref;

pub trait X {
    fn f(&mut self);
}

impl<T> X for [T] {
    fn f(&mut self) {}
}

impl<T: X + ?Sized> X for &T {
    fn f(&mut self) {
        self.deref().f()
    }
}

const DATA: &[u8] = &[0, 1];

fn main() {
    let mut data: &'static [u8] = DATA;
    data.f();
}

Output:

error[E0275]: overflow evaluating the requirement `&[u8]: X`
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`filter_list`)
note: required because of the requirements on the impl of `X` for `&&[u8]`
  --> examples/filter-list.rs:17:21
   |
17 | impl<T: X + ?Sized> X for &T {
   |                     ^     ^^
   = note: 128 redundant requirements hidden
   = note: required because of the requirements on the impl of `X` for `&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&[u8]`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-trait-system Area: Trait system C-bug Category: This is a bug. E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. P-medium Medium priority 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

5 participants