Commit feb4b01b38

Andrew Kelley <andrew@ziglang.org>
2022-02-18 03:33:19
Sema: fix typeinfo for sentinels of array and pointer
1 parent b837855
Changed files (3)
src/Sema.zig
@@ -9640,9 +9640,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
             // alignment: comptime_int,
             field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target));
             // is_generic: bool,
-            field_values[2] = if (info.is_generic) Value.@"true" else Value.@"false";
+            field_values[2] = Value.makeBool(info.is_generic);
             // is_var_args: bool,
-            field_values[3] = if (info.is_var_args) Value.@"true" else Value.@"false";
+            field_values[3] = Value.makeBool(info.is_var_args);
             // return_type: ?type,
             field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());
             // args: []const FnArg,
@@ -9699,9 +9699,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
             // size: Size,
             field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.size));
             // is_const: bool,
-            field_values[1] = if (!info.mutable) Value.@"true" else Value.@"false";
+            field_values[1] = Value.makeBool(!info.mutable);
             // is_volatile: bool,
-            field_values[2] = if (info.@"volatile") Value.@"true" else Value.@"false";
+            field_values[2] = Value.makeBool(info.@"volatile");
             // alignment: comptime_int,
             field_values[3] = try Value.Tag.int_u64.create(sema.arena, alignment);
             // address_space: AddressSpace
@@ -9709,9 +9709,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
             // child: type,
             field_values[5] = try Value.Tag.ty.create(sema.arena, info.pointee_type);
             // is_allowzero: bool,
-            field_values[6] = if (info.@"allowzero") Value.@"true" else Value.@"false";
-            // sentinel: anytype,
-            field_values[7] = if (info.sentinel) |some| try Value.Tag.opt_payload.create(sema.arena, some) else Value.@"null";
+            field_values[6] = Value.makeBool(info.@"allowzero");
+            // sentinel: ?*const anyopaque,
+            field_values[7] = try sema.optRefValue(block, src, info.pointee_type, info.sentinel);
 
             return sema.addConstant(
                 type_info_ty,
@@ -9728,8 +9728,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
             field_values[0] = try Value.Tag.int_u64.create(sema.arena, info.len);
             // child: type,
             field_values[1] = try Value.Tag.ty.create(sema.arena, info.elem_type);
-            // sentinel: anytype,
-            field_values[2] = if (info.sentinel) |some| try Value.Tag.opt_payload.create(sema.arena, some) else Value.@"null";
+            // sentinel: ?*const anyopaque,
+            field_values[2] = try sema.optRefValue(block, src, info.elem_type, info.sentinel);
 
             return sema.addConstant(
                 type_info_ty,
@@ -9788,7 +9788,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
             var int_tag_type_buffer: Type.Payload.Bits = undefined;
             const int_tag_ty = try ty.intTagType(&int_tag_type_buffer).copy(sema.arena);
 
-            const is_exhaustive = if (ty.isNonexhaustiveEnum()) Value.@"false" else Value.@"true";
+            const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum());
 
             var fields_anon_decl = try block.startAnonDecl(src);
             defer fields_anon_decl.deinit();
@@ -10050,14 +10050,12 @@ fn typeInfoDecls(
             break :v try Value.Tag.decl_ref.create(decls_anon_decl.arena(), new_decl);
         };
 
-        const is_pub = if (decl.is_pub) Value.@"true" else Value.@"false";
-
         const fields = try decls_anon_decl.arena().create([2]Value);
         fields.* = .{
             //name: []const u8,
             name_val,
             //is_pub: bool,
-            is_pub,
+            Value.makeBool(decl.is_pub),
         };
         decls_val.* = try Value.Tag.@"struct".create(decls_anon_decl.arena(), fields);
     }
@@ -15660,6 +15658,24 @@ fn ensureDeclAnalyzed(sema: *Sema, decl: *Decl) CompileError!void {
     };
 }
 
+fn refValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, val: Value) !Value {
+    var anon_decl = try block.startAnonDecl(src);
+    defer anon_decl.deinit();
+    const decl = try anon_decl.finish(
+        try ty.copy(anon_decl.arena()),
+        try val.copy(anon_decl.arena()),
+    );
+    try sema.mod.declareDeclDependency(sema.owner_decl, decl);
+    return try Value.Tag.decl_ref.create(sema.arena, decl);
+}
+
+fn optRefValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, opt_val: ?Value) !Value {
+    const val = opt_val orelse return Value.@"null";
+    const ptr_val = try refValue(sema, block, src, ty, val);
+    const result = try Value.Tag.opt_payload.create(sema.arena, ptr_val);
+    return result;
+}
+
 fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
     try sema.mod.declareDeclDependency(sema.owner_decl, decl);
     try sema.ensureDeclAnalyzed(decl);
src/value.zig
@@ -3971,6 +3971,10 @@ pub const Value = extern union {
     pub const @"null" = initTag(.null_value);
     pub const @"false" = initTag(.bool_false);
     pub const @"true" = initTag(.bool_true);
+
+    pub fn makeBool(x: bool) Value {
+        return if (x) Value.@"true" else Value.@"false";
+    }
 };
 
 var negative_one_payload: Value.Payload.I64 = .{
test/behavior/type_info.zig
@@ -103,8 +103,6 @@ fn testUnknownLenPtr() !void {
 }
 
 test "type info: null terminated pointer type info" {
-    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
     try testNullTerminatedPtr();
     comptime try testNullTerminatedPtr();
 }
@@ -136,8 +134,6 @@ fn testSlice() !void {
 }
 
 test "type info: array type info" {
-    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
     try testArray();
     comptime try testArray();
 }