diff options
| author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-09-13 22:09:22 +0900 |
|---|---|---|
| committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-09-15 01:09:06 +0900 |
| commit | 864bb8680cee48a2bed85703dc2e4070728362d4 (patch) | |
| tree | c112ae4b3afc70ff40e8f82f54aca2823fe8a2be | |
| parent | e8896a31d48e5797df3878696dcb50aed85b87c2 (diff) | |
[Bug #19877] Named captures should take place from regexps in block
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/8440
| -rw-r--r-- | parse.y | 15 | ||||
| -rw-r--r-- | test/ruby/test_parse.rb | 14 |
2 files changed, 27 insertions, 2 deletions
@@ -10965,6 +10965,16 @@ new_command_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *a } #define nd_once_body(node) (nd_type_p((node), NODE_ONCE) ? (node)->nd_body : node) + +static NODE* +last_expr_once_body(NODE *node) +{ + if (!node) return 0; + node = last_expr_node(node); + if (!node) return 0; + return nd_once_body(node); +} + static NODE* match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_loc, const YYLTYPE *loc) { @@ -10973,7 +10983,8 @@ match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_lo value_expr(node1); value_expr(node2); - if (node1 && (n = nd_once_body(node1)) != 0) { + + if ((n = last_expr_once_body(node1)) != 0) { switch (nd_type(n)) { case NODE_DREGX: { @@ -10993,7 +11004,7 @@ match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_lo } } - if (node2 && (n = nd_once_body(node2)) != 0) { + if ((n = last_expr_once_body(node2)) != 0) { NODE *match3; switch (nd_type(n)) { diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index 5209a4839f..0f71e11f7e 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -970,6 +970,20 @@ x = __ENCODING__ assert_warning('') {eval("#{a} = 1; /(?<#{a}>)/ =~ ''")} end + def test_named_capture_in_block + [ + '(/(?<a>.*)/)', + '(;/(?<a>.*)/)', + '(%s();/(?<a>.*)/)', + '(%w();/(?<a>.*)/)', + '(1; (2; 3; (4; /(?<a>.*)/)))', + '(1+1; /(?<a>.*)/)', + ].each do |code| + token = Random.bytes(4).unpack1("H*") + assert_equal(token, eval("#{code} =~ #{token.dump}; a")) + end + end + def test_rescue_in_command_assignment bug = '[ruby-core:75621] [Bug #12402]' all_assertions(bug) do |a| |
