From 2698c43d0be6ef99f4a9e6dd252767edce807621 Mon Sep 17 00:00:00 2001
From: Quinton Miller <nicetas.c@gmail.com>
Date: Mon, 15 Mar 2021 22:41:14 +0800
Subject: [PATCH] Don't merge NamedTuple metaclasses through instance types
 (#10501)

---
 spec/compiler/semantic/named_tuple_spec.cr  | 11 +++++++++++
 src/compiler/crystal/semantic/type_merge.cr |  3 +++
 2 files changed, 14 insertions(+)

diff --git a/spec/compiler/semantic/named_tuple_spec.cr b/spec/compiler/semantic/named_tuple_spec.cr
index f45f19cfbbce..acad0c61b832 100644
--- a/spec/compiler/semantic/named_tuple_spec.cr
+++ b/spec/compiler/semantic/named_tuple_spec.cr
@@ -332,4 +332,15 @@ describe "Semantic: named tuples" do
       call("")
       )) { int32 }
   end
+
+  it "doesn't unify named tuple metaclasses (#5384)" do
+    assert_type(%(
+      NamedTuple(a: Int32) || NamedTuple(a: String)
+      )) {
+      union_of(
+        named_tuple_of({"a": int32}).metaclass,
+        named_tuple_of({"a": string}).metaclass,
+      )
+    }
+  end
 end
diff --git a/src/compiler/crystal/semantic/type_merge.cr b/src/compiler/crystal/semantic/type_merge.cr
index 761653e272ca..bd9f034e9d85 100644
--- a/src/compiler/crystal/semantic/type_merge.cr
+++ b/src/compiler/crystal/semantic/type_merge.cr
@@ -249,6 +249,9 @@ module Crystal
       # Tuple instances might be unified, but never tuple metaclasses
       return nil if instance_type.is_a?(TupleInstanceType) || other.instance_type.is_a?(TupleInstanceType)
 
+      # NamedTuple instances might be unified, but never named tuple metaclasses
+      return nil if instance_type.is_a?(NamedTupleInstanceType) || other.instance_type.is_a?(NamedTupleInstanceType)
+
       common = instance_type.common_ancestor(other.instance_type)
       common.try &.metaclass
     end