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

New "infinite recursion" error in latest nightly (2023-04-21) #110656

Closed
apoelstra opened this issue Apr 21, 2023 · 5 comments
Closed

New "infinite recursion" error in latest nightly (2023-04-21) #110656

apoelstra opened this issue Apr 21, 2023 · 5 comments
Labels
C-bug Category: This is a bug.

Comments

@apoelstra
Copy link
Contributor

apoelstra commented Apr 21, 2023

I will spend a bit of time minimizing this, but I'm filing an issue now while the details are fresh in my head, since I might not have time until tomorrow.

My crate has the following recursive function which takes a FnMut pred and then calls itself with &mut pred. This causes an infinite chain of &mut &mut &mut ... for the compiler when trying to resolve F: FnMut. This seems natural enough except that this code has been present for at least 2 years, and has worked fine until the 2023-04-21 nightly. The 2023-04-20 will accept it.

Specifically the error is

error[E0275]: overflow evaluating the requirement `F: FnMut<(&Pk,)>`
  |
  = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`miniscript`)
  = note: required for `&mut AAA` to implement `FnMut<(&Pk,)>`
  = note: 128 redundant requirements hidden
  = note: required for `&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut ...` to implement `FnMut<(&Pk,)>`
  = note: the full type name has been written to '/store/home/apoelstra/code/rust-bitcoin/miniscript/master/target/release/deps/miniscript-79ed028b5570a04b.long-type-1335565870067577868.txt'

There is a workaround, which is to replace the offending &mut pred with &mut |key| pred(key), but I don't understand exactly what type magic is going on here that makes one okay but not the other. It never occurred to me to use this form except that I showed this error to GPT4 and that's what it suggested I do.

My questions are then:

  • Is this a regression in the compiler?
  • Is my code at fault?
  • Why does &mut |key| pred(key) break the recursion? Thoughout my codebase, but not here for some reason, I have a number of functions that take &mut F with F: FnMut rather than directly taking F. I call these functions names like real_for_each and then call them from the API-exposed for_each which directly takes F. Is this closure trick an alternative solution to avoiding compiler errors?
@apoelstra apoelstra added the C-bug Category: This is a bug. label Apr 21, 2023
@apoelstra
Copy link
Contributor Author

On further reflection I think I understand why &mut |key| pred(key) works -- it hides the &mut-ref inside the closure, while the type of the closure itsel only includes F.

I have also convinced myself that my code is at fault, though since it used to work, it may be prudent to change the compiler to merely warn on this for a few iterations, or something.

@saethlin
Copy link
Member

saethlin commented Apr 22, 2023

Duplicate of #110475 (same report, same root cause conclusion too. Neat)

@saethlin saethlin marked this as a duplicate of #110475 Apr 22, 2023
@apoelstra
Copy link
Contributor Author

@saethlin thank you for finding this! I only checked the open issues from the last 24 hours since I wasn't able to reproduce the issue until the most recent nightly.

@apoelstra
Copy link
Contributor Author

Indeed, it looks like trying to use this method will cause a compilation error on any compiler -- but one that includes a line number, and one that only occurs when used. So that answers my "how did this ever work?" confusion. It didn't :).

However, what has changed is that even code that doesn't use the offending funciton, now fails to compile.

@jyn514
Copy link
Member

jyn514 commented Apr 26, 2023

I'm going to close this as a duplicate.

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.
Projects
None yet
Development

No branches or pull requests

3 participants