aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-03-28 14:17:05 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-03-28 14:17:05 -0700
commitb6ccde47adeb0dbd7b39150c36498100e0d98075 (patch)
treec9fff157c08701cd6d6849a1c95fddd5385e1c86 /src/Sema.zig
parent691c7cb3cd3cc6cb4f6324d0ad4a5c3e2e8ff94c (diff)
downloadzig-b6ccde47adeb0dbd7b39150c36498100e0d98075.tar.gz
zig-b6ccde47adeb0dbd7b39150c36498100e0d98075.zip
Sema: allow mixing array and vector operands
* Added peer type resolution for arrays and vectors: the vector type is selected. * Fixed passing the lhs type or rhs type instead of the peer resolved type when calling Value methods during analyzeArithmetic handling of comptime expressions. * `checkVectorizableBinaryOperands` now allows mixing vectors and arrays, as long as one of the operands is a vector. This matches stage1's handling of `^=` but apparently stage1 is inconsistent and does not handle e.g. `*=`. stage2 now will always allow mixing vector and array operands for all operations.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig51
1 files changed, 37 insertions, 14 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 375b588c40..e79e358907 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -9617,7 +9617,7 @@ fn analyzeArithmetic(
if (lhs_val.isUndef()) {
if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
if (maybe_rhs_val) |rhs_val| {
- if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
+ if (rhs_val.compare(.neq, Value.negative_one, resolved_type, target)) {
return sema.addConstUndef(resolved_type);
}
}
@@ -9692,7 +9692,7 @@ fn analyzeArithmetic(
if (lhs_val.isUndef()) {
if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
if (maybe_rhs_val) |rhs_val| {
- if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
+ if (rhs_val.compare(.neq, Value.negative_one, resolved_type, target)) {
return sema.addConstUndef(resolved_type);
}
}
@@ -9755,7 +9755,7 @@ fn analyzeArithmetic(
if (lhs_val.isUndef()) {
if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
if (maybe_rhs_val) |rhs_val| {
- if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
+ if (rhs_val.compare(.neq, Value.negative_one, resolved_type, target)) {
return sema.addConstUndef(resolved_type);
}
}
@@ -9845,7 +9845,7 @@ fn analyzeArithmetic(
if (lhs_val.compareWithZero(.eq)) {
return sema.addConstant(resolved_type, Value.zero);
}
- if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
+ if (lhs_val.compare(.eq, Value.one, resolved_type, target)) {
return casted_rhs;
}
}
@@ -9861,7 +9861,7 @@ fn analyzeArithmetic(
if (rhs_val.compareWithZero(.eq)) {
return sema.addConstant(resolved_type, Value.zero);
}
- if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
+ if (rhs_val.compare(.eq, Value.one, resolved_type, target)) {
return casted_lhs;
}
if (maybe_lhs_val) |lhs_val| {
@@ -9896,7 +9896,7 @@ fn analyzeArithmetic(
if (lhs_val.compareWithZero(.eq)) {
return sema.addConstant(resolved_type, Value.zero);
}
- if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
+ if (lhs_val.compare(.eq, Value.one, resolved_type, target)) {
return casted_rhs;
}
}
@@ -9908,7 +9908,7 @@ fn analyzeArithmetic(
if (rhs_val.compareWithZero(.eq)) {
return sema.addConstant(resolved_type, Value.zero);
}
- if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
+ if (rhs_val.compare(.eq, Value.one, resolved_type, target)) {
return casted_lhs;
}
if (maybe_lhs_val) |lhs_val| {
@@ -9932,7 +9932,7 @@ fn analyzeArithmetic(
if (lhs_val.compareWithZero(.eq)) {
return sema.addConstant(resolved_type, Value.zero);
}
- if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
+ if (lhs_val.compare(.eq, Value.one, resolved_type, target)) {
return casted_rhs;
}
}
@@ -9944,7 +9944,7 @@ fn analyzeArithmetic(
if (rhs_val.compareWithZero(.eq)) {
return sema.addConstant(resolved_type, Value.zero);
}
- if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
+ if (rhs_val.compare(.eq, Value.one, resolved_type, target)) {
return casted_lhs;
}
if (maybe_lhs_val) |lhs_val| {
@@ -14521,9 +14521,20 @@ fn checkVectorizableBinaryOperands(
) CompileError!void {
const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
- if (lhs_zig_ty_tag == .Vector and rhs_zig_ty_tag == .Vector) {
- const lhs_len = lhs_ty.vectorLen();
- const rhs_len = rhs_ty.vectorLen();
+ if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;
+
+ const lhs_is_vector = switch (lhs_zig_ty_tag) {
+ .Vector, .Array => true,
+ else => false,
+ };
+ const rhs_is_vector = switch (rhs_zig_ty_tag) {
+ .Vector, .Array => true,
+ else => false,
+ };
+
+ if (lhs_is_vector and rhs_is_vector) {
+ const lhs_len = lhs_ty.arrayLen();
+ const rhs_len = rhs_ty.arrayLen();
if (lhs_len != rhs_len) {
const msg = msg: {
const msg = try sema.errMsg(block, src, "vector length mismatch", .{});
@@ -14534,14 +14545,14 @@ fn checkVectorizableBinaryOperands(
};
return sema.failWithOwnedErrorMsg(block, msg);
}
- } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {
+ } else {
const target = sema.mod.getTarget();
const msg = msg: {
const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{
lhs_ty.fmt(target), rhs_ty.fmt(target),
});
errdefer msg.destroy(sema.gpa);
- if (lhs_zig_ty_tag == .Vector) {
+ if (lhs_is_vector) {
try sema.errNote(block, lhs_src, msg, "vector here", .{});
try sema.errNote(block, rhs_src, msg, "scalar here", .{});
} else {
@@ -21017,6 +21028,18 @@ fn resolvePeerTypes(
chosen_i = candidate_i + 1;
continue;
},
+ .Vector => switch (chosen_ty_tag) {
+ .Array => {
+ chosen = candidate;
+ chosen_i = candidate_i + 1;
+ continue;
+ },
+ else => {},
+ },
+ .Array => switch (chosen_ty_tag) {
+ .Vector => continue,
+ else => {},
+ },
else => {},
}