
Issue #21031 has been updated by jeremyevans0 (Jeremy Evans). Eregon (Benoit Daloze) wrote in #note-1:
@jeremyevans0 Isn't this parse.y behavior breaking the optimization to forward `*/**/&` efficiently (and maybe `...` too)? It means static analysis can't reason about where the `*/**/&/...` are used.
For `*` and `**`, it shouldn't break the allocationless anonymous splat forwarding optimization. The optimization just makes the parameter not allocate an array/hash, regardless of the content of the method, since you can only splat the arguments, not access them directly. For `&`, there is no optimization for anonymous block arguments. The block argument optimization to avoid Proc allocation was `getblockparamproxy` in Ruby 2.5, and applies to both named and anonymous blocks, and I believe works fine in `eval` (maybe @ko1 can confirm). For `...`, that never used allocationless anonymous splat forwarding in a shipped version of Ruby, only temporarily during the 3.4 development cycle. @tenderlovemaking applied a separate generic argument forwarding optimization (commit:cdf33ed5f37f9649c482c3ba1d245f0d80ac01ce). I assume it works inside `eval`, but @tenderlovemaking would know better than I. ---------------------------------------- Bug #21031: Incompatibility with prism and parse.y when eval'ing unnamed forwarding variables https://bugs.ruby-lang.org/issues/21031#change-111464 * Author: ksss (Yuki Kurihara) * Status: Open * ruby -v: ruby 3.5.0dev (2025-01-13T03:12:28Z master 384e6945ac) +PRISM [arm64-darwin23] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ## Case 1 ```rb # t.rb def foo(*) eval("p(*)") end foo(1) ``` ``` $ ruby --parser=prism t.rb t.rb:4:in 'Kernel#eval': (eval at t.rb:4):1: syntax error found (SyntaxError)
1 | p(*) | ^ unexpected `*`; no anonymous rest parameter
from t.rb:4:in 'Object#foo' from t.rb:7:in '<main>' ``` ``` $ ruby --parser=parse.y t.rb 1 ``` ## Case 2 ```rb # t.rb def foo(**) eval("p(**)") end foo(a: 1) ``` ``` $ ruby --parser=prism t.rb t.rb:4:in 'Kernel#eval': (eval at t.rb:4):1: syntax error found (SyntaxError)
1 | p(**) | ^~ unexpected `**`; no anonymous keyword rest parameter
from t.rb:4:in 'Object#foo' from t.rb:7:in '<main>' ``` ``` $ ruby --parser=parse.y t.rb {a: 1} ``` ## Case 3 ```rb # t.rb def foo(&) eval("p(&)") end foo{} ``` ``` $ ruby --parser=prism t.rb t.rb:4:in 'Kernel#eval': (eval at t.rb:4):1: syntax error found (SyntaxError)
1 | p(&) | ^ unexpected `&`; no anonymous block parameter
from t.rb:4:in 'Object#foo' from t.rb:7:in '<main>' ``` ``` $ ruby --parser=parse.y t.rb ``` ## Case 4 ```rb # t.rb def foo(...) eval("p(...)") end foo(1, 2, 3) ``` ``` $ ruby --parser=prism t.rb t.rb:4:in 'Kernel#eval': (eval at t.rb:4):1: syntax error found (SyntaxError)
1 | p(...) | ^~~ unexpected ... when the parent method is not forwarding
from t.rb:4:in 'Object#foo' from t.rb:7:in '<main>' ``` ``` $ ruby --parser=parse.y t.rb 1 2 3 ``` I expect to the parse.y behavior. -- https://bugs.ruby-lang.org/