diff --git a/spec/compiler/codegen/closure_spec.cr b/spec/compiler/codegen/closure_spec.cr index 1068c35a470c88219e4a1ce1c8df0153266749ef..f6de8a59547dfabbfb06e1d0a07981d9ee066041 100644 --- a/spec/compiler/codegen/closure_spec.cr +++ b/spec/compiler/codegen/closure_spec.cr @@ -575,4 +575,19 @@ describe "Code gen: closure" do a )).to_i.should eq(3) end + + it "closures struct self" do + run(%( + struct Foo + def initialize(@x) + end + + def foo + ->{ @x } + end + end + + Foo.new(1).foo.call + )).to_i.should eq(1) + end end diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr index c0f30c72e2326becbd70a6e95149b045053b8ccc..ff8933562a4dd1485f8603686c0d0d13cc18d0bd 100644 --- a/src/compiler/crystal/codegen/codegen.cr +++ b/src/compiler/crystal/codegen/codegen.cr @@ -1750,7 +1750,11 @@ module Crystal if self_closured offset = parent_closure_type ? 1 : 0 - store llvm_self, gep(closure_ptr, 0, closure_vars.length + offset, "self") + self_value = llvm_self + self_value = load self_value if current_context.type.passed_by_value? + + store self_value, gep(closure_ptr, 0, closure_vars.length + offset, "self") + current_context.closure_self = current_context.type end elsif parent_context && parent_context.closure_type diff --git a/src/compiler/crystal/codegen/fun.cr b/src/compiler/crystal/codegen/fun.cr index c262bd2fba6912816612b0fa338661a944ec1c9c..8541d9d37017392eb85e8dcdc16f72045de22b0e 100644 --- a/src/compiler/crystal/codegen/fun.cr +++ b/src/compiler/crystal/codegen/fun.cr @@ -218,7 +218,9 @@ class Crystal::CodeGenVisitor < Crystal::Visitor setup_closure_vars(parent_vars, closure_parent_context, load(parent_closure_ptr, "parent")) elsif closure_self = context.closure_self offset = context.closure_parent_context ? 1 : 0 - self.context.vars["self"] = LLVMVar.new(load(gep(closure_ptr, 0, closure_vars.length + offset, "self")), closure_self, true) + self_value = gep(closure_ptr, 0, closure_vars.length + offset, "self") + self_value = load(self_value) unless context.type.passed_by_value? + self.context.vars["self"] = LLVMVar.new(self_value, closure_self, true) end end end