From 25dc6b119dd4daa7aff1310cb8bdec355d562bea Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Sat, 4 Sep 2021 17:44:15 +0800 Subject: [PATCH] Allow union types to be unbound --- spec/compiler/semantic/union_spec.cr | 27 +++++++++++++++++++++++++++ src/compiler/crystal/types.cr | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/spec/compiler/semantic/union_spec.cr b/spec/compiler/semantic/union_spec.cr index 61017e7997de..091447a0859d 100644 --- a/spec/compiler/semantic/union_spec.cr +++ b/spec/compiler/semantic/union_spec.cr @@ -314,4 +314,31 @@ describe "Semantic: union" do Union(Foo) )) { types["Foo"].metaclass } end + + it "doesn't run virtual lookup on unbound unions (#9173)" do + assert_type(%( + class Object + def foo + self + end + end + + abstract class Parent + end + + class Child(T) < Parent + @buffer = uninitialized T + + def bar + @buffer.foo + end + end + + class Foo(U) + @x = Child(U | Char).new + end + + Child(Int32).new.as(Parent).bar + )) { int32 } + end end diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr index 21a2e44b40f0..af822c790e24 100644 --- a/src/compiler/crystal/types.cr +++ b/src/compiler/crystal/types.cr @@ -3070,6 +3070,10 @@ module Crystal program.type_merge(new_union_types) || program.no_return end + def unbound? + union_types.any? &.unbound? + end + def all? union_types.all? { |union_type| yield union_type } end