Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give proper error when doing sizeof uninstantiated generic type #6418

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions spec/compiler/codegen/sizeof_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,6 @@ describe "Code gen: sizeof" do
").to_i.should eq(16)
end

it "gives error if using instance_sizeof on something that's not a class" 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)
Expand Down
16 changes: 0 additions & 16 deletions spec/compiler/semantic/primitives_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,6 @@ describe "Semantic: primitives" do
assert_type("1 + 2") { int32 }
end

it "types sizeof" do
assert_type("sizeof(Float64)") { int32 }
end

it "types sizeof NoReturn (missing type) (#5717)" do
assert_type("x = nil; x ? sizeof(typeof(x)) : 1") { int32 }
end

it "types instance_sizeof" do
assert_type("instance_sizeof(Reference)") { int32 }
end

it "types instance_sizeof NoReturn (missing type) (#5717)" do
assert_type("x = nil; x ? instance_sizeof(typeof(x)) : 1") { int32 }
end

it "errors when comparing void (#225)" do
assert_error %(
lib LibFoo
Expand Down
31 changes: 31 additions & 0 deletions spec/compiler/semantic/sizeof_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require "../../spec_helper"

describe "Semantic: sizeof" do
it "types sizeof" do
assert_type("sizeof(Float64)") { int32 }
end

it "types sizeof NoReturn (missing type) (#5717)" do
assert_type("x = nil; x ? sizeof(typeof(x)) : 1") { int32 }
end

it "types instance_sizeof" do
assert_type("instance_sizeof(Reference)") { int32 }
end

it "types instance_sizeof NoReturn (missing type) (#5717)" do
assert_type("x = nil; x ? instance_sizeof(typeof(x)) : 1") { int32 }
end

it "errors on sizeof uninstantiated generic type (#6415)" do
assert_error "sizeof(Array)", "can't take sizeof uninstantiated generic type Array(T)"
end

it "gives error if using instance_sizeof on something that's not a class" 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 take instance_sizeof uninstantiated generic type Array(T)"
end
end
8 changes: 6 additions & 2 deletions src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2552,6 +2552,10 @@ module Crystal

type = node.exp.type?

if type.is_a?(GenericType)
node.exp.raise "can't take sizeof uninstantiated generic type #{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)
Expand All @@ -2573,8 +2577,8 @@ module Crystal

type = node.exp.type?

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

# Try to resolve the instance_sizeof right now to a number literal
Expand Down