diff --git a/spec/compiler/interpreter/blocks_spec.cr b/spec/compiler/interpreter/blocks_spec.cr index c91e73e16a63..3d598ef09230 100644 --- a/spec/compiler/interpreter/blocks_spec.cr +++ b/spec/compiler/interpreter/blocks_spec.cr @@ -599,5 +599,23 @@ describe Crystal::Repl::Interpreter do end CODE end + + it "caches method with captured block (#12276)" do + interpret(<<-CODE).should eq(42) + def execute(x, &block : -> Int32) + if x + execute(false) do + block.call + end + else + yield + end + end + + execute(true) do + 42 + end + CODE + end end end diff --git a/src/compiler/crystal/interpreter/compiler.cr b/src/compiler/crystal/interpreter/compiler.cr index 90cd90faf5ce..7941a589c71c 100644 --- a/src/compiler/crystal/interpreter/compiler.cr +++ b/src/compiler/crystal/interpreter/compiler.cr @@ -1992,7 +1992,7 @@ class Crystal::Repl::Compiler < Crystal::Visitor compiled_def = CompiledDef.new(@context, target_def, owner, args_bytesize) # We don't cache defs that yield because we inline the block's contents - if block + if block && !block.fun_literal @context.add_gc_reference(compiled_def) else @context.defs[target_def] = compiled_def