diff --git a/compile.c b/compile.c index 24d980e95fe702..8b574cb5b340cd 100644 --- a/compile.c +++ b/compile.c @@ -4213,11 +4213,28 @@ compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) } static int -compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) +compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { int cnt; + + if (!RNODE_DREGX(node)->nd_next) { + VALUE match = RNODE_DREGX(node)->nd_lit; + if (RB_TYPE_P(match, T_REGEXP)) { + if (!popped) { + ADD_INSN1(ret, node, putobject, match); + RB_OBJ_WRITTEN(iseq, Qundef, match); + } + return COMPILE_OK; + } + } + CHECK(compile_dstr_fragments(iseq, ret, node, &cnt)); ADD_INSN2(ret, node, toregexp, INT2FIX(RNODE_DREGX(node)->nd_cflag), INT2FIX(cnt)); + + if (popped) { + ADD_INSN(ret, node, pop); + } + return COMPILE_OK; } @@ -9901,14 +9918,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no case NODE_EVSTR: CHECK(compile_evstr(iseq, ret, RNODE_EVSTR(node)->nd_body, popped)); break; - case NODE_DREGX:{ - compile_dregx(iseq, ret, node); - - if (popped) { - ADD_INSN(ret, node, pop); - } + case NODE_DREGX: + compile_dregx(iseq, ret, node, popped); break; - } case NODE_ONCE:{ int ic_index = body->ise_size++; const rb_iseq_t *block_iseq; diff --git a/parse.y b/parse.y index f767108181591d..5922c410929c54 100644 --- a/parse.y +++ b/parse.y @@ -12891,8 +12891,8 @@ new_regexp(struct parser_params *p, NODE *node, int options, const YYLTYPE *loc) } if (!RNODE_DREGX(node)->nd_next) { VALUE src = RNODE_DREGX(node)->nd_lit; - nd_set_type(node, NODE_LIT); - RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(node)->nd_lit = reg_compile(p, src, options)); + VALUE re = reg_compile(p, src, options); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_DREGX(node)->nd_lit = re); } if (options & RE_OPTION_ONCE) { node = NEW_ONCE(node, loc); diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index 6121205857a33b..acaeedcc2d8553 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -1071,6 +1071,7 @@ def test_named_capture_in_block '(%w();/(?.*)/)', '(1; (2; 3; (4; /(?.*)/)))', '(1+1; /(?.*)/)', + '/#{""}(?.*)/', ) do |code, pass| token = Random.bytes(4).unpack1("H*") if pass