diff --git a/spec/compiler/codegen/fun_spec.cr b/spec/compiler/codegen/fun_spec.cr
index 7879c04cd18b22b8c8d7bb2b68af631f09756899..4fe078742a1cb8ec4e3414b7cf1c85b9c036f52c 100644
--- a/spec/compiler/codegen/fun_spec.cr
+++ b/spec/compiler/codegen/fun_spec.cr
@@ -485,4 +485,22 @@ describe "Code gen: fun" do
       foo.call(a).to_i
       )).to_i.should eq(1)
   end
+
+  it "codegens issue with missing byval in fun literal inside struct" do
+    run(%(
+      require "prelude"
+
+      struct Params
+        def foo
+          params = [] of {String}
+          params << {"foo"}
+          params << {"bar"}
+          params.sort! { |x, y| x[0] <=> y[0] }
+          params[0][0]
+        end
+      end
+
+      Params.new.foo
+      )).to_string.should eq("bar")
+  end
 end
diff --git a/src/compiler/crystal/codegen/fun.cr b/src/compiler/crystal/codegen/fun.cr
index 02f66af7160fc4741c1e79ce13d2690da8511a1a..ceff74a52d349954bd170b8d179572c0b42fad97 100644
--- a/src/compiler/crystal/codegen/fun.cr
+++ b/src/compiler/crystal/codegen/fun.cr
@@ -180,8 +180,10 @@ class Crystal::CodeGenVisitor < Crystal::Visitor
 
       # Set 'byval' attribute
       # but don't set it if it's the "self" argument and it's a struct (while not in a closure).
-      if arg.type.passed_by_value? && (is_closure || !(i == 0 && self_type.struct?))
-        param.add_attribute LibLLVM::Attribute::ByVal
+      if arg.type.passed_by_value?
+        if (is_fun_literal && !is_closure) || (is_closure || !(i == 0 && self_type.struct?))
+          param.add_attribute LibLLVM::Attribute::ByVal
+        end
       end
     end