diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-02-25 12:54:40 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-02-26 12:51:23 -0700 |
| commit | ee149aaa03e586e48c32cce09bf488ae0e88d053 (patch) | |
| tree | 786f7b54e7e47027ee66e3fd2c412bed4a31b7bf /src | |
| parent | b3aa1ab693ac160a07c44f07c7b90577039860a1 (diff) | |
| download | zig-ee149aaa03e586e48c32cce09bf488ae0e88d053.tar.gz zig-ee149aaa03e586e48c32cce09bf488ae0e88d053.zip | |
stage2: actually coerce in coerce_result_ptr at comptime
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 31 | ||||
| -rw-r--r-- | src/type.zig | 4 |
2 files changed, 30 insertions, 5 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 41398016e5..4f08fb12d0 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1598,11 +1598,37 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE // we cannot do it. if (try sema.resolveDefinedValue(block, src, ptr)) |ptr_val| { if (ptr_val.isComptimeMutablePtr()) { + const sentinel_val = try sema.addConstant(pointee_ty, Value.initTag(.unreachable_value)); + const coerced = try sema.coerce(block, sema.typeOf(ptr).childType(), sentinel_val, src); + + var res_ptr = ptr_val; + var cur_val = (try sema.resolveMaybeUndefVal(block, .unneeded, coerced)).?; + while (true) switch (cur_val.tag()) { + .unreachable_value => break, + .opt_payload => { + res_ptr = try Value.Tag.opt_payload_ptr.create(sema.arena, res_ptr); + cur_val = cur_val.castTag(.opt_payload).?.data; + }, + .eu_payload => { + res_ptr = try Value.Tag.eu_payload_ptr.create(sema.arena, res_ptr); + cur_val = cur_val.castTag(.eu_payload).?.data; + }, + else => { + if (std.debug.runtime_safety) { + std.debug.panic("unexpected Value tag for coerce_result_ptr: {s}", .{ + cur_val.tag(), + }); + } else { + unreachable; + } + }, + }; + const ptr_ty = try Type.ptr(sema.arena, .{ .pointee_type = pointee_ty, .@"addrspace" = addr_space, }); - return sema.addConstant(ptr_ty, ptr_val); + return sema.addConstant(ptr_ty, res_ptr); } } @@ -1673,7 +1699,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE } }, } - } else unreachable; // TODO should not need else unreachable + } } pub fn analyzeStructDecl( @@ -16937,7 +16963,6 @@ fn wrapErrorUnionPayload( const dest_payload_ty = dest_ty.errorUnionPayload(); const coerced = try sema.coerce(block, dest_payload_ty, inst, inst_src); if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| { - if (val.isUndef()) return sema.addConstUndef(dest_ty); return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val)); } try sema.requireRuntimeBlock(block, inst_src); diff --git a/src/type.zig b/src/type.zig index 4eb78b0656..581465c51a 100644 --- a/src/type.zig +++ b/src/type.zig @@ -3980,7 +3980,7 @@ pub const Type = extern union { pub fn structFields(ty: Type) Module.Struct.Fields { switch (ty.tag()) { - .empty_struct => return .{}, + .empty_struct, .empty_struct_literal => return .{}, .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; assert(struct_obj.haveFieldTypes()); @@ -3996,7 +3996,7 @@ pub const Type = extern union { const struct_obj = ty.castTag(.@"struct").?.data; return struct_obj.fields.count(); }, - .empty_struct => return 0, + .empty_struct, .empty_struct_literal => return 0, .tuple => return ty.castTag(.tuple).?.data.types.len, else => unreachable, } |
