Issue #20051 has been updated by jeremyevans0 (Jeremy Evans).
Looks like I was testing on Ruby 3.2, not on master. The current master branch has even
worse behavior for keywords. The following code segfaults in the compiler (`--dump=parse`
works, `--dump=i` segfaults):
```ruby
Object[kw: 1] += 1
```
Code with keyword splats results in a TypeError:
```ruby
h = Object.new
def h.[](*a, **b) p [:[], a, b]; 3 end
def h.[]=(*a, **b) p [:[]=, a, b]; nil end
kw = Object.new
def kw.to_hash; p [:to_hash]; {4=>5} end
h[**kw] += 1
```
In Ruby 3.2:
```
[:[], [#<Object:0x00000ce0f9c44c80>], {}]
[:[]=, [#<Object:0x00000ce0f9c44c80>, 4], {}]
```
In Ruby 3.3-preview3:
```
[:to_hash]
[:[], [], {4=>5}]
t/t99.rb:8:in `<main>': no implicit conversion of Integer into Hash (TypeError)
h[**kw] += 1
^^^^^^^^^^
```
----------------------------------------
Bug #20051: Op asgn calls handle keywords and keyword splats as positional arguments
https://bugs.ruby-lang.org/issues/20051#change-105591
* Author: jeremyevans0 (Jeremy Evans)
* Status: Open
* Priority: Normal
* Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
Ruby passes a keywords given to op asgn method calls as a positional hash argument, both
to `[]` and `[]=`:
```ruby
foo[kw: 1] += bar
```
This seems wrong, because `foo[kw: 1]` passes `kw: 1` as keywords.
Worse, Ruby passes a keyword splat given to the op asgn method calls as a regular
positional argument to `[]` and `[]=`, with no `to_hash` conversion:
```ruby
foo[**kw] += bar
```
Example:
```ruby
[1][**0] += 2
# => 3
```
I'll try to fix this before the 3.3 release if I have time, but if anyone else wants
to work on a fix, please do so.
--
https://bugs.ruby-lang.org/