diff --git a/spec/compiler/codegen/fun_spec.cr b/spec/compiler/codegen/fun_spec.cr
index 211bb86d21b2f199f5c0a9a5a29fa03fab70e6fc..e99eb72b7ee61216bb05cf9742eb1805d9e3e078 100644
--- a/spec/compiler/codegen/fun_spec.cr
+++ b/spec/compiler/codegen/fun_spec.cr
@@ -166,4 +166,17 @@ describe "Code gen: fun" do
       f.call(1 || 1.5).to_i
       ").to_i.should eq(1)
   end
+
+  it "allows fun pointer where self is a class" do
+    run("
+      class A
+        def self.bla
+          1
+        end
+      end
+
+      f = ->A.bla
+      f.call
+      ").to_i.should eq(1)
+  end
 end
diff --git a/src/compiler/crystal/codegen.cr b/src/compiler/crystal/codegen.cr
index 58132cfb0e4bcade5afd5523dda51cdafff73a86..92799b2e76a4b32997165598586acd99cc73e8b9 100644
--- a/src/compiler/crystal/codegen.cr
+++ b/src/compiler/crystal/codegen.cr
@@ -907,25 +907,49 @@ module Crystal
       last_fun = target_def_fun(node.call.target_def, owner)
       @last = last_fun.fun
 
+      is_metaclass = owner.metaclass?
+
       if call_self
-        wrapper = trampoline_wrapper(node.call.target_def, last_fun)
+        wrapper = trampoline_wrapper(node.call.target_def, last_fun, is_metaclass)
+
+        # In the case of a metaclass we set the closure context to be a pointer
+        # to the type id.
+        if is_metaclass
+          new_call_self = malloc llvm_type(owner)
+          store call_self, new_call_self
+          call_self = new_call_self
+        end
+
         trampoline_init node.type, wrapper.fun, call_self
       end
 
       false
     end
 
-    def trampoline_wrapper(target_def, target_fun)
+    def trampoline_wrapper(target_def, target_fun, is_metaclass)
       key = target_def.object_id
       wrappers = (@trampoline_wrappers ||= {} of typeof(object_id) => LLVM::Function)
       wrappers[key] ||= begin
         param_types = target_fun.param_types
         ret_type = target_fun.return_type
+
+        # In the case of a metaclass, we want the nest type to be i32*, not i32
+        if is_metaclass
+          param_types[0] = pointer_type(param_types[0])
+        end
+
         @llvm_mod.functions.add("trampoline_wrapper_#{key}", param_types, ret_type) do |func|
           func.linkage = LibLLVM::Linkage::Internal if @single_module
           LLVM.add_attribute func.get_param(0), LibLLVM::Attribute::Nest
           func.append_basic_block("entry") do |builder|
-            call_ret = builder.call target_fun, func.params
+            params = func.params
+
+            # In the case of a metaclass, we load the type id from the i32* parameter
+            if is_metaclass
+              params[0] = builder.load params[0]
+            end
+
+            call_ret = builder.call target_fun, params
             case target_def.type
             when .no_return?
               builder.unreachable