Skip to content

Commit

Permalink
Showing 2 changed files with 26 additions and 3 deletions.
19 changes: 19 additions & 0 deletions spec/compiler/codegen/struct_spec.cr
Original file line number Diff line number Diff line change
@@ -606,4 +606,23 @@ describe "Code gen: struct" do
x.as(Bar).foo
)).to_i.should eq(1)
end

it "casts virtual struct to base type, only one subclass (#2885)" do
run(%(
abstract struct Entry
def initialize(@uid : String, @country : String)
end
def uid
@uid
end
end
struct MyEntry < Entry
end
entry = MyEntry.new("1", "GER")
entry.as(Entry).uid
)).to_string.should eq("1")
end
end
10 changes: 7 additions & 3 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
@@ -1956,9 +1956,13 @@ module Crystal

if type.is_a?(VirtualType)
if type.struct?
# For a struct we need to cast the second part of the union to the base type
value_ptr = gep(pointer, 0, 1)
pointer = bit_cast value_ptr, llvm_type(type.base_type).pointer
if type.remove_indirection.is_a?(UnionType)
# For a struct we need to cast the second part of the union to the base type
value_ptr = gep(pointer, 0, 1)
pointer = bit_cast value_ptr, llvm_type(type.base_type).pointer
else
# Nothing, there's only one subclass so it's the struct already
end
else
pointer = cast_to pointer, type.base_type
end

0 comments on commit e0f83fd

Please sign in to comment.