diff --git a/prism_compile.c b/prism_compile.c index e655688401..63893c5184 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -9640,7 +9640,19 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // -> { it } // ^^ if (!popped) { - PUSH_GETLOCAL(ret, location, scope_node->local_table_for_iseq_size, 0); + pm_scope_node_t *current_scope_node = scope_node; + int level = 0; + + while (current_scope_node) { + if (current_scope_node->parameters && PM_NODE_TYPE_P(current_scope_node->parameters, PM_IT_PARAMETERS_NODE)) { + PUSH_GETLOCAL(ret, location, current_scope_node->local_table_for_iseq_size, level); + return; + } + + current_scope_node = current_scope_node->previous; + level++; + } + rb_bug("Local `it` does not exist"); } return; diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 62f1d99bdc..f24929092b 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -1946,6 +1946,14 @@ eom end assert_valid_syntax('proc {def foo(_);end;it}') assert_syntax_error('p { [it **2] }', /unexpected \*\*/) + assert_equal(1, eval('1.then { raise rescue it }')) + assert_equal(2, eval('1.then { 2.then { raise rescue it } }')) + assert_equal(3, eval('3.then { begin; raise; rescue; it; end }')) + assert_equal(4, eval('4.tap { begin; raise ; rescue; raise rescue it; end; }')) + assert_equal(5, eval('a = 0; 5.then { begin; nil; ensure; a = it; end }; a')) + assert_equal(6, eval('a = 0; 6.then { begin; nil; rescue; ensure; a = it; end }; a')) + assert_equal(7, eval('a = 0; 7.then { begin; raise; ensure; a = it; end } rescue a')) + assert_equal(8, eval('a = 0; 8.then { begin; raise; rescue; ensure; a = it; end }; a')) end def test_value_expr_in_condition