diff --git a/spec/compiler/codegen/fun_spec.cr b/spec/compiler/codegen/fun_spec.cr index b2be16818e64bf62e84cf410464eb1ffee709ba9..adcd3a346621f599a8dd54bb403e4d5cf4be8eab 100644 --- a/spec/compiler/codegen/fun_spec.cr +++ b/spec/compiler/codegen/fun_spec.cr @@ -375,4 +375,17 @@ describe "Code gen: fun" do f.call(1).to_i ").to_i.should eq(1) end + + it "does closure? false" do + run(" + ->{ 1 }.closure? + ").to_b.should be_false + end + + it "does closure? false" do + run(" + a = 1 + ->{ a }.closure? + ").to_b.should be_true + end end diff --git a/spec/compiler/type_inference/fun_spec.cr b/spec/compiler/type_inference/fun_spec.cr index fcfec2e0042e7026f7d8dd8684ba596d804cc535..5b8eddcf0c10c7775054f8a51f1ff4f84c37ceda 100644 --- a/spec/compiler/type_inference/fun_spec.cr +++ b/spec/compiler/type_inference/fun_spec.cr @@ -225,10 +225,6 @@ describe "Type inference: fun" do "can't cast (Int32 -> Float64) to (Float64 -> Float64)" end - it "inherits Reference" do - assert_type("->{}.object_id") { uint64 } - end - it "types fun literal hard type inference (1)" do assert_type(%( require "prelude" diff --git a/src/compiler/crystal/codegen/primtiives.cr b/src/compiler/crystal/codegen/primtiives.cr index 04bf7d4fe261bb1f6e52fc1d4dc0fde026b4617c..8261d4db80ed49100cda992bf05f893039917580 100644 --- a/src/compiler/crystal/codegen/primtiives.cr +++ b/src/compiler/crystal/codegen/primtiives.cr @@ -68,6 +68,8 @@ class Crystal::CodeGenVisitor < Crystal::Visitor codegen_primitive_class node, target_def, call_args when :fun_call codegen_primitive_fun_call node, target_def, call_args + when :fun_closure? + codegen_primitive_fun_closure node, target_def, call_args when :pointer_diff codegen_primitive_pointer_diff node, target_def, call_args when :pointer_null @@ -467,6 +469,12 @@ class Crystal::CodeGenVisitor < Crystal::Visitor end end + def codegen_primitive_fun_closure(node, target_def, call_args) + closure_ptr = call_args[0] + ctx_ptr = @builder.extract_value closure_ptr, 1 + not_equal? ctx_ptr, LLVM.null(LLVM::VoidPointer) + end + def codegen_primitive_pointer_diff(node, target_def, call_args) p0 = ptr2int(call_args[0], LLVM::Int64) p1 = ptr2int(call_args[1], LLVM::Int64) diff --git a/src/compiler/crystal/type_inference.cr b/src/compiler/crystal/type_inference.cr index 0fde8917f3329852bdc7dbe3712ab2621dc1630f..69669f77773958f72cd5649959b9c6dfe4ad98ee 100644 --- a/src/compiler/crystal/type_inference.cr +++ b/src/compiler/crystal/type_inference.cr @@ -1565,7 +1565,7 @@ module Crystal node.type = mod.string when :class node.type = scope.metaclass - when :fun_call + when :fun_call, :fun_closure? # Nothing to do when :pointer_diff node.type = mod.int64 diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr index 98989364e27f0acc0e9b62c977c3a7dc9db627b6..dfa692cf7a7d699ef938b20138ae0a2f5bcb8e8c 100644 --- a/src/compiler/crystal/types.cr +++ b/src/compiler/crystal/types.cr @@ -2911,6 +2911,8 @@ module Crystal args = arg_types.map_with_index { |type, i| Arg.new_with_type("arg#{i}", type) } add_def Def.new("call", args, Primitive.new(:fun_call, return_type)) add_def Def.new("arity", [] of Arg, NumberLiteral.new(fun_types.length - 1, :i32)) + add_def Def.new("closure?", [] of Arg, Primitive.new(:fun_closure?, @program.bool)) + add_def Def.new("to_s", [] of Arg, StringLiteral.new(to_s)) end def arg_types @@ -2922,7 +2924,7 @@ module Crystal end def parents - @parents ||= [@program.reference] of Type + @parents ||= [@program.value] of Type end def primitive_like?