zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 505e720421ce4f7ed11730fe68d32e3bba711f3c (tree)
parent 06b263825a67e68cec128c640a6287fa1716dc63
Author: John Schmidt <john.schmidt.h@gmail.com>
Date:   Wed,  8 Mar 2023 17:49:52 +0100

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);
```

Diffstat:
Msrc/Sema.zig | 25+++++++++++++++++++++++++
Mtest/behavior/vector.zig | 19+++++++++++++++++++
2 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/src/Sema.zig b/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; diff --git a/test/behavior/vector.zig b/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