diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-28 14:17:05 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-28 14:17:05 -0700 |
| commit | b6ccde47adeb0dbd7b39150c36498100e0d98075 (patch) | |
| tree | c9fff157c08701cd6d6849a1c95fddd5385e1c86 /src/Sema.zig | |
| parent | 691c7cb3cd3cc6cb4f6324d0ad4a5c3e2e8ff94c (diff) | |
| download | zig-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.zig | 51 |
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 => {}, } |
