2 releases
Uses new Rust 2024
new 0.1.1 | Apr 14, 2025 |
---|---|
0.1.0 | Apr 14, 2025 |
#2 in #rec
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 Rec
ursive-impl
-friendly extension trait of InternalIterator
.
Whenever impl
ementing 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