authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-07 17:28:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-07 17:29:36-07:00
log6673b476855931137119ae92e91fdcb2822e9c4f
tree397a6f1077f0eda6c194fcea91da0d2ca19e8651
parent426d65d700012b27ffa652258554032f171ad77d

frontend: vectors and arrays no longer support in-memory coercion

closes #25172

3 files changed, 9 insertions(+), 45 deletions(-)

doc/langref.html.in+8
......@@ -1969,6 +1969,14 @@ or
19691969 </p>
19701970 {#see_also|@splat|@shuffle|@select|@reduce#}
19711971
1972 {#header_open|Relationship with Arrays#}
1973 <p>Vectors and {#link|Arrays#} each have a well-defined <strong>bit layout</strong>
1974 and therefore support {#link|@bitCast#} between each other. {#link|Type Coercion#} implicitly peforms
1975 {#syntax#}@bitCast{#endsyntax#}.</p>
1976 <p>Arrays have well-defined byte layout, but vectors do not, making {#link|@ptrCast#} between
1977 them {#link|Illegal Behavior#}.</p>
1978 {#header_close#}
1979
19721980 {#header_open|Destructuring Vectors#}
19731981 <p>
19741982 Vectors can be destructured:
doc/langref/test_vector.zig+1-1
......@@ -17,7 +17,7 @@ test "Basic vector usage" {
1717}
1818
1919test "Conversion between vectors, arrays, and slices" {
20 // Vectors and fixed-length arrays can be automatically assigned back and forth
20 // Vectors can be coerced to arrays, and vice versa.
2121 const arr1: [4]f32 = [_]f32{ 1.1, 3.2, 4.5, 5.6 };
2222 const vec: @Vector(4, f32) = arr1;
2323 const arr2: [4]f32 = vec;
src/Sema.zig-44
......@@ -29649,50 +29649,6 @@ pub fn coerceInMemoryAllowed(
2964929649 return .ok;
2965029650 }
2965129651
29652 // Arrays <-> Vectors
29653 if ((dest_tag == .vector and src_tag == .array) or
29654 (dest_tag == .array and src_tag == .vector))
29655 {
29656 const dest_len = dest_ty.arrayLen(zcu);
29657 const src_len = src_ty.arrayLen(zcu);
29658 if (dest_len != src_len) {
29659 return .{ .array_len = .{
29660 .actual = src_len,
29661 .wanted = dest_len,
29662 } };
29663 }
29664
29665 const dest_elem_ty = dest_ty.childType(zcu);
29666 const src_elem_ty = src_ty.childType(zcu);
29667 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src, null);
29668 if (child != .ok) {
29669 return .{ .array_elem = .{
29670 .child = try child.dupe(sema.arena),
29671 .actual = src_elem_ty,
29672 .wanted = dest_elem_ty,
29673 } };
29674 }
29675
29676 if (dest_tag == .array) {
29677 const dest_info = dest_ty.arrayInfo(zcu);
29678 if (dest_info.sentinel != null) {
29679 return .{ .array_sentinel = .{
29680 .actual = Value.@"unreachable",
29681 .wanted = dest_info.sentinel.?,
29682 .ty = dest_info.elem_type,
29683 } };
29684 }
29685 }
29686
29687 // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M),
29688 // that is to say, the padding bits are not in the same place as the array [N]iM.
29689 // If there's no padding, the bitcast is possible.
29690 const elem_bit_size = dest_elem_ty.bitSize(zcu);
29691 const elem_abi_byte_size = dest_elem_ty.abiSize(zcu);
29692 if (elem_abi_byte_size * 8 == elem_bit_size)
29693 return .ok;
29694 }
29695
2969629652 // Optionals
2969729653 if (dest_tag == .optional and src_tag == .optional) {
2969829654 if ((maybe_dest_ptr_ty != null) != (maybe_src_ptr_ty != null)) {