Skip to content

Overflow evaluating requirement for an unusued type when function has generic lifetime parameters #113496

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
JackStade opened this issue Jul 9, 2023 · 1 comment
Labels
A-type-system Area: Type system C-bug Category: This is a bug. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@JackStade
Copy link

I tried this code:

#![recursion_limit = "8"]

use std::ops::Mul;

fn test<'a, T: 'a>() {
    17 * Foo;
}

#[derive(Clone, Copy)]
struct Foo;

impl Mul<Foo> for u32 {
    type Output = u32;
    
    fn mul(self, other: Foo) -> u32 {
        self
    }
}

struct Wrap<T>{
    t: T,
}

impl<T: Copy> Mul<Wrap<T>> for u32 where u32: Mul<T, Output = T> {
    type Output = Wrap<T>;
    
    fn mul(self, other: Wrap<T>) -> Self::Output {
        Wrap {
            t: self * other.t,
        }
    }
}

I would expect this compile.

Instead, I get this error:

error[[E0275]](https://doc.rust-lang.org/stable/error_codes/E0275.html): overflow evaluating the requirement `u32: Mul<Wrap<_>>`
  --> src/lib.rs:6:8
   |
6  |     17 * Foo;
   |        ^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "16"]` attribute to your crate (`playground`)
note: required for `u32` to implement `Mul<Wrap<Wrap<_>>>`
  --> src/lib.rs:25:15
   |
25 | impl<T: Copy> Mul<Wrap<T>> for u32 where u32: Mul<T, Output = T> {
   |               ^^^^^^^^^^^^     ^^^                   ---------- unsatisfied trait bound introduced here
   = note: 6 redundant requirements hidden
   = note: required for `u32` to implement `Mul<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<_>>>>>>>>>`

For more information about this error, try `rustc --explain E0275`.|

I reduced the recursion limit to make the output smaller, but this still happens with default recursion.

The function test doesn't involve the type Wrap at all. If everything involving Wrap is removed then the code compiles.

If the function test is removed or the (unused) generic parameters are removed, then the code compiles.

In order for the bug to occur, the function test needs to have a lifetime parameter and another parameter which depends on that lifetime parameter (the signature fn test<'a, 'b: 'a>() also causes the bug). I couldn't get this to happen without using lifetimes.

Several closely related issues have been mentioned in this thread: #39959. Some of the specific behavior here seems unique to this example as far as I can tell.

Meta

rustc --version --verbose:

rustc 1.70.0 (90c541806 2023-05-31)
binary: rustc
commit-hash: 90c541806f23a127002de5b4038be731ba1458ca
commit-date: 2023-05-31
host: x86_64-unknown-linux-gnu
release: 1.70.0
LLVM version: 16.0.2

@JackStade JackStade added the C-bug Category: This is a bug. label Jul 9, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 9, 2023
@Noratrieb Noratrieb added A-type-system Area: Type system T-types Relevant to the types team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jul 9, 2023
@theemathas
Copy link
Contributor

Encountered a similar issue at https://www.reddit.com/r/rust/comments/1i56nk7/comment/m83klsy/

I expected this code to compile:

fn main() {
    // This works
    foo::<Zero>(Zero);
    // This fails
    foo(Zero);
}

fn foo<T>(_: T)
where
    Wrap<T>: WrappedPeano,
{
}

struct Zero;
struct Succ<T>(T);

struct Wrap<T>(T);

pub trait WrappedPeano {}
impl WrappedPeano for Wrap<Zero> {}
impl<T> WrappedPeano for Wrap<Succ<T>> where Wrap<T>: WrappedPeano {}

Instead, I got this error:

error[E0275]: overflow evaluating the requirement `Wrap<Succ<_>>: WrappedPeano`
  --> src/main.rs:5:5
   |
5  |     foo(Zero);
   |     ^^^^^^^^^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`playground`)
note: required for `Wrap<Succ<Succ<_>>>` to implement `WrappedPeano`
  --> src/main.rs:21:9
   |
21 | impl<T> WrappedPeano for Wrap<Succ<T>> where Wrap<T>: WrappedPeano {}
   |         ^^^^^^^^^^^^     ^^^^^^^^^^^^^                ------------ unsatisfied trait bound introduced here
   = note: 126 redundant requirements hidden
   = note: required for `Wrap<Succ<Succ<Succ<Succ<Succ<Succ<Succ<Succ<Succ<Succ<...>>>>>>>>>>>` to implement `WrappedPeano`
note: required by a bound in `foo`
  --> src/main.rs:10:14
   |
8  | fn foo<T>(_: T)
   |    --- required by a bound in this function
9  | where
10 |     Wrap<T>: WrappedPeano,
   |              ^^^^^^^^^^^^ required by this bound in `foo`
   = note: the full name for the type has been written to '/playground/target/debug/deps/playground-535e106d104f71b4.long-type-16015811270050310182.txt'
   = note: consider using `--verbose` to print the full type name to the console

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system C-bug Category: This is a bug. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants