Skip to content
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

Infinite recursion in type resolution for unused type #134719

Open
andriyDev opened this issue Dec 24, 2024 · 0 comments
Open

Infinite recursion in type resolution for unused type #134719

andriyDev opened this issue Dec 24, 2024 · 0 comments
Labels
C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. I-hang Issue: The compiler never terminates, due to infinite loops, deadlock, livelock, etc. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@andriyDev
Copy link

Example:

use std::collections::HashMap;
use std::marker::PhantomData;

trait Resource {}

struct Res<'w, T: ?Sized + Resource>(&'w T);

impl<'w, 'a, T: Resource> IntoIterator for &'a Res<'w, T>
where
    &'a T: IntoIterator,
{
    type Item = <&'a T as IntoIterator>::Item;
    type IntoIter = <&'a T as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

trait Matcher<T> {}

impl<'a, A, B, U: Matcher<&'a A>, V: Matcher<&'a B>> Matcher<(&'a A, &'a B)> for (U, V) {}

struct EqMatcher<T>(PhantomData<T>);

impl<T> Matcher<T> for EqMatcher<T> {}

struct ContainerMatcher<T>(Box<dyn Matcher<T>>);

impl<T, ContainerT> Matcher<ContainerT> for ContainerMatcher<T> where
    ContainerT: IntoIterator<Item = T>
{
}

#[test]
fn it_works() {
    // todo just to get the types to work.
    let matcher: Box<(EqMatcher<&u32>, ContainerMatcher<(&u32, &u32)>)> = todo!();
    // This is converting the Box into a Box<dyn Matcher>
    let bad_matcher = ContainerMatcher(matcher);

    let blah = HashMap::<u32, HashMap<u32, u32>>::default();
    fn check<T>(val: T, matcher: impl Matcher<T>) {}
    check(&blah, bad_matcher);
}

As a short summary: I am implementing a trait for one struct to operate on anything that impls IntoIterator. In addition this trait "distributes" to elements in a pair. I then try and merge these two properties to construct bad_matcher. For context, this happens as a result of merging the googletest and bevy_ecs crates.

I expected to see this happen: The test to compile.

Instead, this happened: Failed to compile due to infinite recursion of the Res type (which is completely unused).

error[E0275]: overflow evaluating the requirement `&_: IntoIterator`
  --> src\lib.rs:38:40
   |
38 |     let bad_matcher = ContainerMatcher(matcher);
   |                                        ^^^^^^^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`bevy_googletest`)
note: required for `&Res<'_, _>` to implement `IntoIterator`
  --> src\lib.rs:8:27
   |
8  | impl<'w, 'a, T: Resource> IntoIterator for &'a Res<'w, T>
   |                           ^^^^^^^^^^^^     ^^^^^^^^^^^^^^
9  | where
10 |     &'a T: IntoIterator,
   |            ------------ unsatisfied trait bound introduced here
   = note: 123 redundant requirements hidden
   = note: required for `&Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, ...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implem
ent `IntoIterator`
note: required for `ContainerMatcher<(&u32, &u32)>` to implement `Matcher<&Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<
'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res
<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Re
s<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, _>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
  --> src\lib.rs:30:21
   |
30 | impl<T, ContainerT> Matcher<ContainerT> for ContainerMatcher<T> where
   |                     ^^^^^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^
31 |     ContainerT: IntoIterator<Item = T>
   |                              -------- unsatisfied trait bound introduced here
   = note: 1 redundant requirement hidden
   = note: required for `(EqMatcher, ContainerMatcher<(&u32, &u32)>)` to implement `Matcher<(&u32, &Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res
<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Re
s<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, R
es<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, _>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>)>`
   = note: required for the cast from `Box<(EqMatcher, ContainerMatcher<(&u32, &u32)>)>` to `Box<dyn Matcher<(&u32, &Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Res<'_, Re
s<'_, Res<'_, Res<'_, ...>>>>>>>>>>>>>>>>>>>>>>>>>>>>)>>`
   = note: the full name for the type has been written to 'E:\Content\bevy_googletest\target\debug\deps\bevy_googletest-3fef145a913b892a.long-type-9581655154092012888.txt'
   = note: consider using `--verbose` to print the full type name to the console
   = note: the full name for the type has been written to 'E:\Content\bevy_googletest\target\debug\deps\bevy_googletest-3fef145a913b892a.long-type-1543903567385044461.txt'
   = note: consider using `--verbose` to print the full type name to the console

Meta

rustc --version --verbose:

rustc 1.83.0 (90b35a623 2024-11-26)
binary: rustc
commit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf
commit-date: 2024-11-26
host: x86_64-pc-windows-msvc
release: 1.83.0
LLVM version: 19.1.1

This seems to be fixed with -Znext-solver.

@andriyDev andriyDev added the C-bug Category: This is a bug. label Dec 24, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 24, 2024
@jieyouxu jieyouxu added I-hang Issue: The compiler never terminates, due to infinite loops, deadlock, livelock, etc. T-types Relevant to the types team, which will review and decide on the PR/issue. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. labels Dec 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. I-hang Issue: The compiler never terminates, due to infinite loops, deadlock, livelock, etc. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. 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

3 participants