Skip to content

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

Closed
@apoelstra

Description

@apoelstra

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions