aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-26 14:52:45 -0500
committerGitHub <noreply@github.com>2022-02-26 14:52:45 -0500
commit8349a644d0b9d4b2d58d736a14cdcc567a9e9b89 (patch)
tree419fe3dc7cab67d43f0cc5b85040340476ab42a1 /src
parentb3aa1ab693ac160a07c44f07c7b90577039860a1 (diff)
parentbf5c055562b88f1a686815c85d2a29c0889a97ee (diff)
downloadzig-8349a644d0b9d4b2d58d736a14cdcc567a9e9b89.tar.gz
zig-8349a644d0b9d4b2d58d736a14cdcc567a9e9b89.zip
Merge pull request #10986 from Vexu/stage2
stage2: actually coerce in coerce_result_ptr at comptime
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig29
-rw-r--r--src/type.zig4
-rw-r--r--src/value.zig23
3 files changed, 28 insertions, 28 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 41398016e5..4588f487e2 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -1593,27 +1593,16 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
}
}
- // We would like to rely on the mechanism below even for comptime values.
- // However in the case that the pointer points to comptime-mutable value,
- // we cannot do it.
- if (try sema.resolveDefinedValue(block, src, ptr)) |ptr_val| {
- if (ptr_val.isComptimeMutablePtr()) {
- const ptr_ty = try Type.ptr(sema.arena, .{
- .pointee_type = pointee_ty,
- .@"addrspace" = addr_space,
- });
- return sema.addConstant(ptr_ty, ptr_val);
- }
- }
-
// Make a dummy store through the pointer to test the coercion.
// We will then use the generated instructions to decide what
// kind of transformations to make on the result pointer.
var trash_block = block.makeSubBlock();
+ trash_block.is_comptime = false;
defer trash_block.instructions.deinit(sema.gpa);
+ const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));
const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value);
- try sema.storePtr(&trash_block, src, ptr, dummy_operand);
+ try sema.storePtr(&trash_block, src, dummy_ptr, dummy_operand);
{
const air_tags = sema.air_instructions.items(.tag);
@@ -1644,6 +1633,9 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
switch (air_tags[trash_inst]) {
.bitcast => {
if (Air.indexToRef(trash_inst) == dummy_operand) {
+ if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
+ return sema.addConstant(ptr_ty, ptr_val);
+ }
return sema.bitCast(block, ptr_ty, new_ptr, src);
}
const ty_op = air_datas[trash_inst].ty_op;
@@ -1652,7 +1644,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
.pointee_type = operand_ty,
.@"addrspace" = addr_space,
});
- new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src);
+ if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| {
+ new_ptr = try sema.addConstant(ptr_operand_ty, ptr_val);
+ } else {
+ new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src);
+ }
},
.wrap_optional => {
new_ptr = try sema.analyzeOptionalPayloadPtr(block, src, new_ptr, false, true);
@@ -1673,7 +1669,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 +16933,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,
}
diff --git a/src/value.zig b/src/value.zig
index 4df36f79a1..7c28398b73 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -791,19 +791,24 @@ pub const Value = extern union {
return decl_val.toAllocatedBytes(decl.ty, allocator);
},
.the_only_possible_value => return &[_]u8{},
- .slice => return toAllocatedBytes(val.castTag(.slice).?.data.ptr, ty, allocator),
- else => {
- const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));
- var elem_value_buf: ElemValueBuffer = undefined;
- for (result) |*elem, i| {
- const elem_val = val.elemValueBuffer(i, &elem_value_buf);
- elem.* = @intCast(u8, elem_val.toUnsignedInt());
- }
- return result;
+ .slice => {
+ const slice = val.castTag(.slice).?.data;
+ return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(), allocator);
},
+ else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator),
}
}
+ fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator) ![]u8 {
+ const result = try allocator.alloc(u8, @intCast(usize, len));
+ var elem_value_buf: ElemValueBuffer = undefined;
+ for (result) |*elem, i| {
+ const elem_val = val.elemValueBuffer(i, &elem_value_buf);
+ elem.* = @intCast(u8, elem_val.toUnsignedInt());
+ }
+ return result;
+ }
+
pub const ToTypeBuffer = Type.Payload.Bits;
/// Asserts that the value is representable as a type.