Repository navigation
Keep the closure when a cast instantiates a capturing untyped arrow - #708
Merged
Merged
Conversation
`new W((v) => { seen += 1; })` crashed in every memory model. The arrow has
no parameter types, so it stays generic until the cast to the constructor
parameter's type instantiates it. verifyFunctionCastRules did that through
instantiateSpecializedFunction but kept only its LogicalResult: when the
arrow captures, the result is a new value (the closure bound over the
captured variables), and the cast went on with the bare function, whose
captures were then read through a null pointer.
verifyFunctionCastRules now takes value and valueType by reference and
continues the cast with the returned closure, as instantiateGenericsForBinaryOp
already does. Under -mm=own the program now gets the escaping-closure
diagnostic the explicitly typed form already got.
Regression test 00capture_in_new_untyped_arrow.ts (gc compile/jit, rc and
none through the corpus).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem
This program crashed with a stack dump under every memory model (gc, rc, none, own):
The arrow
(v) => ...has no parameter types, so it stays generic until the cast to the constructor parameter's type instantiates it.verifyFunctionCastRulesdid that throughinstantiateSpecializedFunction, but it kept only theLogicalResult. When the arrow captures something, the result is a new value: the closure bound over the captured variables. The cast carried on with the bare function, so the constructor stored a function whose captures were a null pointer.The same arrow worked as an argument to an ordinary call, where the delayed instantiation already uses the returned value. It also worked with typed parameters, or when it captured nothing.
Fix
verifyFunctionCastRulesnow takesvalueandvalueTypeby reference. It finishes the cast with the returned closure, the same wayinstantiateGenericsForBinaryOpalready did, and refreshesvalueTypeafter instantiation.Results
1.-mm=own: the program now gets the same "captured by a closure that escapes" diagnostic that the explicitly typed form already got.00capture_in_new_untyped_arrow.tscovers a parameter property, a stored field, a value-returning arrow and a non-capturing control. It runs as gc compile and JIT, and as rc and none through the corpus.ctest -C Release: 100% passed, 0 failed out of 6026.🤖 Generated with Claude Code