diff --git a/spec/compiler/codegen/is_a_spec.cr b/spec/compiler/codegen/is_a_spec.cr index cf78d6119863..e2e9deb89605 100644 --- a/spec/compiler/codegen/is_a_spec.cr +++ b/spec/compiler/codegen/is_a_spec.cr @@ -905,4 +905,21 @@ describe "Codegen: is_a?" do end )).to_i.should eq(2) end + + it "does is_a? for generic type against generic class instance type (#12304)" do + run(%( + require "prelude" + + class A + end + + class B(T) < A + end + + a = B(Int32).new.as(A) + b = a.as(B) + + b.is_a?(B(Int32)) + )).to_b.should be_true + end end diff --git a/src/compiler/crystal/semantic/type_intersect.cr b/src/compiler/crystal/semantic/type_intersect.cr index 8e533bd29b44..500c214a2cfb 100644 --- a/src/compiler/crystal/semantic/type_intersect.cr +++ b/src/compiler/crystal/semantic/type_intersect.cr @@ -72,6 +72,10 @@ module Crystal common_descendent_instance_and_generic(type1, type2) end + def self.common_descendent(type1 : GenericClassType, type2 : GenericClassInstanceType) + common_descendent(type2, type1) + end + def self.common_descendent(type1 : GenericInstanceType, type2 : GenericInstanceType) common_descendent_generic_instances(type1, type2) || common_descendent_base(type1, type2)