diff --git a/spec/compiler/interpreter/types_spec.cr b/spec/compiler/interpreter/types_spec.cr index 084264c61d99..385de7ce0258 100644 --- a/spec/compiler/interpreter/types_spec.cr +++ b/spec/compiler/interpreter/types_spec.cr @@ -87,6 +87,19 @@ describe Crystal::Repl::Interpreter do repl_value.value.should eq(context.type_id(context.program.int32)) end + it "interprets crystal_type_id for virtual metaclass type (#12228)" do + interpret(<<-CODE).should eq(true) + class P + end + + class A < P + end + + p = A.as(P.class) + p.crystal_type_id == A.crystal_type_id + CODE + end + it "interprets class_crystal_instance_type_id" do interpret(<<-CODE, prelude: "prelude").should eq("true") class Foo diff --git a/src/compiler/crystal/interpreter/primitives.cr b/src/compiler/crystal/interpreter/primitives.cr index b30a6db9ec73..28ab79e2d4e4 100644 --- a/src/compiler/crystal/interpreter/primitives.cr +++ b/src/compiler/crystal/interpreter/primitives.cr @@ -102,17 +102,24 @@ class Crystal::Repl::Compiler put_type type, node: node end when "object_crystal_type_id" - type = + type = obj.try(&.type) || scope + + unless @wants_value + discard_value obj if obj + return + end + + if type.is_a?(VirtualMetaclassType) + # For a virtual metaclass type, the value is already an int + # that's exactly the crystal_type_id, so there's nothing else to do. if obj - discard_value(obj) - obj.type + obj.accept self else - scope + put_self node: node end - - return unless @wants_value - - put_i32 type_id(type), node: node + else + put_i32 type_id(type), node: node + end when "class_crystal_instance_type_id" type = if obj