Commit 955fd65cb1
src/Sema.zig
@@ -34238,7 +34238,21 @@ fn resolvePeerTypesInner(
.peer_idx_b = i,
} };
- if (!ty.childType(mod).eql(elem_ty, mod)) {
+ const peer_elem_ty = ty.childType(mod);
+ if (!peer_elem_ty.eql(elem_ty, mod)) coerce: {
+ const peer_elem_coerces_to_elem =
+ try sema.coerceInMemoryAllowed(block, elem_ty, peer_elem_ty, false, mod.getTarget(), src, src);
+ if (peer_elem_coerces_to_elem == .ok) {
+ break :coerce;
+ }
+
+ const elem_coerces_to_peer_elem =
+ try sema.coerceInMemoryAllowed(block, peer_elem_ty, elem_ty, false, mod.getTarget(), src, src);
+ if (elem_coerces_to_peer_elem == .ok) {
+ elem_ty = peer_elem_ty;
+ break :coerce;
+ }
+
return .{ .conflict = .{
.peer_idx_a = first_arr_idx,
.peer_idx_b = i,
test/behavior/cast.zig
@@ -2201,6 +2201,23 @@ test "peer type resolution: pointer attributes are combined correctly" {
try expectEqualSlices(u8, std.mem.span(@volatileCast(r3)), "baz");
}
+test "peer type resolution: arrays of compatible types" {
+ 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
+
+ var e0: u8 = 3;
+ var e1: u8 = 2;
+ var e2: u8 = 1;
+ const a = [3]*u8{ &e0, &e1, &e2 };
+ const b = [3]*const u8{ &e0, &e1, &e2 };
+
+ comptime assert(@TypeOf(a, b) == [3]*const u8);
+ comptime assert(@TypeOf(b, a) == [3]*const u8);
+
+ try expectEqual(@as(@TypeOf(a, b), a), b);
+}
+
test "cast builtins can wrap result in optional" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO