diff --git a/spec/compiler/semantic/class_spec.cr b/spec/compiler/semantic/class_spec.cr index eb16a2d1f188..babf78f343e9 100644 --- a/spec/compiler/semantic/class_spec.cr +++ b/spec/compiler/semantic/class_spec.cr @@ -1075,4 +1075,20 @@ describe "Semantic: class" do { {{ Foo::Bar.superclass }}, {{ Foo::Baz.superclass }} } )) { tuple_of [types["Foo"].metaclass, types["Foo"].metaclass] } end + + it "errors if reading instance var of union type (#7187)" do + assert_error %( + class Foo + @x = 1 + end + + class Bar + @x = 1 + end + + z = Foo.new || Bar.new + z.@x + ), + "can't read instance variables of union types (@x of (Bar | Foo))" + end end diff --git a/src/compiler/crystal/semantic/bindings.cr b/src/compiler/crystal/semantic/bindings.cr index 606198430de2..6a3dbf2bd50c 100644 --- a/src/compiler/crystal/semantic/bindings.cr +++ b/src/compiler/crystal/semantic/bindings.cr @@ -557,6 +557,10 @@ module Crystal obj_type = obj.type? return unless obj_type + if obj_type.is_a?(UnionType) + raise "can't read instance variables of union types (#{name} of #{obj_type})" + end + var = visitor.lookup_instance_var(self, obj_type) self.type = var.type end