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