authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2023-03-08 17:49:52+01:00
committergravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2023-03-09 00:55:17+01:00
log505e720421ce4f7ed11730fe68d32e3bba711f3c
tree9bb76c6995902416714832b5506218b8b12a8251
parent06b263825a67e68cec128c640a6287fa1716dc63

sema: add peer type resolution for vectors

This is consistent with how coercion for vectors work. So now you can do this: ``` var a: @Vector(2, u16) = .{1, 2}; var b: @Vector(2, u8) = .{2, 1}; const c = @min(a, b); ``` where previously you had to cast explicitly: ``` var a: @Vector(2, u16) = .{1, 2}; var b: @Vector(2, u8) = .{2, 1}; var c: @Vector(2, u16) = b; const c = @min(a, c); ```

2 files changed, 44 insertions(+), 0 deletions(-)

src/Sema.zig+25
......@@ -29875,6 +29875,31 @@ fn resolvePeerTypes(
2987529875 continue;
2987629876 },
2987729877 .Vector => switch (chosen_ty_tag) {
29878 .Vector => {
29879 const chosen_len = chosen_ty.vectorLen();
29880 const candidate_len = candidate_ty.vectorLen();
29881 if (chosen_len != candidate_len)
29882 continue;
29883
29884 const chosen_child_ty = chosen_ty.childType();
29885 const candidate_child_ty = candidate_ty.childType();
29886 if (chosen_child_ty.zigTypeTag() == .Int and candidate_child_ty.zigTypeTag() == .Int) {
29887 const chosen_info = chosen_child_ty.intInfo(target);
29888 const candidate_info = candidate_child_ty.intInfo(target);
29889 if (chosen_info.bits < candidate_info.bits) {
29890 chosen = candidate;
29891 chosen_i = candidate_i + 1;
29892 }
29893 continue;
29894 }
29895 if (chosen_child_ty.zigTypeTag() == .Float and candidate_child_ty.zigTypeTag() == .Float) {
29896 if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) {
29897 chosen = candidate;
29898 chosen_i = candidate_i + 1;
29899 }
29900 continue;
29901 }
29902 },
2987829903 .Array => {
2987929904 chosen = candidate;
2988029905 chosen_i = candidate_i + 1;
test/behavior/vector.zig+19
......@@ -175,6 +175,25 @@ test "array to vector" {
175175 comptime try S.doTheTest();
176176}
177177
178test "peer type resolution with coercible element types" {
179 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
180 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
181 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
182 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184
185 const S = struct {
186 fn doTheTest() !void {
187 var b: @Vector(2, u8) = .{ 1, 2 };
188 var a: @Vector(2, u16) = .{ 2, 1 };
189 var t: bool = true;
190 var c = if (t) a else b;
191 try std.testing.expect(@TypeOf(c) == @Vector(2, u16));
192 }
193 };
194 comptime try S.doTheTest();
195}
196
178197test "tuple to vector" {
179198 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
180199 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO