Commit 505e720421

John Schmidt <john.schmidt.h@gmail.com>
2023-03-08 17:49:52
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); ```
1 parent 06b2638
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -29875,6 +29875,31 @@ fn resolvePeerTypes(
                 continue;
             },
             .Vector => switch (chosen_ty_tag) {
+                .Vector => {
+                    const chosen_len = chosen_ty.vectorLen();
+                    const candidate_len = candidate_ty.vectorLen();
+                    if (chosen_len != candidate_len)
+                        continue;
+
+                    const chosen_child_ty = chosen_ty.childType();
+                    const candidate_child_ty = candidate_ty.childType();
+                    if (chosen_child_ty.zigTypeTag() == .Int and candidate_child_ty.zigTypeTag() == .Int) {
+                        const chosen_info = chosen_child_ty.intInfo(target);
+                        const candidate_info = candidate_child_ty.intInfo(target);
+                        if (chosen_info.bits < candidate_info.bits) {
+                            chosen = candidate;
+                            chosen_i = candidate_i + 1;
+                        }
+                        continue;
+                    }
+                    if (chosen_child_ty.zigTypeTag() == .Float and candidate_child_ty.zigTypeTag() == .Float) {
+                        if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) {
+                            chosen = candidate;
+                            chosen_i = candidate_i + 1;
+                        }
+                        continue;
+                    }
+                },
                 .Array => {
                     chosen = candidate;
                     chosen_i = candidate_i + 1;
test/behavior/vector.zig
@@ -175,6 +175,25 @@ test "array to vector" {
     comptime try S.doTheTest();
 }
 
+test "peer type resolution with coercible element types" {
+    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn doTheTest() !void {
+            var b: @Vector(2, u8) = .{ 1, 2 };
+            var a: @Vector(2, u16) = .{ 2, 1 };
+            var t: bool = true;
+            var c = if (t) a else b;
+            try std.testing.expect(@TypeOf(c) == @Vector(2, u16));
+        }
+    };
+    comptime try S.doTheTest();
+}
+
 test "tuple to vector" {
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO