Repository navigation
resolve: an anonymous parameter slot hides nothing (nested function-type false refusal) - #13395
Merged
Merged
Conversation
…type false refusal) A function whose declared return is nested function types, `fn(Int) -> fn(Int) -> Int`, was refused resolve_reason_binder_hides_visible_value: each Arrow type's unnamed slot is labelled by its position in its own list (v2.std.anonymous_binder anonymous_param_label, ruled), so both levels bind <anonymous-parameter-1>, and the value-binder gate added by #12506 (861c829) found the outer slot in frame. Measured by instrumenting the gate: the flagged binder is <anonymous-parameter-1>, not a fresh return type variable. An anonymous slot is unauthorable, so no reference can name it and it cannot hide anything. admit_one_value_binder admits it into the frame without the outer lookup, read through is_anonymous_param_label, the one recogniser; the duplicate-in-frame check still applies, and an authored binder hiding an outer parameter still refuses. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Pre-queue gate at head 4c141e7 against merge base 4bf26c8: N7 native route (
The 12 lambda/fold modules, every test function, head vs base: 0 new failures. The only change is
— sent from calm-boar-904 |
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.
The bug. A function whose declared return is nested function types was falsely refused with
resolve_reason_binder_hides_visible_value. For example,fn f(p: Int) -> fn(Int) -> fn(Int) -> Int { x => y => x }. This is the eighth silent red on main:v2.test.claim.body_lowering.function_value_body_routea_curried_function_typed_return_emits_impl_fn_over_box_dyn_fn.First bad #12506 (861c829). It passes at the parent e5859c5 and fails at 861c829, by the claim_batch first-parent bisect.
Which binder, measured. I instrumented
binder_hides_visible_value_diagnosticlocally so its reason carries the flagged binder, then ran the emit route on main:x => y => xrefuses on<anonymous-parameter-1>;fn(x) { fn(y) { x } }also refuses on<anonymous-parameter-1>;So the cause is not a fresh return type variable, which was the first guess.
Why it refuses. Each Arrow type's unnamed domain slot is labelled by its position within its OWN list (
v2.std.anonymous_binderanonymous_param_label, a ruled naming: a counter- or occurrence-derived label would makefn(_: Int) -> Inttwo types at two sites). So both levels offn(Int) -> fn(Int) -> Intbind<anonymous-parameter-1>, and #12506's value-binder gate (admit_value_binders/admit_one_value_binder) found the outer slot in frame.Earliest unjustified link: the gate, not the naming. Hiding is the risk that a body reference silently rebinds to the inner binder. An anonymous slot is unauthorable and never referenceable by construction, so it cannot hide anything.
Fix.
admit_one_value_binderadmits a name answeringis_anonymous_param_label(the one recogniser, already used by emission and reference_conservation) into the frame's locals without the outer lookup. The duplicate-in-frame check still applies, and the naming is unchanged.Controls (
function_value_body_route_test.dag; all 7 claims of the module):Runs: with the fix https://app.buildbuddy.io/invocation/b82aaed0-f7a5-4ef2-8a55-626aaa9720ea ; without it https://app.buildbuddy.io/invocation/e5b00b13-06b3-4729-aa36-6e125cd60f5c .
Pre-queue gate (the 12 lambda/fold modules at head vs merge base; the N7 native diff): results are posted below as they land.
🤖 Generated with Claude Code