From 00c8f82ebf76b27be97dcb50f507e235cc22ed75 Mon Sep 17 00:00:00 2001 From: Takumi Shotoku Date: Sun, 3 May 2026 12:04:44 +0900 Subject: [PATCH] Fix NoMethodError in CallBaseNode#modified_vars for anonymous rest Since ff8a5167, anonymous rest arguments (bare `*`) are represented as `nil` placeholders in `@positional_args` instead of `DummyNilNode`. However, `CallBaseNode#modified_vars` iterates the positional args array without skipping nil, raising NoMethodError when a call with anonymous rest forwarding appears inside a branch (e.g. `if cond; bar(*); end`) whose `modified_vars` is walked from `BranchNode#install0`. Use safe navigation so nil placeholders are skipped, matching how `each_subnode` already guards against nil subnodes. Add a regression case to scenario/args/anonymous_rest.rb. --- lib/typeprof/core/ast/call.rb | 2 +- scenario/args/anonymous_rest.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/typeprof/core/ast/call.rb b/lib/typeprof/core/ast/call.rb index a2ddb1e31..59f9c9313 100644 --- a/lib/typeprof/core/ast/call.rb +++ b/lib/typeprof/core/ast/call.rb @@ -247,7 +247,7 @@ def modified_vars(tbl, vars) subnode.modified_vars(tbl, vars) end else - subnode.each {|n| n.modified_vars(tbl, vars) } + subnode.each {|n| n&.modified_vars(tbl, vars) } end end end diff --git a/scenario/args/anonymous_rest.rb b/scenario/args/anonymous_rest.rb index e66e7efbd..deebf1ee6 100644 --- a/scenario/args/anonymous_rest.rb +++ b/scenario/args/anonymous_rest.rb @@ -7,10 +7,17 @@ def bar(*) nil end +def foo_in_if(*) + if true + bar(*) + end +end + bar(1, "foo") ## assert class Object def foo: (*untyped) -> nil def bar: (*Integer | String) -> nil + def foo_in_if: (*untyped) -> nil end