route a call through a loop variable to the loop's storage slot - #618
Merged
Conversation
giving a for loop variable its own slot fixed the over-release and the clobbering, but a call through that variable still named the source variable: `for f in fns:` stored into __loopvar_0_f while `f(x)` emitted `call r f`. the consumer resolves a non-function callee by variable name, found no `f`, and fell through to the unresolved-function stub — a compile-clean program that died at runtime with "call to a function the compiler could not resolve". indexing the list worked all along, which is how it hid. the callee resolution now consults the loop-slot mapping the loads and stores already use, only for a bare identifier that is not a declared function — so a plain function call cannot be captured by a loop variable that happens not to shadow it, and everything else is unchanged. the case covers the plain loop call, nested loops with two live fn variables, rebinding the name after the loop, and a mixed-type pair of fn lists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
summary
the loop-variable slot fix gave
for f in fns:its own storage(
__loopvar_0_f), but a call through the variable still emittedcall r f.the consumer resolves a non-function callee by variable name, found no
f,and fell through to the runtime's unresolved-function stub, so a program that
compiled cleanly died at runtime. indexing (
fns[i](x)) always worked, whichis why the gap survived: nothing in the corpus called through a loop variable.
the fix is one interception in the static-call path: a bare-identifier callee
that is not a declared function consults the same loop-slot mapping that loads
and stores already use. a declared function keeps its direct call even if a
loop variable of the same name is live, so nothing existing changes shape.
what was tested
new regression case: the plain loop call, nested loops with two live fn
variables at once, rebinding the loop variable's name after the loop, and a
mixed pair of
List[fn(Int) -> Int]andList[fn(Int) -> String]. verifiedidentical under green default and
PITH_GREEN=0, and valgrind-clean with thestruct freelist disabled.
full battery:
make testboth backends,make bootstrap-verify, both corpora,make memcheck,make leak-check. seed refreshed last and the driver rebuiltfrom the committed seed alone.