diff --git a/spec/compiler/codegen/class_spec.cr b/spec/compiler/codegen/class_spec.cr index 61905f8ffbda8f382120bb1d726b2a9f921dffbe..d9db3201e68b03553d84cc5558f8a50a5d26858b 100755 --- a/spec/compiler/codegen/class_spec.cr +++ b/spec/compiler/codegen/class_spec.cr @@ -299,6 +299,21 @@ describe "Code gen: class" do )).to_i.should eq(1) end + it "reads a virtual type instance var" do + run(%( + class Foo + def initialize(@x) + end + end + + class Bar < Foo + end + + foo = Foo.new(1) || Bar.new(2) + foo.@x + )).to_i.should eq(1) + end + it "runs with nil instance var" do run(" struct Nil diff --git a/spec/compiler/type_inference/class_spec.cr b/spec/compiler/type_inference/class_spec.cr index e5f79d8aeda4447e46d8ae6e1c0744a1bac607fd..a4f5ed9e97cd555150c19b2a59f844f36eadba53 100755 --- a/spec/compiler/type_inference/class_spec.cr +++ b/spec/compiler/type_inference/class_spec.cr @@ -521,6 +521,21 @@ describe "Type inference: class" do )) { int32 } end + it "reads a virtual type instance var" do + assert_type(%( + class Foo + def initialize(@x) + end + end + + class Bar < Foo + end + + foo = Foo.new(1) || Bar.new(2) + foo.@x + )) { int32 } + end + it "errors if reading non-existent ivar" do assert_error %( class Foo diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr index e08c8855ff141758ce47edad3408dc5d852f4775..bc4abaead6838256d3b2dcf35ce3f62a0356d541 100644 --- a/src/compiler/crystal/types.cr +++ b/src/compiler/crystal/types.cr @@ -2817,6 +2817,10 @@ module Crystal base_type.lookup_instance_var(name, create) end + def lookup_instance_var?(name, create = false) + base_type.lookup_instance_var?(name, create) + end + def index_of_instance_var(name) base_type.index_of_instance_var(name) end @@ -2845,6 +2849,10 @@ module Crystal base_type.all_instance_vars end + def owned_instance_vars + base_type.owned_instance_vars + end + def abstract base_type.abstract end