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