diff --git a/spec/compiler/codegen/is_a_spec.cr b/spec/compiler/codegen/is_a_spec.cr index 2aaa8abf04e003f0641f9279afbfb9bdca79e0e1..a250b1d9332d636e20ffc5d8d05a9dbca860cfda 100644 --- a/spec/compiler/codegen/is_a_spec.cr +++ b/spec/compiler/codegen/is_a_spec.cr @@ -249,7 +249,7 @@ describe "Codegen: is_a?" do ").to_i.should eq(2) end - pending "restricts union with union" do + it "restricts union with union" do run(" class Char def +(other : Int32) diff --git a/src/compiler/crystal/parser.cr b/src/compiler/crystal/parser.cr index ec526628a37316494c618d29f8bb74afe3960c74..256d27995ffae118dcf32d6b8bf086d1fd0042fc 100644 --- a/src/compiler/crystal/parser.cr +++ b/src/compiler/crystal/parser.cr @@ -556,17 +556,6 @@ module Crystal raise "'ptr' can't receive a block" end atomic = PointerOf.new(atomic_obj) - when "is_a?" - if atomic.args.length != 1 - raise "wrong number of arguments for 'is_a?' (#{atomic.args.length} for 1)" - end - if !atomic.args[0].is_a?(Ident) - raise "'is_a?' argument must be a Constant" - end - if atomic.block - raise "'is_a?' can't receive a block" - end - atomic = IsA.new(atomic_obj, atomic.args[0]) when "responds_to?" if atomic.args.length != 1 raise "wrong number of arguments for 'responds_to?' (#{atomic.args.length} for 1)" diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr index ceaa0026226e2deeecb03495a58584bda021a648..77a670f34e4d8a3fec609674b6f634e51323d826 100644 --- a/src/compiler/crystal/types.cr +++ b/src/compiler/crystal/types.cr @@ -154,8 +154,15 @@ module Crystal raise "Bug: #{self} doesn't implement allocated=" end - def implements?(other_type) - self == other_type + def implements?(other_type : Type) + case other_type + when UnionType + other_type.union_types.any? do |union_type| + implements?(union_type) + end + else + self == other_type + end end def is_subclass_of?(type)