Skip to content

Commit

Permalink
Showing 4 changed files with 70 additions and 0 deletions.
31 changes: 31 additions & 0 deletions spec/compiler/codegen/class_spec.cr
Original file line number Diff line number Diff line change
@@ -855,4 +855,35 @@ describe "Code gen: class" do
end
))
end

it "can assign virtual metaclass to virtual metaclass (#3007)" do
run(%(
class Foo
def self.foo
1
end
end
class Bar < Foo
def self.foo
2
end
end
class Baz < Bar
def self.foo
3
end
end
class Gen(T)
def initialize(x : T)
end
end
ptr = Pointer(Foo.class).malloc(1_u64)
ptr.value = Bar || Baz
ptr.value.foo
)).to_i.should eq(2)
end
end
31 changes: 31 additions & 0 deletions spec/compiler/type_inference/generic_class_spec.cr
Original file line number Diff line number Diff line change
@@ -796,4 +796,35 @@ describe "Type inference: generic class" do
Foo(Int32, Float64, Char).new.t
)) { tuple_of([int32.metaclass, tuple_of([float64]).metaclass, char.metaclass]) }
end

it "virtual metaclass type implements super virtual metaclass type (#3007)" do
assert_type(%(
class Base
end
class Child < Base
end
class Child1 < Child
end
class Gen(T)
class Entry(T)
def initialize(@x : T)
end
def foo
1
end
end
def foo(x)
Entry(T).new(x).foo
end
end
gen = Gen(Base.class).new
gen.foo(Child || Child1)
)) { int32 }
end
end
4 changes: 4 additions & 0 deletions src/compiler/crystal/codegen/cast.cr
Original file line number Diff line number Diff line change
@@ -206,6 +206,10 @@ class Crystal::CodeGenVisitor
store value, target_pointer
end

def assign_distinct(target_pointer, target_type : VirtualMetaclassType, value_type : VirtualMetaclassType, value)
store value, target_pointer
end

def assign_distinct(target_pointer, target_type : NilableProcType, value_type : NilType, value)
nilable_fun = make_nilable_fun target_type
store nilable_fun, target_pointer
4 changes: 4 additions & 0 deletions src/compiler/crystal/types.cr
Original file line number Diff line number Diff line change
@@ -3176,6 +3176,10 @@ module Crystal
nil
end

def implements?(other : VirtualMetaclassType)
base_type.implements?(other.base_type)
end

def to_s_with_options(io : IO, skip_union_parens : Bool = false, generic_args : Bool = true, codegen = false)
instance_type.to_s_with_options(io, codegen: codegen)
io << ":Class"

0 comments on commit 9dfa448

Please sign in to comment.