Skip to content

Commit

Permalink
give error if using instance_sizeof on a generic type without type va…
Browse files Browse the repository at this point in the history
…rs (#5209)
  • Loading branch information
lbguilherme authored and RX14 committed Nov 3, 2017
1 parent 7acedf8 commit 074d61c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
15 changes: 15 additions & 0 deletions spec/compiler/codegen/sizeof_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ describe "Code gen: sizeof" do
assert_error "instance_sizeof(Int32)", "Int32 is not a class, it's a struct"
end

it "gives error if using instance_sizeof on a generic type without type vars" do
assert_error "instance_sizeof(Array)", "can't calculate instance_sizeof of generic class"
end

it "gets instance_sizeof a generic type with type vars" do
run(%(
class Foo(T)
def initialize(@x : T)
end
end
instance_sizeof(Foo(Int32))
)).to_i.should eq(8)
end

it "gets sizeof Void" do
# Same as the size of a byte
run("sizeof(Void)").to_i.should eq(1)
Expand Down
18 changes: 16 additions & 2 deletions src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2456,10 +2456,15 @@ module Crystal
node.exp.accept self
@in_type_args -= 1

type = node.exp.type?
unless type
raise "BUG: #{node} at #{node.location} should receive a type"
end

# Try to resolve the sizeof right now to a number literal
# (useful for sizeof inside as a generic type argument, but also
# to make it easier for LLVM to optimize things)
if (type = node.exp.type?) && !node.exp.is_a?(TypeOf)
if !node.exp.is_a?(TypeOf)
expanded = NumberLiteral.new(@program.size_of(type.sizeof_type))
expanded.type = @program.int32
node.expanded = expanded
Expand All @@ -2473,10 +2478,19 @@ module Crystal
node.exp.accept self
@in_type_args -= 1

type = node.exp.type?
unless type
raise "BUG: #{node} at #{node.location} should receive a type"
end

if type.is_a? GenericType
node.raise "can't calculate instance_sizeof of generic class #{type} without specifying its type vars"
end

# Try to resolve the instance_sizeof right now to a number literal
# (useful for sizeof inside as a generic type argument, but also
# to make it easier for LLVM to optimize things)
if (type = node.exp.type?) && type.instance_type.devirtualize.class? && !node.exp.is_a?(TypeOf)
if type.instance_type.devirtualize.class? && !node.exp.is_a?(TypeOf)
expanded = NumberLiteral.new(@program.instance_size_of(type.sizeof_type))
expanded.type = @program.int32
node.expanded = expanded
Expand Down

0 comments on commit 074d61c

Please sign in to comment.