aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2021-10-16 17:23:30 +0200
committerRobin Voetter <robin@voetter.nl>2021-10-17 20:33:04 +0200
commitd193ba9843324dcaf239220df8db63ebe3adf67e (patch)
treed90845ee6808df06d314325e9e85b4395bd8b454 /src/Sema.zig
parent9336a87452eda87c19cb707484d0b6dfb4140b57 (diff)
downloadzig-d193ba9843324dcaf239220df8db63ebe3adf67e.tar.gz
zig-d193ba9843324dcaf239220df8db63ebe3adf67e.zip
stage2: array->vector coercion
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig51
1 files changed, 29 insertions, 22 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 6ad423a8e8..b9c296bd4b 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -11653,7 +11653,11 @@ fn coerce(
else => {},
},
.Array => switch (inst_ty.zigTypeTag()) {
- .Vector => return sema.coerceVectorToArray(block, dest_ty, dest_ty_src, inst, inst_src),
+ .Vector => return sema.coerceVectorInMemory(block, dest_ty, dest_ty_src, inst, inst_src),
+ else => {},
+ },
+ .Vector => switch (inst_ty.zigTypeTag()) {
+ .Array => return sema.coerceVectorInMemory(block, dest_ty, dest_ty_src, inst, inst_src),
else => {},
},
else => {},
@@ -12237,46 +12241,49 @@ fn coerceEnumToUnion(
return sema.failWithOwnedErrorMsg(msg);
}
-fn coerceVectorToArray(
+// Coerces vectors/arrays which have the same in-memory layout. This can be used for
+// both coercing from and to vectors.
+fn coerceVectorInMemory(
sema: *Sema,
block: *Block,
- array_ty: Type,
- array_ty_src: LazySrcLoc,
- vector: Air.Inst.Ref,
- vector_src: LazySrcLoc,
+ dest_ty: Type,
+ dest_ty_src: LazySrcLoc,
+ inst: Air.Inst.Ref,
+ inst_src: LazySrcLoc,
) !Air.Inst.Ref {
- const vector_ty = sema.typeOf(vector);
- const array_len = array_ty.arrayLen();
- const vector_len = vector_ty.arrayLen();
- if (array_len != vector_len) {
+ const inst_ty = sema.typeOf(inst);
+ const inst_len = inst_ty.arrayLen();
+ const dest_len = dest_ty.arrayLen();
+
+ if (dest_len != inst_len) {
const msg = msg: {
- const msg = try sema.errMsg(block, vector_src, "expected {}, found {}", .{
- array_ty, vector_ty,
+ const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
+ dest_ty, inst_ty,
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, array_ty_src, msg, "array has length {d}", .{array_len});
- try sema.errNote(block, vector_src, msg, "vector has length {d}", .{vector_len});
+ try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
+ try sema.errNote(block, inst_src, msg, "source has length {d}", .{inst_len});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(msg);
}
const target = sema.mod.getTarget();
- const array_elem_ty = array_ty.childType();
- const vector_elem_ty = vector_ty.childType();
- const in_memory_result = coerceInMemoryAllowed(array_elem_ty, vector_elem_ty, false, target);
+ const dest_elem_ty = dest_ty.childType();
+ const inst_elem_ty = inst_ty.childType();
+ const in_memory_result = coerceInMemoryAllowed(dest_elem_ty, inst_elem_ty, false, target);
if (in_memory_result != .ok) {
// TODO recursive error notes for coerceInMemoryAllowed failure
- return sema.fail(block, vector_src, "expected {}, found {}", .{ array_ty, vector_ty });
+ return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty });
}
- if (try sema.resolveMaybeUndefVal(block, vector_src, vector)) |vector_val| {
+ if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |inst_val| {
// These types share the same comptime value representation.
- return sema.addConstant(array_ty, vector_val);
+ return sema.addConstant(dest_ty, inst_val);
}
- try sema.requireRuntimeBlock(block, vector_src);
- return block.addTyOp(.bitcast, array_ty, vector);
+ try sema.requireRuntimeBlock(block, inst_src);
+ return block.addTyOp(.bitcast, dest_ty, inst);
}
fn coerceErrSetToAnyError(