Don't generalize capturing lambdas in argument position#9708
Merged
Conversation
A static-dispatch method chain on a not-yet-concrete value, such as letters.to_utf8().contains(...) where letters is a string literal flowing through find_first, could report a spurious MISSING METHOD error. The cause was that a capturing lambda passed directly as a call argument was generalized at its own rank, before the caller pinned its parameter types, freezing the lambda body's dispatch chain as a generalized scheme. When the predicate was then instantiated, only the instantiated copy's dispatches resolved, leaving the original CIR node's type variable an unresolved flex dispatcher that the end-of-check ambiguity sweep flagged. A bare (non-capturing) lambda in argument position already skips generalization via the !is_call_arg guard in shouldGeneralize; the closure case slipped through because checkExpr clears checking_call_arg before delegating to the inner lambda. Re-assert the flag in the e_closure case so a capturing argument lambda is treated the same as a bare one and its dispatch chain resolves in place once the element type is pinned.
report.zig already emits "the annotation says it should be"; this snapshot still had the older "annotation say" wording, so a full snapshot regen (run-check-snapshots in CI) leaves it dirty. Regenerate it to match.
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.
Closes #9699.
A static-dispatch method chain on a value whose type is not yet concrete — such as
letters.to_utf8().contains(...)wherelettersis a string literal flowing throughfind_first— could report a spuriousMISSING METHOD: ... on an unresolved type variableerror. The cause was that a capturing lambda passed directly as a call argument was being generalized at its own rank, before the caller pinned its parameter types. That froze the lambda body's static-dispatch chain as a generalized scheme; when the predicate was then instantiated, only the instantiated copy's dispatches got resolved against the concrete element type, leaving the original CIR node's type variable an unresolved flex dispatcher that the end-of-check ambiguity sweep then flagged.A bare (non-capturing) lambda in argument position already skips generalization via the
!is_call_argguard inshouldGeneralize; the closure (capture-wrapper) case slipped through becausecheckExprclears thechecking_call_argflag before delegating to the inner lambda. The fix re-asserts that flag in thee_closurecase, so a capturing argument lambda is treated the same as a bare one and is not generalized — letting its dispatch chain resolve in place oncefind_firstpins the element type, with the side benefit of creating fewer type variables.