Commit 04e66e6b4d

Jacob Young <jacobly0@users.noreply.github.com>
2023-06-02 07:15:36
InternPool: add optional coercion
1 parent fdfe730
lib/std/child_process.zig
@@ -542,7 +542,7 @@ pub const ChildProcess = struct {
             } else if (builtin.output_mode == .Exe) {
                 // Then we have Zig start code and this works.
                 // TODO type-safety for null-termination of `os.environ`.
-                break :m @ptrCast([*:null]?[*:0]const u8, os.environ.ptr);
+                break :m @ptrCast([*:null]const ?[*:0]const u8, os.environ.ptr);
             } else {
                 // TODO come up with a solution for this.
                 @compileError("missing std lib enhancement: ChildProcess implementation has no way to collect the environment variables to forward to the child process");
@@ -1425,9 +1425,9 @@ pub fn createWindowsEnvBlock(allocator: mem.Allocator, env_map: *const EnvMap) !
     return try allocator.realloc(result, i);
 }
 
-pub fn createNullDelimitedEnvMap(arena: mem.Allocator, env_map: *const EnvMap) ![:null]?[*:0]const u8 {
+pub fn createNullDelimitedEnvMap(arena: mem.Allocator, env_map: *const EnvMap) ![:null]?[*:0]u8 {
     const envp_count = env_map.count();
-    const envp_buf = try arena.allocSentinel(?[*:0]const u8, envp_count, null);
+    const envp_buf = try arena.allocSentinel(?[*:0]u8, envp_count, null);
     {
         var it = env_map.iterator();
         var i: usize = 0;
lib/std/process.zig
@@ -1143,7 +1143,7 @@ pub fn execve(
         } else if (builtin.output_mode == .Exe) {
             // Then we have Zig start code and this works.
             // TODO type-safety for null-termination of `os.environ`.
-            break :m @ptrCast([*:null]?[*:0]const u8, os.environ.ptr);
+            break :m @ptrCast([*:null]const ?[*:0]const u8, os.environ.ptr);
         } else {
             // TODO come up with a solution for this.
             @compileError("missing std lib enhancement: std.process.execv implementation has no way to collect the environment variables to forward to the child process");
src/InternPool.zig
@@ -4614,18 +4614,27 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
                     .int => |int| return ip.getCoerced(gpa, int, new_ty),
                     else => {},
                 },
-            .opt => |opt| if (ip.isPointerType(new_ty))
-                return switch (opt.val) {
+            .opt => |opt| switch (ip.indexToKey(new_ty)) {
+                .ptr_type => |ptr_type| return switch (opt.val) {
                     .none => try ip.get(gpa, .{ .ptr = .{
                         .ty = new_ty,
                         .addr = .{ .int = .zero_usize },
-                        .len = switch (ip.indexToKey(new_ty).ptr_type.flags.size) {
+                        .len = switch (ptr_type.flags.size) {
                             .One, .Many, .C => .none,
                             .Slice => try ip.get(gpa, .{ .undef = .usize_type }),
                         },
                     } }),
                     else => |payload| try ip.getCoerced(gpa, payload, new_ty),
                 },
+                .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{
+                    .ty = new_ty,
+                    .val = switch (opt.val) {
+                        .none => .none,
+                        else => try ip.getCoerced(gpa, opt.val, child_type),
+                    },
+                } }),
+                else => {},
+            },
             .err => |err| if (ip.isErrorSetType(new_ty))
                 return ip.get(gpa, .{ .err = .{
                     .ty = new_ty,
src/Sema.zig
@@ -26470,7 +26470,11 @@ fn coerceExtra(
                     }
 
                     if (dest_info.sentinel == null or inst_info.sentinel == null or
-                        !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, mod))
+                        !dest_info.sentinel.?.eql(
+                        try mod.getCoerced(inst_info.sentinel.?, dest_info.pointee_type),
+                        dest_info.pointee_type,
+                        mod,
+                    ))
                         break :p;
 
                     const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
@@ -27350,7 +27354,11 @@ fn coerceInMemoryAllowed(
         }
         const ok_sent = dest_info.sentinel == null or
             (src_info.sentinel != null and
-            dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, mod));
+            dest_info.sentinel.?.eql(
+            try mod.getCoerced(src_info.sentinel.?, dest_info.elem_type),
+            dest_info.elem_type,
+            mod,
+        ));
         if (!ok_sent) {
             return InMemoryCoercionResult{ .array_sentinel = .{
                 .actual = src_info.sentinel orelse Value.@"unreachable",
@@ -27704,8 +27712,11 @@ fn coerceInMemoryAllowedPtrs(
     }
 
     const ok_sent = dest_info.sentinel == null or src_info.size == .C or
-        (src_info.sentinel != null and
-        dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type, sema.mod));
+        (src_info.sentinel != null and dest_info.sentinel.?.eql(
+        try mod.getCoerced(src_info.sentinel.?, dest_info.pointee_type),
+        dest_info.pointee_type,
+        sema.mod,
+    ));
     if (!ok_sent) {
         return InMemoryCoercionResult{ .ptr_sentinel = .{
             .actual = src_info.sentinel orelse Value.@"unreachable",