| author | |
| committer | |
| log | 5f5ab491684f0f5dd235189416f9c3d85e8e9be0 |
| tree | 51d450c61c1ece9b6208d0904ab306f660502251 |
| parent | a492a607d5410b1136db3a63fabd01c10827144c |
Closes #106924 files changed, 47 insertions(+), 12 deletions(-)
src/Sema.zig+4-4| ... | @@ -11842,7 +11842,7 @@ fn zirShl( | ... | @@ -11842,7 +11842,7 @@ fn zirShl( |
| 11842 | if (scalar_ty.zigTypeTag() == .ComptimeInt) { | 11842 | if (scalar_ty.zigTypeTag() == .ComptimeInt) { |
| 11843 | break :val shifted.wrapped_result; | 11843 | break :val shifted.wrapped_result; |
| 11844 | } | 11844 | } |
| 11845 | if (shifted.overflow_bit.compareAllWithZero(.eq)) { | 11845 | if (shifted.overflow_bit.compareAllWithZero(.eq, sema.mod)) { |
| 11846 | break :val shifted.wrapped_result; | 11846 | break :val shifted.wrapped_result; |
| 11847 | } | 11847 | } |
| 11848 | return sema.fail(block, src, "operation caused overflow", .{}); | 11848 | return sema.fail(block, src, "operation caused overflow", .{}); |
| ... | @@ -12831,7 +12831,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -12831,7 +12831,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 12831 | const lhs_val = maybe_lhs_val orelse unreachable; | 12831 | const lhs_val = maybe_lhs_val orelse unreachable; |
| 12832 | const rhs_val = maybe_rhs_val orelse unreachable; | 12832 | const rhs_val = maybe_rhs_val orelse unreachable; |
| 12833 | const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod) catch unreachable; | 12833 | const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod) catch unreachable; |
| 12834 | if (!rem.compareAllWithZero(.eq)) { | 12834 | if (!rem.compareAllWithZero(.eq, mod)) { |
| 12835 | return sema.fail(block, src, "ambiguous coercion of division operands '{s}' and '{s}'; non-zero remainder '{}'", .{ | 12835 | return sema.fail(block, src, "ambiguous coercion of division operands '{s}' and '{s}'; non-zero remainder '{}'", .{ |
| 12836 | @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()), rem.fmtValue(resolved_type, sema.mod), | 12836 | @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()), rem.fmtValue(resolved_type, sema.mod), |
| 12837 | }); | 12837 | }); |
| ... | @@ -13024,7 +13024,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13024,7 +13024,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13024 | if (maybe_rhs_val) |rhs_val| { | 13024 | if (maybe_rhs_val) |rhs_val| { |
| 13025 | if (is_int) { | 13025 | if (is_int) { |
| 13026 | const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod); | 13026 | const modulus_val = try lhs_val.intMod(rhs_val, resolved_type, sema.arena, mod); |
| 13027 | if (!(modulus_val.compareAllWithZero(.eq))) { | 13027 | if (!(modulus_val.compareAllWithZero(.eq, mod))) { |
| 13028 | return sema.fail(block, src, "exact division produced remainder", .{}); | 13028 | return sema.fail(block, src, "exact division produced remainder", .{}); |
| 13029 | } | 13029 | } |
| 13030 | const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, mod); | 13030 | const res = try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, mod); |
| ... | @@ -13035,7 +13035,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13035,7 +13035,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13035 | return sema.addConstant(resolved_type, res); | 13035 | return sema.addConstant(resolved_type, res); |
| 13036 | } else { | 13036 | } else { |
| 13037 | const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod); | 13037 | const modulus_val = try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, mod); |
| 13038 | if (!(modulus_val.compareAllWithZero(.eq))) { | 13038 | if (!(modulus_val.compareAllWithZero(.eq, mod))) { |
| 13039 | return sema.fail(block, src, "exact division produced remainder", .{}); | 13039 | return sema.fail(block, src, "exact division produced remainder", .{}); |
| 13040 | } | 13040 | } |
| 13041 | return sema.addConstant( | 13041 | return sema.addConstant( |
src/type.zig+3-3| ... | @@ -5533,7 +5533,7 @@ pub const Type = extern union { | ... | @@ -5533,7 +5533,7 @@ pub const Type = extern union { |
| 5533 | } | 5533 | } |
| 5534 | const S = struct { | 5534 | const S = struct { |
| 5535 | fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, m: *Module) ?usize { | 5535 | fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, m: *Module) ?usize { |
| 5536 | if (int_val.compareAllWithZero(.lt)) return null; | 5536 | if (int_val.compareAllWithZero(.lt, m)) return null; |
| 5537 | var end_payload: Value.Payload.U64 = .{ | 5537 | var end_payload: Value.Payload.U64 = .{ |
| 5538 | .base = .{ .tag = .int_u64 }, | 5538 | .base = .{ .tag = .int_u64 }, |
| 5539 | .data = end, | 5539 | .data = end, |
| ... | @@ -6556,12 +6556,12 @@ pub const Type = extern union { | ... | @@ -6556,12 +6556,12 @@ pub const Type = extern union { |
| 6556 | if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) { | 6556 | if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) { |
| 6557 | switch (d.size) { | 6557 | switch (d.size) { |
| 6558 | .Slice => { | 6558 | .Slice => { |
| 6559 | if (sent.compareAllWithZero(.eq)) { | 6559 | if (sent.compareAllWithZero(.eq, mod)) { |
| 6560 | return Type.initTag(.const_slice_u8_sentinel_0); | 6560 | return Type.initTag(.const_slice_u8_sentinel_0); |
| 6561 | } | 6561 | } |
| 6562 | }, | 6562 | }, |
| 6563 | .Many => { | 6563 | .Many => { |
| 6564 | if (sent.compareAllWithZero(.eq)) { | 6564 | if (sent.compareAllWithZero(.eq, mod)) { |
| 6565 | return Type.initTag(.manyptr_const_u8_sentinel_0); | 6565 | return Type.initTag(.manyptr_const_u8_sentinel_0); |
| 6566 | } | 6566 | } |
| 6567 | }, | 6567 | }, |
src/value.zig+29-5| ... | @@ -2076,13 +2076,22 @@ pub const Value = extern union { | ... | @@ -2076,13 +2076,22 @@ pub const Value = extern union { |
| 2076 | /// For vectors, returns true if comparison is true for ALL elements. | 2076 | /// For vectors, returns true if comparison is true for ALL elements. |
| 2077 | /// | 2077 | /// |
| 2078 | /// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)` | 2078 | /// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)` |
| 2079 | pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator) bool { | 2079 | pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, mod: *Module) bool { |
| 2080 | return compareAllWithZeroAdvanced(lhs, op, null) catch unreachable; | 2080 | return compareAllWithZeroAdvancedExtra(lhs, op, mod, null) catch unreachable; |
| 2081 | } | 2081 | } |
| 2082 | 2082 | ||
| 2083 | pub fn compareAllWithZeroAdvanced( | 2083 | pub fn compareAllWithZeroAdvanced( |
| 2084 | lhs: Value, | 2084 | lhs: Value, |
| 2085 | op: std.math.CompareOperator, | 2085 | op: std.math.CompareOperator, |
| 2086 | sema: *Sema, | ||
| 2087 | ) Module.CompileError!bool { | ||
| 2088 | return compareAllWithZeroAdvancedExtra(lhs, op, sema.mod, sema); | ||
| 2089 | } | ||
| 2090 | |||
| 2091 | pub fn compareAllWithZeroAdvancedExtra( | ||
| 2092 | lhs: Value, | ||
| 2093 | op: std.math.CompareOperator, | ||
| 2094 | mod: *Module, | ||
| 2086 | opt_sema: ?*Sema, | 2095 | opt_sema: ?*Sema, |
| 2087 | ) Module.CompileError!bool { | 2096 | ) Module.CompileError!bool { |
| 2088 | if (lhs.isInf()) { | 2097 | if (lhs.isInf()) { |
| ... | @@ -2095,10 +2104,25 @@ pub const Value = extern union { | ... | @@ -2095,10 +2104,25 @@ pub const Value = extern union { |
| 2095 | } | 2104 | } |
| 2096 | 2105 | ||
| 2097 | switch (lhs.tag()) { | 2106 | switch (lhs.tag()) { |
| 2098 | .repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvanced(op, opt_sema), | 2107 | .repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvancedExtra(op, mod, opt_sema), |
| 2099 | .aggregate => { | 2108 | .aggregate => { |
| 2100 | for (lhs.castTag(.aggregate).?.data) |elem_val| { | 2109 | for (lhs.castTag(.aggregate).?.data) |elem_val| { |
| 2101 | if (!(try elem_val.compareAllWithZeroAdvanced(op, opt_sema))) return false; | 2110 | if (!(try elem_val.compareAllWithZeroAdvancedExtra(op, mod, opt_sema))) return false; |
| 2111 | } | ||
| 2112 | return true; | ||
| 2113 | }, | ||
| 2114 | .str_lit => { | ||
| 2115 | const str_lit = lhs.castTag(.str_lit).?.data; | ||
| 2116 | const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; | ||
| 2117 | for (bytes) |byte| { | ||
| 2118 | if (!std.math.compare(byte, op, 0)) return false; | ||
| 2119 | } | ||
| 2120 | return true; | ||
| 2121 | }, | ||
| 2122 | .bytes => { | ||
| 2123 | const bytes = lhs.castTag(.bytes).?.data; | ||
| 2124 | for (bytes) |byte| { | ||
| 2125 | if (!std.math.compare(byte, op, 0)) return false; | ||
| 2102 | } | 2126 | } |
| 2103 | return true; | 2127 | return true; |
| 2104 | }, | 2128 | }, |
| ... | @@ -3103,7 +3127,7 @@ pub const Value = extern union { | ... | @@ -3103,7 +3127,7 @@ pub const Value = extern union { |
| 3103 | .int_i64, | 3127 | .int_i64, |
| 3104 | .int_big_positive, | 3128 | .int_big_positive, |
| 3105 | .int_big_negative, | 3129 | .int_big_negative, |
| 3106 | => compareAllWithZero(self, .eq), | 3130 | => self.orderAgainstZero().compare(.eq), |
| 3107 | 3131 | ||
| 3108 | .undef => unreachable, | 3132 | .undef => unreachable, |
| 3109 | .unreachable_value => unreachable, | 3133 | .unreachable_value => unreachable, |
test/behavior/vector.zig+11| ... | @@ -1286,3 +1286,14 @@ test "store to vector in slice" { | ... | @@ -1286,3 +1286,14 @@ test "store to vector in slice" { |
| 1286 | s[i] = s[0]; | 1286 | s[i] = s[0]; |
| 1287 | try expectEqual(v[1], v[0]); | 1287 | try expectEqual(v[1], v[0]); |
| 1288 | } | 1288 | } |
| 1289 | |||
| 1290 | test "addition of vectors represented as strings" { | ||
| 1291 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1292 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1293 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1294 | |||
| 1295 | const V = @Vector(3, u8); | ||
| 1296 | const foo: V = "foo".*; | ||
| 1297 | const bar: V = @typeName(u32).*; | ||
| 1298 | try expectEqual(V{ 219, 162, 161 }, foo + bar); | ||
| 1299 | } |