Skip to content

fix: prevent panic on variadic anonymous functions with closure variables - #535

Open
Thanatos9404 wants to merge 3 commits into
uber-go:mainfrom
Thanatos9404:fix/anonymousfunc-variadic-closure-panic
Open

Thanatos9404 wants to merge 3 commits into
uber-go:mainfrom
Thanatos9404:fix/anonymousfunc-variadic-closure-panic

Conversation

@Thanatos9404

@Thanatos9404 Thanatos9404 commented Oct 19, 2026 •

Copy link
Copy Markdown

Fixes #532

With -experimental-anonymous-function, a variadic function literal that captures a variable makes the analyzer panic (want variadic parameter of slice or string type), which hides every other diagnostic in the package. createFakeFuncDecl appends the closure variables after the literal's parameters but keeps the variadic flag, so the last parameter is no longer the variadic one. A captured slice doesn't panic, but it gets treated as the variadic parameter.

Changes:

  • createFakeFuncDecl inserts the closure variables right before the variadic parameter, in both the AST and the signature. Non-variadic literals are unchanged.
  • funcArgsFromCallExpr passes them at the same position, before the variadic arguments.
  • An xs... argument is now detected by comparing it with the call's last argument instead of by index. As a side effect, a method expression call like T.m(t, xs...) is now handled like t.m(xs...).

Testing: new cases in testdata/src/anonymousfunction/variadic.go and the assertion/anonymousfunc testdata. TestAnonymousFunction and TestClosureCollection fail on main and pass with this change.

This is independent of #534 and the two merge cleanly. A literal with closure variables called as f(g()) still panics, as it already does on main for non-variadic literals.

…bles

With -experimental-anonymous-function, the fake func decl created for a
function literal gets one extra parameter per closure variable, appended
after the literal's own parameters, while the fake signature keeps the
literal's variadic flag. For a variadic literal, the last parameter is
then a closure variable instead of the variadic slice, so
types.NewSignatureType panics ("got *T, want variadic parameter of slice
or string type"), and the panic hides every other diagnostic in the
package. A captured slice or string does not panic, but is then treated
as the variadic parameter.

Insert the fake parameters right before the variadic parameter instead,
in both the AST field list and the signature, so that the fake func
stays variadic, and pass the closure variables at the same position at
the call sites: after the regular arguments, before the variadic ones.
The argument unpacked with `...` is now recognized by identity rather
than by its index, since the closure variables come before it. This
also covers method expressions such as T.m(t, xs...), whose receiver is
not passed to the method as an argument.

Only making the fake signature non-variadic is not enough: calls with
more than one variadic argument then panic with "no such parameter
number", and the arguments flow to the wrong parameters.

Fixes uber-go#532
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 35bac9d6-db88-485f-a6c1-a04524089c7e
Commits

Reviewing files that changed from the base of the PR and between 1be6d77 and 9e91659.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review

No actionable comments were generated in the recent review.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed analysis of variadic anonymous functions so captured variables and variadic arguments are handled in the correct order.
    • Improved handling of slice expansion in variadic calls, including method calls.
  • Tests
    • Added coverage for variadic closures, captured variables, argument flow, and slice expansion.

Walkthrough

The analyzer now places captured closure parameters before variadic parameters in fake declarations and call arguments. Variadic-unpacking detection checks whether the argument expression is the call’s final argument. Tests cover fake declaration signatures and variadic closure analysis, including captured values, argument flow, and slice expansion.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: Minimal · previous review 9119c

No merge-blocking issue was identified in the variadic closure change; it is ready for normal merge checks.

Pre-merge checks: Passed 4

Check name Status Explanation
Linked Issues check Passed The changes satisfy #532. createFakeFuncDecl places captured closure parameters before the variadic parameter in the fake declaration and signature. Call argument construction uses the same order. T…
Out of Scope Changes check Passed The changes stay within the implementation and test scope of #532. The call-site update is required to keep arguments aligned with the new fake parameter order. The unpacked-argument check and method-…
Title check Passed The title clearly and concisely identifies the main fix: preventing panics when variadic anonymous functions capture closure variables.
Description check Passed The description directly explains the panic, the implementation changes, testing, and known limitations. It is fully related to the changeset.
Full details: Linked Issues check

Explanation

The changes satisfy #532. createFakeFuncDecl places captured closure parameters before the variadic parameter in the fake declaration and signature. Call argument construction uses the same order. The variadic parameter therefore remains last and preserves variadic behavior. The added regression test covers the reported receiver capture and verifies that analysis reports the variadic-parameter indexing diagnostic instead of panicking. Additional tests cover nil closure flow and captured slices. The reported test validation also supports the fix.

Full details: Out of Scope Changes check

Explanation

The changes stay within the implementation and test scope of #532. The call-site update is required to keep arguments aligned with the new fake parameter order. The unpacked-argument check and method-expression test cover the shared call-path behavior affected by that fix. The declaration tests and variadic test fixture provide regression coverage. No unrelated product behavior or unrelated files are identified.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

ℹ️ Recent review info

⚙️ Run configuration

  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ce54d1bc-3db7-4687-8455-aea8a613a405
📥 Commits

Reviewing files that changed from the base of the PR and between acb8859 and 9119ca4.

📒 Files selected for processing: 5

  • assertion/anonymousfunc/analyzer.go
  • assertion/anonymousfunc/analyzer_test.go
  • assertion/anonymousfunc/testdata/src/go.uber.org/anonymousfunc/variadic.go
  • assertion/function/assertiontree/root_assertion_node.go
  • testdata/src/anonymousfunction/variadic.go

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

@CLAassistant

CLAassistant commented Oct 21, 2026 •

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ ccuetoh
❌ Thanatos9404
You have signed the CLA already but the status is still pending? Let us recheck it.

@ccuetoh ccuetoh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Thanatos9404! Thank you very much for your contribution and for taking this fix. The changes look good to me!

Please note that you need to sign the CLA before the changes can be merged. See the CLAassistant bot comment.

@codecov

codecov Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.92%. Comparing base (ccd0056) to head (9e91659).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #535      +/-   ##
==========================================
- Coverage   93.20%   92.92%   -0.28%     
==========================================
  Files          82       82              
  Lines        8515     9949    +1434     
==========================================
+ Hits         7936     9245    +1309     
- Misses        579      694     +115     
- Partials        0       10      +10     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Golden Test

Note

✅ NilAway errors reported on standard libraries are identical.

2394 errors on base branch (main, ccd0056)
2394 errors on test branch (345ca61)

@ccuetoh

ccuetoh commented Nov 12, 2026

Copy link
Copy Markdown
Collaborator

@Thanatos9404, changes re-approved pending CLA signing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anonymous-function analysis panics on a variadic function literal that captures a pointer-typed variable

3 participants