#rec #iterator #internal-iterator-rec

internal_iterator_rec

Recursive extension for the internal_iterator crate

2 releases

Uses new Rust 2024

new 0.1.1 Apr 14, 2025
0.1.0 Apr 14, 2025

#2 in #rec

Zlib OR Apache-2.0 OR MIT

6KB
50 lines

internal_iterator_rec

Recursive extension for the internal_iterator crate

Most of this was done by danielhenrymantilla, who is way smarter at Rust. I've just packed up their example code into a complete crate.


lib.rs:

A Recursive-impl-friendly extension trait of InternalIterator.

Whenever implementing InternalIterator is to be done by recurse-delegating to multiple sub-fields, then the mut f: F = impl FnMut(…) visitor cannot be used by value, and a &mut f borrow of it needs to be used.

But, given the recursion, if the child field is of a type which may ultimately contain the parent (as is often the case with mutually recursive AST definitions), it means we will end up back at our original function call, but with F having become &mut F.

And even if this recursion will terminate at runtime, the type system and codegen / <F>-generic-code monorphization stages don't know of this (similar problem to that of a recursive type).

This means that codegen will try to monomorphize the code for <F>, then for <&mut F>, then for <&mut &mut F>, etc., ad nauseam, since there is no termination within the type system.

This issue, called a "polymorphization error", causes compilation (codegen) to fail.

The solution, then, is to start off a reborrowable &mut F arg to begin with. That way, the recursive stage with multiple accesses can keep using this arg (reborrows of &mut F).

Granted, we are technically back at a similar situation (codegen for &'r mut F ultimately requires codegen for &'slightly_shorter mut F, and so on), but this is fine since lifetimes do not affect codegen).

But InternalIterator offers no such method.

Hence this helper "extension" trait, simply offering such a method, alongside a helper macro to play the role of the blanket impl (which cannot be written due to orphan rules) from which the proper InternalIterator impl can be derived (by delegating to our well-defined &mut F case).

Dependencies

~58KB