Skip to content

Commit d34616f

Browse files
authored
- builder.rb: correctly handle ... forwarding to super with explicit block (#1049)
Upstream commit ruby/ruby@a850cd1 is specific to 3.3, previous versions already did not allow this. See https://bugs.ruby-lang.org/issues/20392 for a bit more info. But since the super node has has a different shape, it behaved unexpectedly in earlier ruby versions already. It allowed forwarding with zero and one arguments and failed for more. Now correctly rejects it as invalid syntax, except in Ruby 3.3, that fix has not been backported.
1 parent beb5ccd commit d34616f

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/parser/builders/default.rb

+8-4
Original file line numberDiff line numberDiff line change
@@ -1120,15 +1120,19 @@ def call_lambda(lambda_t)
11201120
end
11211121

11221122
def block(method_call, begin_t, args, body, end_t)
1123-
_receiver, _selector, *call_args = *method_call
1124-
11251123
if method_call.type == :yield
11261124
diagnostic :error, :block_given_to_yield, nil, method_call.loc.keyword, [loc(begin_t)]
11271125
end
11281126

1129-
last_arg = call_args.last
1127+
if method_call.type == :super
1128+
*_args, last_arg = *method_call
1129+
else
1130+
_receiver, _selector, *_args, last_arg = *method_call
1131+
end
11301132
if last_arg && (last_arg.type == :block_pass || last_arg.type == :forwarded_args)
1131-
diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
1133+
if (@parser.version == 33 && method_call.type != :super) || @parser.version != 33
1134+
diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
1135+
end
11321136
end
11331137

11341138
if args.type == :numargs

test/test_parser.rb

+24
Original file line numberDiff line numberDiff line change
@@ -8163,6 +8163,30 @@ def test_forward_args_invalid
81638163
SINCE_2_7 - SINCE_3_1)
81648164
end
81658165

8166+
def test_forward_args_super_with_block
8167+
[
8168+
%q{def foo(...) super(...) {}; end},
8169+
%q{def foo(...) super(a, ...) {}; end},
8170+
%q{def foo(...) super(a, b, ...) {}; end},
8171+
].each do |code|
8172+
# https://bugs.ruby-lang.org/issues/20392
8173+
refute_diagnoses(code, %w(3.3))
8174+
assert_diagnoses(
8175+
[:error, :block_and_blockarg],
8176+
code,
8177+
%q{},
8178+
SINCE_2_7 - %w(3.3))
8179+
end
8180+
8181+
[
8182+
%q{def foo(...) super {}; end},
8183+
%q{def foo(...) super() {}; end},
8184+
%q{def foo(...) super(a) {}; end},
8185+
%q{def foo(...) super(a, b) {}; end},
8186+
].each do |code|
8187+
refute_diagnoses(code, SINCE_2_7)
8188+
end
8189+
end
81668190
def test_trailing_forward_arg
81678191
assert_parses(
81688192
s(:def, :foo,

0 commit comments

Comments
 (0)