aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index bc9d5ea55f..93b367b9d8 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -24581,8 +24581,12 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
const len = try sema.usizeCast(block, src, dest_ty.arrayLen(zcu));
- // `len == 0` because `[0:s]T` always has a comptime-known splat.
- if (!dest_ty.hasRuntimeBits(zcu) or len == 0) {
+ if (try sema.typeHasOnePossibleValue(dest_ty)) |val| {
+ return Air.internedToRef(val.toIntern());
+ }
+
+ // We also need this case because `[0:s]T` is not OPV.
+ if (len == 0) {
const empty_aggregate = try pt.intern(.{ .aggregate = .{
.ty = dest_ty.toIntern(),
.storage = .{ .elems = &.{} },
@@ -25924,6 +25928,22 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
}
}
+ zero_bit: {
+ const src_comptime = try src_elem_ty.comptimeOnlySema(pt);
+ const dest_comptime = try dest_elem_ty.comptimeOnlySema(pt);
+ assert(src_comptime == dest_comptime); // IMC
+ if (src_comptime) break :zero_bit;
+
+ const src_has_bits = try src_elem_ty.hasRuntimeBitsIgnoreComptimeSema(pt);
+ const dest_has_bits = try dest_elem_ty.hasRuntimeBitsIgnoreComptimeSema(pt);
+ assert(src_has_bits == dest_has_bits); // IMC
+ if (src_has_bits) break :zero_bit;
+
+ // The element type is zero-bit. We've done all validation (aside from the aliasing check,
+ // which we must skip) so we're done.
+ return;
+ }
+
const runtime_src = rs: {
const dest_ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;
const src_ptr_val = try sema.resolveDefinedValue(block, src_src, src_ptr) orelse break :rs src_src;