Skip to content

Commit 4dba6cc

Browse files
committed
Add peer type resolution for compatible tuples and arrays
1 parent 95ac94b commit 4dba6cc

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

src/Sema.zig

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30079,6 +30079,63 @@ fn resolvePeerTypes(
3007930079
},
3008030080
.Array => switch (chosen_ty_tag) {
3008130081
.Vector => continue,
30082+
.Struct => {
30083+
if (chosen_ty.isTuple() and candidate_ty.arrayLen() == chosen_ty.arrayLen()) {
30084+
const candidate_child_ty = candidate_ty.childType();
30085+
const candidate_child_ty_tag = try candidate_child_ty.zigTypeTagOrPoison();
30086+
for (chosen_ty.tupleFields().types) |chosen_child_ty| {
30087+
const chosen_child_ty_tag = try chosen_child_ty.zigTypeTagOrPoison();
30088+
if (chosen_child_ty_tag == .ComptimeInt and (candidate_child_ty_tag == .Int or candidate_child_ty_tag == .Float) or
30089+
chosen_child_ty_tag == .ComptimeFloat and candidate_child_ty_tag == .Float) {
30090+
continue;
30091+
} else if (chosen_child_ty_tag == .Int and candidate_child_ty_tag == .Int) {
30092+
if (chosen_child_ty.intInfo(target).bits < candidate_child_ty.intInfo(target).bits) {
30093+
continue;
30094+
}
30095+
} else if (chosen_child_ty_tag == .Float and candidate_child_ty_tag == .Float) {
30096+
if (chosen_child_ty.floatBits(target) < candidate_child_ty.floatBits(target)) {
30097+
continue;
30098+
}
30099+
}
30100+
if (.ok != try sema.coerceInMemoryAllowed(block, candidate_child_ty, chosen_child_ty, false, target, src, src)) {
30101+
break;
30102+
}
30103+
} else {
30104+
chosen = candidate;
30105+
chosen_i = candidate_i + 1;
30106+
continue;
30107+
}
30108+
}
30109+
},
30110+
else => {},
30111+
},
30112+
.Struct => switch (chosen_ty_tag) {
30113+
.Array => {
30114+
if (candidate_ty.isTuple() and candidate_ty.arrayLen() == chosen_ty.arrayLen()) {
30115+
const chosen_child_ty = chosen_ty.childType();
30116+
const chosen_child_ty_tag = try chosen_child_ty.zigTypeTagOrPoison();
30117+
for (candidate_ty.tupleFields().types) |candidate_child_ty| {
30118+
const candidate_child_ty_tag = try candidate_child_ty.zigTypeTagOrPoison();
30119+
if (candidate_child_ty_tag == .ComptimeInt and (chosen_child_ty_tag == .Int or chosen_child_ty_tag == .Float) or
30120+
candidate_child_ty_tag == .ComptimeFloat and chosen_child_ty_tag == .Float) {
30121+
continue;
30122+
} else if (candidate_child_ty_tag == .Int and chosen_child_ty_tag == .Int) {
30123+
if (candidate_child_ty.intInfo(target).bits < chosen_child_ty.intInfo(target).bits) {
30124+
continue;
30125+
}
30126+
} else if (candidate_child_ty_tag == .Float and chosen_child_ty_tag == .Float) {
30127+
if (candidate_child_ty.floatBits(target) < chosen_child_ty.floatBits(target)) {
30128+
continue;
30129+
}
30130+
}
30131+
if (.ok != try sema.coerceInMemoryAllowed(block, chosen_child_ty, candidate_child_ty, false, target, src, src)) {
30132+
break;
30133+
}
30134+
} else {
30135+
continue;
30136+
}
30137+
}
30138+
},
3008230139
else => {},
3008330140
},
3008430141
.Fn => if (chosen_ty.isSinglePointer() and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag() == .Fn) {

test/behavior/cast.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,3 +1558,21 @@ test "coercion from single-item pointer to @as to slice" {
15581558

15591559
try expect(t[0] == 1);
15601560
}
1561+
1562+
test "peer type resolution of tuple to array" {
1563+
const empty_array : [0]u8 = .{};
1564+
const empty_tuple = .{};
1565+
try std.testing.expect(@TypeOf(empty_array, empty_tuple) == [0]u8);
1566+
1567+
const a_array : [4]i16 = .{1,2,3,4};
1568+
const a_tuple = .{1,2,3,4};
1569+
try std.testing.expect(@TypeOf(a_array, a_tuple) == [4]i16);
1570+
1571+
const b_array : [4]f32 = .{1,2,3,4};
1572+
const b_tuple = .{1, 2.0, @as(f32, 2.4), @as(f16, 4)};
1573+
try std.testing.expect(@TypeOf(b_array, b_tuple) == [4]f32);
1574+
1575+
const c_array : [4]i32 = .{1,2,3,4};
1576+
const c_tuple = .{@as(i32, 1), @as(i16, 2), @as(u31, 3), 4};
1577+
try std.testing.expect(@TypeOf(c_array, c_tuple) == [4]i32);
1578+
}

0 commit comments

Comments
 (0)