Skip to content

Commit 75c6ce0

Browse files
authored
- numbered parameters are valid for pattern matching pinning (#1060)
The following is how different versions behave: ``` # Valid only in 2.7 case 0; in _1; end 1.then { 1 in _1 } # Valid in no versions case 0; in ^_1; end # Valid an all versions 1.then { 1 in ^_1 } ``` `@builder.accessible` makes the numparam visible to the environment, so it must be called first
1 parent 6c92533 commit 75c6ce0

File tree

7 files changed

+62
-6
lines changed

7 files changed

+62
-6
lines changed

lib/parser/ruby27.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2152,11 +2152,12 @@ opt_block_args_tail:
21522152
p_var_ref: tCARET tIDENTIFIER
21532153
{
21542154
name = val[1][0]
2155+
lvar = @builder.accessible(@builder.ident(val[1]))
2156+
21552157
unless static_env.declared?(name)
21562158
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
21572159
end
21582160
2159-
lvar = @builder.accessible(@builder.ident(val[1]))
21602161
result = @builder.pin(val[0], lvar)
21612162
}
21622163

lib/parser/ruby30.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2225,11 +2225,12 @@ opt_block_args_tail:
22252225
p_var_ref: tCARET tIDENTIFIER
22262226
{
22272227
name = val[1][0]
2228+
lvar = @builder.accessible(@builder.ident(val[1]))
2229+
22282230
unless static_env.declared?(name)
22292231
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
22302232
end
22312233
2232-
lvar = @builder.accessible(@builder.ident(val[1]))
22332234
result = @builder.pin(val[0], lvar)
22342235
}
22352236

lib/parser/ruby31.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2323,11 +2323,12 @@ opt_block_args_tail:
23232323
p_var_ref: tCARET tIDENTIFIER
23242324
{
23252325
name = val[1][0]
2326+
lvar = @builder.accessible(@builder.ident(val[1]))
2327+
23262328
unless static_env.declared?(name)
23272329
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
23282330
end
23292331
2330-
lvar = @builder.accessible(@builder.ident(val[1]))
23312332
result = @builder.pin(val[0], lvar)
23322333
}
23332334

lib/parser/ruby32.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2332,11 +2332,12 @@ opt_block_args_tail:
23322332
p_var_ref: tCARET tIDENTIFIER
23332333
{
23342334
name = val[1][0]
2335+
lvar = @builder.accessible(@builder.ident(val[1]))
2336+
23352337
unless static_env.declared?(name)
23362338
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
23372339
end
23382340
2339-
lvar = @builder.accessible(@builder.ident(val[1]))
23402341
result = @builder.pin(val[0], lvar)
23412342
}
23422343

lib/parser/ruby33.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2278,11 +2278,12 @@ opt_block_args_tail:
22782278
p_var_ref: tCARET tIDENTIFIER
22792279
{
22802280
name = val[1][0]
2281+
lvar = @builder.accessible(@builder.ident(val[1]))
2282+
22812283
unless static_env.declared?(name)
22822284
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
22832285
end
22842286
2285-
lvar = @builder.accessible(@builder.ident(val[1]))
22862287
result = @builder.pin(val[0], lvar)
22872288
}
22882289

lib/parser/ruby34.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2285,11 +2285,12 @@ opt_block_args_tail:
22852285
p_var_ref: tCARET tIDENTIFIER
22862286
{
22872287
name = val[1][0]
2288+
lvar = @builder.accessible(@builder.ident(val[1]))
2289+
22882290
unless static_env.declared?(name)
22892291
diagnostic :error, :undefined_lvar, { :name => name }, val[1]
22902292
end
22912293
2292-
lvar = @builder.accessible(@builder.ident(val[1]))
22932294
result = @builder.pin(val[0], lvar)
22942295
}
22952296

test/test_parser.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9567,6 +9567,56 @@ def test_pattern_matching_blank_else
95679567
)
95689568
end
95699569

9570+
def test_pattern_matching_numbered_parameter
9571+
assert_parses(
9572+
s(:numblock,
9573+
s(:send,
9574+
s(:int, 1), :then), 1,
9575+
s(:match_pattern,
9576+
s(:int, 1),
9577+
s(:pin,
9578+
s(:lvar, :_1)))),
9579+
%q{1.then { 1 in ^_1 }},
9580+
%q{},
9581+
%w(2.7)
9582+
)
9583+
9584+
assert_parses(
9585+
s(:numblock,
9586+
s(:send,
9587+
s(:int, 1), :then), 1,
9588+
s(:match_pattern_p,
9589+
s(:int, 1),
9590+
s(:pin,
9591+
s(:lvar, :_1)))),
9592+
%q{1.then { 1 in ^_1 }},
9593+
%q{},
9594+
SINCE_3_0
9595+
)
9596+
9597+
assert_parses(
9598+
s(:case_match,
9599+
s(:int, 0),
9600+
s(:in_pattern,
9601+
s(:match_var, :_1), nil, nil), nil),
9602+
%q{case 0; in _1; end},
9603+
%q{},
9604+
%w(2.7)
9605+
)
9606+
9607+
assert_diagnoses(
9608+
[:error, :reserved_for_numparam, { :name => '_1' }],
9609+
%q{case 0; in _1; end},
9610+
%q{ ^^ location},
9611+
SINCE_3_0)
9612+
9613+
assert_diagnoses(
9614+
[:error, :undefined_lvar, { :name => '_1' }],
9615+
%q{case 0; in ^_1; end},
9616+
%q{ ^^ location},
9617+
SINCE_2_7)
9618+
end
9619+
95709620
def assert_pattern_matching_defines_local_variables(match_code, lvar_names, versions = SINCE_2_7)
95719621
code = "case 1; #{match_code}; then [#{lvar_names.join(', ')}]; end"
95729622

0 commit comments

Comments
 (0)