diff --git a/spec/compiler/semantic/static_array_spec.cr b/spec/compiler/semantic/static_array_spec.cr index cd2db6e88159..0112584753c7 100644 --- a/spec/compiler/semantic/static_array_spec.cr +++ b/spec/compiler/semantic/static_array_spec.cr @@ -155,4 +155,28 @@ describe "Semantic: static array" do ), "expected argument #1 to 'fn' to be StaticArray(Int32, 11), not StaticArray(Int32, 10)" end + + it "doesn't crash on sizeof (#8858)" do + assert_error %( + alias BadArray = Int32[sizeof(Int32)] + ), + "can't use sizeof(Int32) as a generic type argument" + end + + it "doesn't crash on instance_sizeof (#8858)" do + assert_error %( + alias BadArray = Int32[instance_sizeof(String)] + ), + "can't use instance_sizeof(String) as a generic type argument" + end + + it "doesn't crash on offsetof (#8858)" do + assert_error %( + class Foo + @foo : Int32 = 0 + end + alias BadArray = Int32[offsetof(Foo, @foo)] + ), + "can't use offsetof(Foo, @foo) as a generic type argument" + end end diff --git a/src/compiler/crystal/semantic/type_lookup.cr b/src/compiler/crystal/semantic/type_lookup.cr index 7a98450cc72b..64c3b319cf6e 100644 --- a/src/compiler/crystal/semantic/type_lookup.cr +++ b/src/compiler/crystal/semantic/type_lookup.cr @@ -247,6 +247,10 @@ class Crystal::Type type_var.raise "can only splat tuple type, not #{splat_type}" end next + when SizeOf, InstanceSizeOf, OffsetOf + next unless @raise + + type_var.raise "can't use #{type_var} as a generic type argument" end # Check the case of T resolving to a number diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr index adcbcabeece5..e554f500b738 100644 --- a/src/compiler/crystal/syntax/parser.cr +++ b/src/compiler/crystal/syntax/parser.cr @@ -5771,6 +5771,7 @@ module Crystal end def parse_sizeof(klass) + sizeof_location = @token.location next_token_skip_space check :OP_LPAREN @@ -5785,10 +5786,11 @@ module Crystal check :OP_RPAREN next_token_skip_space - klass.new(exp).at_end(end_location) + klass.new(exp).at(sizeof_location).at_end(end_location) end def parse_offsetof + offsetof_location = @token.location next_token_skip_space check :OP_LPAREN @@ -5817,7 +5819,7 @@ module Crystal check :OP_RPAREN next_token_skip_space - OffsetOf.new(type, offset).at_end(end_location) + OffsetOf.new(type, offset).at(offsetof_location).at_end(end_location) end def parse_type_def