Commit fb2acaff06

Andrew Kelley <andrew@ziglang.org>
2019-04-25 04:31:53
`@sizeOf` returns 0 for comptime types
This defines `@sizeOf` to be the runtime size of a type, which means that it is zero for types such as comptime_int, type, and (enum literal). See #2209
1 parent 733c547
Changed files (4)
doc/langref.html.in
@@ -7275,6 +7275,10 @@ test "@setRuntimeSafety" {
       consider whether you want to use {#syntax#}@sizeOf(T){#endsyntax#} or
       {#syntax#}@typeInfo(T).Int.bits{#endsyntax#}.
       </p>
+      <p>
+      This function measures the size at runtime. For types that are disallowed at runtime, such as
+      {#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}.
+      </p>
       {#see_also|@typeInfo#}
       {#header_close#}
 
src/ir.cpp
@@ -16729,16 +16729,16 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
         case ZigTypeIdUnreachable:
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
-        case ZigTypeIdComptimeFloat:
-        case ZigTypeIdComptimeInt:
-        case ZigTypeIdEnumLiteral:
         case ZigTypeIdBoundFn:
-        case ZigTypeIdMetaType:
         case ZigTypeIdArgTuple:
         case ZigTypeIdOpaque:
-            ir_add_error_node(ira, size_of_instruction->base.source_node,
+            ir_add_error_node(ira, type_value->source_node,
                     buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
             return ira->codegen->invalid_instruction;
+        case ZigTypeIdMetaType:
+        case ZigTypeIdEnumLiteral:
+        case ZigTypeIdComptimeFloat:
+        case ZigTypeIdComptimeInt:
         case ZigTypeIdVoid:
         case ZigTypeIdBool:
         case ZigTypeIdInt:
test/stage1/behavior/sizeof_and_typeof.zig
@@ -67,3 +67,10 @@ test "@bitOffsetOf" {
     expect(@byteOffsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
     expect(@byteOffsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
 }
+
+test "@sizeOf on compile-time types" {
+    expect(@sizeOf(comptime_int) == 0);
+    expect(@sizeOf(comptime_float) == 0);
+    expect(@sizeOf(@typeOf(.hi)) == 0);
+    expect(@sizeOf(@typeOf(type)) == 0);
+}
test/compile_errors.zig
@@ -2,6 +2,15 @@ const tests = @import("tests.zig");
 const builtin = @import("builtin");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add(
+        "@sizeOf bad type",
+        \\export fn entry() void {
+        \\    _ = @sizeOf(@typeOf(null));
+        \\}
+    ,
+        "tmp.zig:2:17: error: no size available for type '(null)'",
+    );
+
     cases.add(
         "Generic function where return type is self-referenced",
         \\fn Foo(comptime T: type) Foo(T) {