authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-24 13:51:47-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-02-24 13:51:47-05:00
log1d06c82c3bc44e808a3d7b4fe07e5c9fc492e8c3
treeed247bb05f5a9b5855d931054eb6cd9da4f9f950
parent5275b012020a7bb5de35120ca3e8f5d8d6ef2109
parent9c35f680f73538b8c36121ff938cc0b19eadbb42
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4516 from xackus/remove-bytes-to-slice

remove @bytesToSlice, @sliceToBytes from the language

28 files changed, 225 insertions(+), 589 deletions(-)

doc/langref.html.in+11-50
...@@ -2025,7 +2025,8 @@ test "volatile" {...@@ -2025,7 +2025,8 @@ test "volatile" {
2025 conversions are not possible.2025 conversions are not possible.
2026 </p>2026 </p>
2027 {#code_begin|test#}2027 {#code_begin|test#}
2028const assert = @import("std").debug.assert;2028const std = @import("std");
2029const assert = std.debug.assert;
20292030
2030test "pointer casting" {2031test "pointer casting" {
2031 const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 };2032 const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 };
...@@ -2034,7 +2035,7 @@ test "pointer casting" {...@@ -2034,7 +2035,7 @@ test "pointer casting" {
20342035
2035 // Even this example is contrived - there are better ways to do the above than2036 // Even this example is contrived - there are better ways to do the above than
2036 // pointer casting. For example, using a slice narrowing cast:2037 // pointer casting. For example, using a slice narrowing cast:
2037 const u32_value = @bytesToSlice(u32, bytes[0..])[0];2038 const u32_value = std.mem.bytesAsSlice(u32, bytes[0..])[0];
2038 assert(u32_value == 0x12121212);2039 assert(u32_value == 0x12121212);
20392040
2040 // And even another way, the most straightforward way to do it:2041 // And even another way, the most straightforward way to do it:
...@@ -2114,16 +2115,16 @@ test "function alignment" {...@@ -2114,16 +2115,16 @@ test "function alignment" {
2114 {#link|safety check|Incorrect Pointer Alignment#}:2115 {#link|safety check|Incorrect Pointer Alignment#}:
2115 </p>2116 </p>
2116 {#code_begin|test_safety|incorrect alignment#}2117 {#code_begin|test_safety|incorrect alignment#}
2117const assert = @import("std").debug.assert;2118const std = @import("std");
21182119
2119test "pointer alignment safety" {2120test "pointer alignment safety" {
2120 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };2121 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
2121 const bytes = @sliceToBytes(array[0..]);2122 const bytes = std.mem.sliceAsBytes(array[0..]);
2122 assert(foo(bytes) == 0x11111111);2123 std.debug.assert(foo(bytes) == 0x11111111);
2123}2124}
2124fn foo(bytes: []u8) u32 {2125fn foo(bytes: []u8) u32 {
2125 const slice4 = bytes[1..5];2126 const slice4 = bytes[1..5];
2126 const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));2127 const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
2127 return int_slice[0];2128 return int_slice[0];
2128}2129}
2129 {#code_end#}2130 {#code_end#}
...@@ -2249,7 +2250,7 @@ test "slice widening" {...@@ -2249,7 +2250,7 @@ test "slice widening" {
2249 // Zig supports slice widening and slice narrowing. Cast a slice of u82250 // Zig supports slice widening and slice narrowing. Cast a slice of u8
2250 // to a slice of anything else, and Zig will perform the length conversion.2251 // to a slice of anything else, and Zig will perform the length conversion.
2251 const array align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 };2252 const array align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 };
2252 const slice = @bytesToSlice(u32, array[0..]);2253 const slice = mem.bytesAsSlice(u32, array[0..]);
2253 assert(slice.len == 2);2254 assert(slice.len == 2);
2254 assert(slice[0] == 0x12121212);2255 assert(slice[0] == 0x12121212);
2255 assert(slice[1] == 0x13131313);2256 assert(slice[1] == 0x13131313);
...@@ -5186,7 +5187,6 @@ test "coercion of zero bit types" {...@@ -5186,7 +5187,6 @@ test "coercion of zero bit types" {
5186 <li>{#link|@bitCast#} - change type but maintain bit representation</li>5187 <li>{#link|@bitCast#} - change type but maintain bit representation</li>
5187 <li>{#link|@alignCast#} - make a pointer have more alignment</li>5188 <li>{#link|@alignCast#} - make a pointer have more alignment</li>
5188 <li>{#link|@boolToInt#} - convert true to 1 and false to 0</li>5189 <li>{#link|@boolToInt#} - convert true to 1 and false to 0</li>
5189 <li>{#link|@bytesToSlice#} - convert a slice of bytes to a slice of another type</li>
5190 <li>{#link|@enumToInt#} - obtain the integer tag value of an enum or tagged union</li>5190 <li>{#link|@enumToInt#} - obtain the integer tag value of an enum or tagged union</li>
5191 <li>{#link|@errSetCast#} - convert to a smaller error set</li>5191 <li>{#link|@errSetCast#} - convert to a smaller error set</li>
5192 <li>{#link|@errorToInt#} - obtain the integer value of an error code</li>5192 <li>{#link|@errorToInt#} - obtain the integer value of an error code</li>
...@@ -5199,7 +5199,6 @@ test "coercion of zero bit types" {...@@ -5199,7 +5199,6 @@ test "coercion of zero bit types" {
5199 <li>{#link|@intToPtr#} - convert an address to a pointer</li>5199 <li>{#link|@intToPtr#} - convert an address to a pointer</li>
5200 <li>{#link|@ptrCast#} - convert between pointer types</li>5200 <li>{#link|@ptrCast#} - convert between pointer types</li>
5201 <li>{#link|@ptrToInt#} - obtain the address of a pointer</li>5201 <li>{#link|@ptrToInt#} - obtain the address of a pointer</li>
5202 <li>{#link|@sliceToBytes#} - convert a slice of anything to a slice of bytes</li>
5203 <li>{#link|@truncate#} - convert between integer types, chopping off bits</li>5202 <li>{#link|@truncate#} - convert between integer types, chopping off bits</li>
5204 </ul>5203 </ul>
5205 {#header_close#}5204 {#header_close#}
...@@ -6929,18 +6928,6 @@ async fn func(y: *i32) void {...@@ -6929,18 +6928,6 @@ async fn func(y: *i32) void {
6929 {#see_also|@bitOffsetOf#}6928 {#see_also|@bitOffsetOf#}
6930 {#header_close#}6929 {#header_close#}
69316930
6932 {#header_open|@bytesToSlice#}
6933 <pre>{#syntax#}@bytesToSlice(comptime Element: type, bytes: []u8) []Element{#endsyntax#}</pre>
6934 <p>
6935 Converts a slice of bytes or array of bytes into a slice of {#syntax#}Element{#endsyntax#}.
6936 The resulting slice has the same {#link|pointer|Pointers#} properties as the parameter.
6937 </p>
6938 <p>
6939 Attempting to convert a number of bytes with a length that does not evenly divide into a slice of
6940 elements results in safety-protected {#link|Undefined Behavior#}.
6941 </p>
6942 {#header_close#}
6943
6944 {#header_open|@call#}6931 {#header_open|@call#}
6945 <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre>6932 <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre>
6946 <p>6933 <p>
...@@ -8101,14 +8088,6 @@ test "@setRuntimeSafety" {...@@ -8101,14 +8088,6 @@ test "@setRuntimeSafety" {
8101 {#see_also|@bitSizeOf|@typeInfo#}8088 {#see_also|@bitSizeOf|@typeInfo#}
8102 {#header_close#}8089 {#header_close#}
81038090
8104 {#header_open|@sliceToBytes#}
8105 <pre>{#syntax#}@sliceToBytes(value: var) []u8{#endsyntax#}</pre>
8106 <p>
8107 Converts a slice or array to a slice of {#syntax#}u8{#endsyntax#}. The resulting slice has the same
8108 {#link|pointer|Pointers#} properties as the parameter.
8109 </p>
8110 {#header_close#}
8111
8112 {#header_open|@splat#}8091 {#header_open|@splat#}
8113 <pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre>8092 <pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre>
8114 <p>8093 <p>
...@@ -8919,25 +8898,6 @@ pub fn main() void {...@@ -8919,25 +8898,6 @@ pub fn main() void {
8919 var b: u32 = 3;8898 var b: u32 = 3;
8920 var c = @divExact(a, b);8899 var c = @divExact(a, b);
8921 std.debug.warn("value: {}\n", .{c});8900 std.debug.warn("value: {}\n", .{c});
8922}
8923 {#code_end#}
8924 {#header_close#}
8925 {#header_open|Slice Widen Remainder#}
8926 <p>At compile-time:</p>
8927 {#code_begin|test_err|unable to convert#}
8928comptime {
8929 var bytes = [5]u8{ 1, 2, 3, 4, 5 };
8930 var slice = @bytesToSlice(u32, bytes[0..]);
8931}
8932 {#code_end#}
8933 <p>At runtime:</p>
8934 {#code_begin|exe_err#}
8935const std = @import("std");
8936
8937pub fn main() void {
8938 var bytes = [5]u8{ 1, 2, 3, 4, 5 };
8939 var slice = @bytesToSlice(u32, bytes[0..]);
8940 std.debug.warn("value: {}\n", .{slice[0]});
8941}8901}
8942 {#code_end#}8902 {#code_end#}
8943 {#header_close#}8903 {#header_close#}
...@@ -9119,14 +9079,15 @@ comptime {...@@ -9119,14 +9079,15 @@ comptime {
9119 {#code_end#}9079 {#code_end#}
9120 <p>At runtime:</p>9080 <p>At runtime:</p>
9121 {#code_begin|exe_err#}9081 {#code_begin|exe_err#}
9082const mem = @import("std").mem;
9122pub fn main() !void {9083pub fn main() !void {
9123 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };9084 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
9124 const bytes = @sliceToBytes(array[0..]);9085 const bytes = mem.sliceAsBytes(array[0..]);
9125 if (foo(bytes) != 0x11111111) return error.Wrong;9086 if (foo(bytes) != 0x11111111) return error.Wrong;
9126}9087}
9127fn foo(bytes: []u8) u32 {9088fn foo(bytes: []u8) u32 {
9128 const slice4 = bytes[1..5];9089 const slice4 = bytes[1..5];
9129 const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));9090 const int_slice = mem.bytesAsSlice(u32, @alignCast(4, slice4));
9130 return int_slice[0];9091 return int_slice[0];
9131}9092}
9132 {#code_end#}9093 {#code_end#}
lib/std/crypto/gimli.zig+2-2
...@@ -24,11 +24,11 @@ pub const State = struct {...@@ -24,11 +24,11 @@ pub const State = struct {
24 const Self = @This();24 const Self = @This();
2525
26 pub fn toSlice(self: *Self) []u8 {26 pub fn toSlice(self: *Self) []u8 {
27 return @sliceToBytes(self.data[0..]);27 return mem.sliceAsBytes(self.data[0..]);
28 }28 }
2929
30 pub fn toSliceConst(self: *Self) []const u8 {30 pub fn toSliceConst(self: *Self) []const u8 {
31 return @sliceToBytes(self.data[0..]);31 return mem.sliceAsBytes(self.data[0..]);
32 }32 }
3333
34 pub fn permute(self: *Self) void {34 pub fn permute(self: *Self) void {
lib/std/cstr.zig+1-1
...@@ -72,7 +72,7 @@ pub const NullTerminated2DArray = struct {...@@ -72,7 +72,7 @@ pub const NullTerminated2DArray = struct {
72 errdefer allocator.free(buf);72 errdefer allocator.free(buf);
7373
74 var write_index = index_size;74 var write_index = index_size;
75 const index_buf = @bytesToSlice(?[*]u8, buf);75 const index_buf = mem.bytesAsSlice(?[*]u8, buf);
7676
77 var i: usize = 0;77 var i: usize = 0;
78 for (slices) |slice| {78 for (slices) |slice| {
lib/std/fifo.zig+4-4
...@@ -101,7 +101,7 @@ pub fn LinearFifo(...@@ -101,7 +101,7 @@ pub fn LinearFifo(
101 }101 }
102 }102 }
103 { // set unused area to undefined103 { // set unused area to undefined
104 const unused = @sliceToBytes(self.buf[self.count..]);104 const unused = mem.sliceAsBytes(self.buf[self.count..]);
105 @memset(unused.ptr, undefined, unused.len);105 @memset(unused.ptr, undefined, unused.len);
106 }106 }
107 }107 }
...@@ -166,12 +166,12 @@ pub fn LinearFifo(...@@ -166,12 +166,12 @@ pub fn LinearFifo(
166 { // set old range to undefined. Note: may be wrapped around166 { // set old range to undefined. Note: may be wrapped around
167 const slice = self.readableSliceMut(0);167 const slice = self.readableSliceMut(0);
168 if (slice.len >= count) {168 if (slice.len >= count) {
169 const unused = @sliceToBytes(slice[0..count]);169 const unused = mem.sliceAsBytes(slice[0..count]);
170 @memset(unused.ptr, undefined, unused.len);170 @memset(unused.ptr, undefined, unused.len);
171 } else {171 } else {
172 const unused = @sliceToBytes(slice[0..]);172 const unused = mem.sliceAsBytes(slice[0..]);
173 @memset(unused.ptr, undefined, unused.len);173 @memset(unused.ptr, undefined, unused.len);
174 const unused2 = @sliceToBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]);174 const unused2 = mem.sliceAsBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]);
175 @memset(unused2.ptr, undefined, unused2.len);175 @memset(unused2.ptr, undefined, unused2.len);
176 }176 }
177 }177 }
lib/std/fs/watch.zig+1-1
...@@ -26,7 +26,7 @@ fn eqlString(a: []const u16, b: []const u16) bool {...@@ -26,7 +26,7 @@ fn eqlString(a: []const u16, b: []const u16) bool {
26}26}
2727
28fn hashString(s: []const u16) u32 {28fn hashString(s: []const u16) u32 {
29 return @truncate(u32, std.hash.Wyhash.hash(0, @sliceToBytes(s)));29 return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceAsBytes(s)));
30}30}
3131
32const WatchEventError = error{32const WatchEventError = error{
lib/std/heap.zig+3-3
...@@ -283,14 +283,14 @@ const WasmPageAllocator = struct {...@@ -283,14 +283,14 @@ const WasmPageAllocator = struct {
283283
284 fn getBit(self: FreeBlock, idx: usize) PageStatus {284 fn getBit(self: FreeBlock, idx: usize) PageStatus {
285 const bit_offset = 0;285 const bit_offset = 0;
286 return @intToEnum(PageStatus, Io.get(@sliceToBytes(self.data), idx, bit_offset));286 return @intToEnum(PageStatus, Io.get(mem.sliceAsBytes(self.data), idx, bit_offset));
287 }287 }
288288
289 fn setBits(self: FreeBlock, start_idx: usize, len: usize, val: PageStatus) void {289 fn setBits(self: FreeBlock, start_idx: usize, len: usize, val: PageStatus) void {
290 const bit_offset = 0;290 const bit_offset = 0;
291 var i: usize = 0;291 var i: usize = 0;
292 while (i < len) : (i += 1) {292 while (i < len) : (i += 1) {
293 Io.set(@sliceToBytes(self.data), start_idx + i, bit_offset, @enumToInt(val));293 Io.set(mem.sliceAsBytes(self.data), start_idx + i, bit_offset, @enumToInt(val));
294 }294 }
295 }295 }
296296
...@@ -552,7 +552,7 @@ pub const ArenaAllocator = struct {...@@ -552,7 +552,7 @@ pub const ArenaAllocator = struct {
552 if (len >= actual_min_size) break;552 if (len >= actual_min_size) break;
553 }553 }
554 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);554 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
555 const buf_node_slice = @bytesToSlice(BufNode, buf[0..@sizeOf(BufNode)]);555 const buf_node_slice = mem.bytesAsSlice(BufNode, buf[0..@sizeOf(BufNode)]);
556 const buf_node = &buf_node_slice[0];556 const buf_node = &buf_node_slice[0];
557 buf_node.* = BufNode{557 buf_node.* = BufNode{
558 .data = buf,558 .data = buf,
lib/std/io/in_stream.zig+1-1
...@@ -235,7 +235,7 @@ pub fn InStream(comptime ReadError: type) type {...@@ -235,7 +235,7 @@ pub fn InStream(comptime ReadError: type) type {
235 // Only extern and packed structs have defined in-memory layout.235 // Only extern and packed structs have defined in-memory layout.
236 comptime assert(@typeInfo(T).Struct.layout != builtin.TypeInfo.ContainerLayout.Auto);236 comptime assert(@typeInfo(T).Struct.layout != builtin.TypeInfo.ContainerLayout.Auto);
237 var res: [1]T = undefined;237 var res: [1]T = undefined;
238 try self.readNoEof(@sliceToBytes(res[0..]));238 try self.readNoEof(mem.sliceAsBytes(res[0..]));
239 return res[0];239 return res[0];
240 }240 }
241241
lib/std/mem.zig+162-6
...@@ -132,7 +132,7 @@ pub const Allocator = struct {...@@ -132,7 +132,7 @@ pub const Allocator = struct {
132 // their own frame with @Frame(func).132 // their own frame with @Frame(func).
133 return @intToPtr([*]T, @ptrToInt(byte_slice.ptr))[0..n];133 return @intToPtr([*]T, @ptrToInt(byte_slice.ptr))[0..n];
134 } else {134 } else {
135 return @bytesToSlice(T, @alignCast(a, byte_slice));135 return mem.bytesAsSlice(T, @alignCast(a, byte_slice));
136 }136 }
137 }137 }
138138
...@@ -173,7 +173,7 @@ pub const Allocator = struct {...@@ -173,7 +173,7 @@ pub const Allocator = struct {
173 return @as([*]align(new_alignment) T, undefined)[0..0];173 return @as([*]align(new_alignment) T, undefined)[0..0];
174 }174 }
175175
176 const old_byte_slice = @sliceToBytes(old_mem);176 const old_byte_slice = mem.sliceAsBytes(old_mem);
177 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;177 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;
178 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure178 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
179 const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);179 const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
...@@ -181,7 +181,7 @@ pub const Allocator = struct {...@@ -181,7 +181,7 @@ pub const Allocator = struct {
181 if (new_n > old_mem.len) {181 if (new_n > old_mem.len) {
182 @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len);182 @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len);
183 }183 }
184 return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));184 return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice));
185 }185 }
186186
187 /// Prefer calling realloc to shrink if you can tolerate failure, such as187 /// Prefer calling realloc to shrink if you can tolerate failure, such as
...@@ -221,18 +221,18 @@ pub const Allocator = struct {...@@ -221,18 +221,18 @@ pub const Allocator = struct {
221 // new_n <= old_mem.len and the multiplication didn't overflow for that operation.221 // new_n <= old_mem.len and the multiplication didn't overflow for that operation.
222 const byte_count = @sizeOf(T) * new_n;222 const byte_count = @sizeOf(T) * new_n;
223223
224 const old_byte_slice = @sliceToBytes(old_mem);224 const old_byte_slice = mem.sliceAsBytes(old_mem);
225 @memset(old_byte_slice.ptr + byte_count, undefined, old_byte_slice.len - byte_count);225 @memset(old_byte_slice.ptr + byte_count, undefined, old_byte_slice.len - byte_count);
226 const byte_slice = self.shrinkFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);226 const byte_slice = self.shrinkFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
227 assert(byte_slice.len == byte_count);227 assert(byte_slice.len == byte_count);
228 return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));228 return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice));
229 }229 }
230230
231 /// Free an array allocated with `alloc`. To free a single item,231 /// Free an array allocated with `alloc`. To free a single item,
232 /// see `destroy`.232 /// see `destroy`.
233 pub fn free(self: *Allocator, memory: var) void {233 pub fn free(self: *Allocator, memory: var) void {
234 const Slice = @typeInfo(@TypeOf(memory)).Pointer;234 const Slice = @typeInfo(@TypeOf(memory)).Pointer;
235 const bytes = @sliceToBytes(memory);235 const bytes = mem.sliceAsBytes(memory);
236 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;236 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;
237 if (bytes_len == 0) return;237 if (bytes_len == 0) return;
238 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));238 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
...@@ -1486,6 +1486,162 @@ test "bytesToValue" {...@@ -1486,6 +1486,162 @@ test "bytesToValue" {
1486 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));1486 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
1487}1487}
14881488
1489//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1490fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type {
1491 if (!(trait.isSlice(bytesType) and meta.Child(bytesType) == u8) and !(trait.isPtrTo(.Array)(bytesType) and meta.Child(meta.Child(bytesType)) == u8)) {
1492 @compileError("expected []u8 or *[_]u8, passed " ++ @typeName(bytesType));
1493 }
1494
1495 if (trait.isPtrTo(.Array)(bytesType) and @typeInfo(meta.Child(bytesType)).Array.len % @sizeOf(T) != 0) {
1496 @compileError("number of bytes in " ++ @typeName(bytesType) ++ " is not divisible by size of " ++ @typeName(T));
1497 }
1498
1499 const alignment = meta.alignment(bytesType);
1500
1501 return if (trait.isConstPtr(bytesType)) []align(alignment) const T else []align(alignment) T;
1502}
1503
1504pub fn bytesAsSlice(comptime T: type, bytes: var) BytesAsSliceReturnType(T, @TypeOf(bytes)) {
1505 const bytesSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(bytes))) bytes[0..] else bytes;
1506
1507 // let's not give an undefined pointer to @ptrCast
1508 // it may be equal to zero and fail a null check
1509 if (bytesSlice.len == 0) {
1510 return &[0]T{};
1511 }
1512
1513 const bytesType = @TypeOf(bytesSlice);
1514 const alignment = comptime meta.alignment(bytesType);
1515
1516 const castTarget = if (comptime trait.isConstPtr(bytesType)) [*]align(alignment) const T else [*]align(alignment) T;
1517
1518 return @ptrCast(castTarget, bytesSlice.ptr)[0..@divExact(bytes.len, @sizeOf(T))];
1519}
1520
1521test "bytesAsSlice" {
1522 const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
1523 const slice = bytesAsSlice(u16, bytes[0..]);
1524 testing.expect(slice.len == 2);
1525 testing.expect(bigToNative(u16, slice[0]) == 0xDEAD);
1526 testing.expect(bigToNative(u16, slice[1]) == 0xBEEF);
1527}
1528
1529test "bytesAsSlice keeps pointer alignment" {
1530 var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 };
1531 const numbers = bytesAsSlice(u32, bytes[0..]);
1532 comptime testing.expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32);
1533}
1534
1535test "bytesAsSlice on a packed struct" {
1536 const F = packed struct {
1537 a: u8,
1538 };
1539
1540 var b = [1]u8{9};
1541 var f = bytesAsSlice(F, &b);
1542 testing.expect(f[0].a == 9);
1543}
1544
1545test "bytesAsSlice with specified alignment" {
1546 var bytes align(4) = [_]u8{
1547 0x33,
1548 0x33,
1549 0x33,
1550 0x33,
1551 };
1552 const slice: []u32 = std.mem.bytesAsSlice(u32, bytes[0..]);
1553 testing.expect(slice[0] == 0x33333333);
1554}
1555
1556//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1557fn SliceAsBytesReturnType(comptime sliceType: type) type {
1558 if (!trait.isSlice(sliceType) and !trait.isPtrTo(.Array)(sliceType)) {
1559 @compileError("expected []T or *[_]T, passed " ++ @typeName(sliceType));
1560 }
1561
1562 const alignment = meta.alignment(sliceType);
1563
1564 return if (trait.isConstPtr(sliceType)) []align(alignment) const u8 else []align(alignment) u8;
1565}
1566
1567pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
1568 const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice;
1569
1570 // let's not give an undefined pointer to @ptrCast
1571 // it may be equal to zero and fail a null check
1572 if (actualSlice.len == 0) {
1573 return &[0]u8{};
1574 }
1575
1576 const sliceType = @TypeOf(actualSlice);
1577 const alignment = comptime meta.alignment(sliceType);
1578
1579 const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8;
1580
1581 return @ptrCast(castTarget, actualSlice.ptr)[0 .. actualSlice.len * @sizeOf(comptime meta.Child(sliceType))];
1582}
1583
1584test "sliceAsBytes" {
1585 const bytes = [_]u16{ 0xDEAD, 0xBEEF };
1586 const slice = sliceAsBytes(bytes[0..]);
1587 testing.expect(slice.len == 4);
1588 testing.expect(eql(u8, slice, switch (builtin.endian) {
1589 .Big => "\xDE\xAD\xBE\xEF",
1590 .Little => "\xAD\xDE\xEF\xBE",
1591 }));
1592}
1593
1594test "sliceAsBytes packed struct at runtime and comptime" {
1595 const Foo = packed struct {
1596 a: u4,
1597 b: u4,
1598 };
1599 const S = struct {
1600 fn doTheTest() void {
1601 var foo: Foo = undefined;
1602 var slice = sliceAsBytes(@as(*[1]Foo, &foo)[0..1]);
1603 slice[0] = 0x13;
1604 switch (builtin.endian) {
1605 .Big => {
1606 testing.expect(foo.a == 0x1);
1607 testing.expect(foo.b == 0x3);
1608 },
1609 .Little => {
1610 testing.expect(foo.a == 0x3);
1611 testing.expect(foo.b == 0x1);
1612 },
1613 }
1614 }
1615 };
1616 S.doTheTest();
1617 comptime S.doTheTest();
1618}
1619
1620test "sliceAsBytes and bytesAsSlice back" {
1621 testing.expect(@sizeOf(i32) == 4);
1622
1623 var big_thing_array = [_]i32{ 1, 2, 3, 4 };
1624 const big_thing_slice: []i32 = big_thing_array[0..];
1625
1626 const bytes = sliceAsBytes(big_thing_slice);
1627 testing.expect(bytes.len == 4 * 4);
1628
1629 bytes[4] = 0;
1630 bytes[5] = 0;
1631 bytes[6] = 0;
1632 bytes[7] = 0;
1633 testing.expect(big_thing_slice[1] == 0);
1634
1635 const big_thing_again = bytesAsSlice(i32, bytes);
1636 testing.expect(big_thing_again[2] == 3);
1637
1638 big_thing_again[2] = -1;
1639 testing.expect(bytes[8] == math.maxInt(u8));
1640 testing.expect(bytes[9] == math.maxInt(u8));
1641 testing.expect(bytes[10] == math.maxInt(u8));
1642 testing.expect(bytes[11] == math.maxInt(u8));
1643}
1644
1489fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {1645fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
1490 if (trait.isConstPtr(T))1646 if (trait.isConstPtr(T))
1491 return *const [length]meta.Child(meta.Child(T));1647 return *const [length]meta.Child(meta.Child(T));
lib/std/meta/trait.zig+16
...@@ -135,6 +135,22 @@ test "std.meta.trait.isPtrTo" {...@@ -135,6 +135,22 @@ test "std.meta.trait.isPtrTo" {
135 testing.expect(!isPtrTo(.Struct)(**struct {}));135 testing.expect(!isPtrTo(.Struct)(**struct {}));
136}136}
137137
138pub fn isSliceOf(comptime id: builtin.TypeId) TraitFn {
139 const Closure = struct {
140 pub fn trait(comptime T: type) bool {
141 if (!comptime isSlice(T)) return false;
142 return id == @typeId(meta.Child(T));
143 }
144 };
145 return Closure.trait;
146}
147
148test "std.meta.trait.isSliceOf" {
149 testing.expect(!isSliceOf(.Struct)(struct {}));
150 testing.expect(isSliceOf(.Struct)([]struct {}));
151 testing.expect(!isSliceOf(.Struct)([][]struct {}));
152}
153
138///////////Strait trait Fns154///////////Strait trait Fns
139155
140//@TODO:156//@TODO:
lib/std/net.zig+2-2
...@@ -120,7 +120,7 @@ pub const Address = extern union {...@@ -120,7 +120,7 @@ pub const Address = extern union {
120 ip_slice[10] = 0xff;120 ip_slice[10] = 0xff;
121 ip_slice[11] = 0xff;121 ip_slice[11] = 0xff;
122122
123 const ptr = @sliceToBytes(@as(*const [1]u32, &addr)[0..]);123 const ptr = mem.sliceAsBytes(@as(*const [1]u32, &addr)[0..]);
124124
125 ip_slice[12] = ptr[0];125 ip_slice[12] = ptr[0];
126 ip_slice[13] = ptr[1];126 ip_slice[13] = ptr[1];
...@@ -164,7 +164,7 @@ pub const Address = extern union {...@@ -164,7 +164,7 @@ pub const Address = extern union {
164 .addr = undefined,164 .addr = undefined,
165 },165 },
166 };166 };
167 const out_ptr = @sliceToBytes(@as(*[1]u32, &result.in.addr)[0..]);167 const out_ptr = mem.sliceAsBytes(@as(*[1]u32, &result.in.addr)[0..]);
168168
169 var x: u8 = 0;169 var x: u8 = 0;
170 var index: u8 = 0;170 var index: u8 = 0;
lib/std/os.zig+1-1
...@@ -1852,7 +1852,7 @@ pub fn isCygwinPty(handle: fd_t) bool {...@@ -1852,7 +1852,7 @@ pub fn isCygwinPty(handle: fd_t) bool {
18521852
1853 const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);1853 const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);
1854 const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)];1854 const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)];
1855 const name_wide = @bytesToSlice(u16, name_bytes);1855 const name_wide = mem.bytesAsSlice(u16, name_bytes);
1856 return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or1856 return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or
1857 mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;1857 mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;
1858}1858}
lib/std/process.zig+1-1
...@@ -430,7 +430,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {...@@ -430,7 +430,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {
430 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);430 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
431 errdefer allocator.free(buf);431 errdefer allocator.free(buf);
432432
433 const result_slice_list = @bytesToSlice([]u8, buf[0..slice_list_bytes]);433 const result_slice_list = mem.bytesAsSlice([]u8, buf[0..slice_list_bytes]);
434 const result_contents = buf[slice_list_bytes..];434 const result_contents = buf[slice_list_bytes..];
435 mem.copy(u8, result_contents, contents_slice);435 mem.copy(u8, result_contents, contents_slice);
436436
lib/std/unicode.zig+6-6
...@@ -243,7 +243,7 @@ pub const Utf16LeIterator = struct {...@@ -243,7 +243,7 @@ pub const Utf16LeIterator = struct {
243243
244 pub fn init(s: []const u16) Utf16LeIterator {244 pub fn init(s: []const u16) Utf16LeIterator {
245 return Utf16LeIterator{245 return Utf16LeIterator{
246 .bytes = @sliceToBytes(s),246 .bytes = mem.sliceAsBytes(s),
247 .i = 0,247 .i = 0,
248 };248 };
249 }249 }
...@@ -496,7 +496,7 @@ pub fn utf16leToUtf8(utf8: []u8, utf16le: []const u16) !usize {...@@ -496,7 +496,7 @@ pub fn utf16leToUtf8(utf8: []u8, utf16le: []const u16) !usize {
496496
497test "utf16leToUtf8" {497test "utf16leToUtf8" {
498 var utf16le: [2]u16 = undefined;498 var utf16le: [2]u16 = undefined;
499 const utf16le_as_bytes = @sliceToBytes(utf16le[0..]);499 const utf16le_as_bytes = mem.sliceAsBytes(utf16le[0..]);
500500
501 {501 {
502 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');502 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');
...@@ -606,12 +606,12 @@ test "utf8ToUtf16Le" {...@@ -606,12 +606,12 @@ test "utf8ToUtf16Le" {
606 {606 {
607 const length = try utf8ToUtf16Le(utf16le[0..], "𐐷");607 const length = try utf8ToUtf16Le(utf16le[0..], "𐐷");
608 testing.expectEqual(@as(usize, 2), length);608 testing.expectEqual(@as(usize, 2), length);
609 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16le[0..]));609 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16le[0..]));
610 }610 }
611 {611 {
612 const length = try utf8ToUtf16Le(utf16le[0..], "\u{10FFFF}");612 const length = try utf8ToUtf16Le(utf16le[0..], "\u{10FFFF}");
613 testing.expectEqual(@as(usize, 2), length);613 testing.expectEqual(@as(usize, 2), length);
614 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16le[0..]));614 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16le[0..]));
615 }615 }
616}616}
617617
...@@ -619,13 +619,13 @@ test "utf8ToUtf16LeWithNull" {...@@ -619,13 +619,13 @@ test "utf8ToUtf16LeWithNull" {
619 {619 {
620 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "𐐷");620 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "𐐷");
621 defer testing.allocator.free(utf16);621 defer testing.allocator.free(utf16);
622 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16[0..]));622 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16[0..]));
623 testing.expect(utf16[2] == 0);623 testing.expect(utf16[2] == 0);
624 }624 }
625 {625 {
626 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "\u{10FFFF}");626 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "\u{10FFFF}");
627 defer testing.allocator.free(utf16);627 defer testing.allocator.free(utf16);
628 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16[0..]));628 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16[0..]));
629 testing.expect(utf16[2] == 0);629 testing.expect(utf16[2] == 0);
630 }630 }
631}631}
src/all_types.hpp-28
...@@ -1750,8 +1750,6 @@ enum BuiltinFnId {...@@ -1750,8 +1750,6 @@ enum BuiltinFnId {
1750 BuiltinFnIdIntCast,1750 BuiltinFnIdIntCast,
1751 BuiltinFnIdFloatCast,1751 BuiltinFnIdFloatCast,
1752 BuiltinFnIdErrSetCast,1752 BuiltinFnIdErrSetCast,
1753 BuiltinFnIdToBytes,
1754 BuiltinFnIdFromBytes,
1755 BuiltinFnIdIntToFloat,1753 BuiltinFnIdIntToFloat,
1756 BuiltinFnIdFloatToInt,1754 BuiltinFnIdFloatToInt,
1757 BuiltinFnIdBoolToInt,1755 BuiltinFnIdBoolToInt,
...@@ -1821,7 +1819,6 @@ enum PanicMsgId {...@@ -1821,7 +1819,6 @@ enum PanicMsgId {
1821 PanicMsgIdDivisionByZero,1819 PanicMsgIdDivisionByZero,
1822 PanicMsgIdRemainderDivisionByZero,1820 PanicMsgIdRemainderDivisionByZero,
1823 PanicMsgIdExactDivisionRemainder,1821 PanicMsgIdExactDivisionRemainder,
1824 PanicMsgIdSliceWidenRemainder,
1825 PanicMsgIdUnwrapOptionalFail,1822 PanicMsgIdUnwrapOptionalFail,
1826 PanicMsgIdInvalidErrorCode,1823 PanicMsgIdInvalidErrorCode,
1827 PanicMsgIdIncorrectAlignment,1824 PanicMsgIdIncorrectAlignment,
...@@ -2699,8 +2696,6 @@ enum IrInstSrcId {...@@ -2699,8 +2696,6 @@ enum IrInstSrcId {
2699 IrInstSrcIdSaveErrRetAddr,2696 IrInstSrcIdSaveErrRetAddr,
2700 IrInstSrcIdAddImplicitReturnType,2697 IrInstSrcIdAddImplicitReturnType,
2701 IrInstSrcIdErrSetCast,2698 IrInstSrcIdErrSetCast,
2702 IrInstSrcIdToBytes,
2703 IrInstSrcIdFromBytes,
2704 IrInstSrcIdCheckRuntimeScope,2699 IrInstSrcIdCheckRuntimeScope,
2705 IrInstSrcIdHasDecl,2700 IrInstSrcIdHasDecl,
2706 IrInstSrcIdUndeclaredIdent,2701 IrInstSrcIdUndeclaredIdent,
...@@ -2739,7 +2734,6 @@ enum IrInstGenId {...@@ -2739,7 +2734,6 @@ enum IrInstGenId {
2739 IrInstGenIdCall,2734 IrInstGenIdCall,
2740 IrInstGenIdReturn,2735 IrInstGenIdReturn,
2741 IrInstGenIdCast,2736 IrInstGenIdCast,
2742 IrInstGenIdResizeSlice,
2743 IrInstGenIdUnreachable,2737 IrInstGenIdUnreachable,
2744 IrInstGenIdAsm,2738 IrInstGenIdAsm,
2745 IrInstGenIdTestNonNull,2739 IrInstGenIdTestNonNull,
...@@ -3271,13 +3265,6 @@ struct IrInstGenCast {...@@ -3271,13 +3265,6 @@ struct IrInstGenCast {
3271 CastOp cast_op;3265 CastOp cast_op;
3272};3266};
32733267
3274struct IrInstGenResizeSlice {
3275 IrInstGen base;
3276
3277 IrInstGen *operand;
3278 IrInstGen *result_loc;
3279};
3280
3281struct IrInstSrcContainerInitList {3268struct IrInstSrcContainerInitList {
3282 IrInstSrc base;3269 IrInstSrc base;
32833270
...@@ -3629,21 +3616,6 @@ struct IrInstSrcErrSetCast {...@@ -3629,21 +3616,6 @@ struct IrInstSrcErrSetCast {
3629 IrInstSrc *target;3616 IrInstSrc *target;
3630};3617};
36313618
3632struct IrInstSrcToBytes {
3633 IrInstSrc base;
3634
3635 IrInstSrc *target;
3636 ResultLoc *result_loc;
3637};
3638
3639struct IrInstSrcFromBytes {
3640 IrInstSrc base;
3641
3642 IrInstSrc *dest_child_type;
3643 IrInstSrc *target;
3644 ResultLoc *result_loc;
3645};
3646
3647struct IrInstSrcIntToFloat {3619struct IrInstSrcIntToFloat {
3648 IrInstSrc base;3620 IrInstSrc base;
36493621
src/codegen.cpp-74
...@@ -972,8 +972,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {...@@ -972,8 +972,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
972 return buf_create_from_str("remainder division by zero or negative value");972 return buf_create_from_str("remainder division by zero or negative value");
973 case PanicMsgIdExactDivisionRemainder:973 case PanicMsgIdExactDivisionRemainder:
974 return buf_create_from_str("exact division produced remainder");974 return buf_create_from_str("exact division produced remainder");
975 case PanicMsgIdSliceWidenRemainder:
976 return buf_create_from_str("slice widening size mismatch");
977 case PanicMsgIdUnwrapOptionalFail:975 case PanicMsgIdUnwrapOptionalFail:
978 return buf_create_from_str("attempt to unwrap null");976 return buf_create_from_str("attempt to unwrap null");
979 case PanicMsgIdUnreachable:977 case PanicMsgIdUnreachable:
...@@ -3085,74 +3083,6 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in...@@ -3085,74 +3083,6 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in
3085 }3083 }
3086}3084}
30873085
3088static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executable,
3089 IrInstGenResizeSlice *instruction)
3090{
3091 ZigType *actual_type = instruction->operand->value->type;
3092 ZigType *wanted_type = instruction->base.value->type;
3093 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3094 assert(expr_val);
3095
3096 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3097 assert(wanted_type->id == ZigTypeIdStruct);
3098 assert(wanted_type->data.structure.special == StructSpecialSlice);
3099 assert(actual_type->id == ZigTypeIdStruct);
3100 assert(actual_type->data.structure.special == StructSpecialSlice);
3101
3102 ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry;
3103 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;
3104 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry;
3105 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
3106
3107
3108 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index;
3109 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index;
3110 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index;
3111 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index;
3112
3113 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");
3114 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
3115 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
3116 get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), "");
3117 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,
3118 (unsigned)wanted_ptr_index, "");
3119 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
3120
3121 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, "");
3122 LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, "");
3123 uint64_t src_size = type_size(g, actual_child_type);
3124 uint64_t dest_size = type_size(g, wanted_child_type);
3125
3126 LLVMValueRef new_len;
3127 if (dest_size == 1) {
3128 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, src_size, false);
3129 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
3130 } else if (src_size == 1) {
3131 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, dest_size, false);
3132 if (ir_want_runtime_safety(g, &instruction->base)) {
3133 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
3134 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
3135 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
3136 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk");
3137 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail");
3138 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
3139
3140 LLVMPositionBuilderAtEnd(g->builder, fail_block);
3141 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
3142
3143 LLVMPositionBuilderAtEnd(g->builder, ok_block);
3144 }
3145 new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, "");
3146 } else {
3147 zig_unreachable();
3148 }
3149
3150 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, "");
3151 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
3152
3153 return result_loc;
3154}
3155
3156static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,3086static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
3157 IrInstGenCast *cast_instruction)3087 IrInstGenCast *cast_instruction)
3158{3088{
...@@ -6485,8 +6415,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl...@@ -6485,8 +6415,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl
6485 return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction);6415 return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction);
6486 case IrInstGenIdAssertNonNull:6416 case IrInstGenIdAssertNonNull:
6487 return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction);6417 return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction);
6488 case IrInstGenIdResizeSlice:
6489 return ir_render_resize_slice(g, executable, (IrInstGenResizeSlice *)instruction);
6490 case IrInstGenIdPtrOfArrayToSlice:6418 case IrInstGenIdPtrOfArrayToSlice:
6491 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction);6419 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction);
6492 case IrInstGenIdSuspendBegin:6420 case IrInstGenIdSuspendBegin:
...@@ -8317,8 +8245,6 @@ static void define_builtin_fns(CodeGen *g) {...@@ -8317,8 +8245,6 @@ static void define_builtin_fns(CodeGen *g) {
8317 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);8245 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
8318 create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4);8246 create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4);
8319 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);8247 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
8320 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
8321 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
8322 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);8248 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
8323 create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2);8249 create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2);
8324 create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3);8250 create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3);
src/ir.cpp-256
...@@ -383,10 +383,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {...@@ -383,10 +383,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {
383 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));383 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));
384 case IrInstSrcIdErrSetCast:384 case IrInstSrcIdErrSetCast:
385 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));385 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));
386 case IrInstSrcIdFromBytes:
387 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFromBytes *>(inst));
388 case IrInstSrcIdToBytes:
389 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcToBytes *>(inst));
390 case IrInstSrcIdIntToFloat:386 case IrInstSrcIdIntToFloat:
391 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));387 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));
392 case IrInstSrcIdFloatToInt:388 case IrInstSrcIdFloatToInt:
...@@ -707,8 +703,6 @@ void destroy_instruction_gen(IrInstGen *inst) {...@@ -707,8 +703,6 @@ void destroy_instruction_gen(IrInstGen *inst) {
707 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst));703 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst));
708 case IrInstGenIdAssertNonNull:704 case IrInstGenIdAssertNonNull:
709 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst));705 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst));
710 case IrInstGenIdResizeSlice:
711 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResizeSlice *>(inst));
712 case IrInstGenIdAlloca:706 case IrInstGenIdAlloca:
713 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst));707 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst));
714 case IrInstGenIdSuspendBegin:708 case IrInstGenIdSuspendBegin:
...@@ -1563,14 +1557,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {...@@ -1563,14 +1557,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {
1563 return IrInstSrcIdErrSetCast;1557 return IrInstSrcIdErrSetCast;
1564}1558}
15651559
1566static constexpr IrInstSrcId ir_inst_id(IrInstSrcToBytes *) {
1567 return IrInstSrcIdToBytes;
1568}
1569
1570static constexpr IrInstSrcId ir_inst_id(IrInstSrcFromBytes *) {
1571 return IrInstSrcIdFromBytes;
1572}
1573
1574static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {1560static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {
1575 return IrInstSrcIdCheckRuntimeScope;1561 return IrInstSrcIdCheckRuntimeScope;
1576}1562}
...@@ -1700,10 +1686,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {...@@ -1700,10 +1686,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {
1700 return IrInstGenIdCast;1686 return IrInstGenIdCast;
1701}1687}
17021688
1703static constexpr IrInstGenId ir_inst_id(IrInstGenResizeSlice *) {
1704 return IrInstGenIdResizeSlice;
1705}
1706
1707static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {1689static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {
1708 return IrInstGenIdUnreachable;1690 return IrInstGenIdUnreachable;
1709}1691}
...@@ -2759,21 +2741,6 @@ static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instructi...@@ -2759,21 +2741,6 @@ static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instructi
2759 return &inst->base;2741 return &inst->base;
2760}2742}
27612743
2762static IrInstGen *ir_build_resize_slice(IrAnalyze *ira, IrInst *source_instruction,
2763 IrInstGen *operand, ZigType *ty, IrInstGen *result_loc)
2764{
2765 IrInstGenResizeSlice *instruction = ir_build_inst_gen<IrInstGenResizeSlice>(&ira->new_irb,
2766 source_instruction->scope, source_instruction->source_node);
2767 instruction->base.value->type = ty;
2768 instruction->operand = operand;
2769 instruction->result_loc = result_loc;
2770
2771 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block);
2772 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
2773
2774 return &instruction->base;
2775}
2776
2777static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2744static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2778 IrInstSrc *target, IrInstSrc *options)2745 IrInstSrc *target, IrInstSrc *options)
2779{2746{
...@@ -3540,32 +3507,6 @@ static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode...@@ -3540,32 +3507,6 @@ static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode
3540 return &instruction->base;3507 return &instruction->base;
3541}3508}
35423509
3543static IrInstSrc *ir_build_to_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target,
3544 ResultLoc *result_loc)
3545{
3546 IrInstSrcToBytes *instruction = ir_build_instruction<IrInstSrcToBytes>(irb, scope, source_node);
3547 instruction->target = target;
3548 instruction->result_loc = result_loc;
3549
3550 ir_ref_instruction(target, irb->current_basic_block);
3551
3552 return &instruction->base;
3553}
3554
3555static IrInstSrc *ir_build_from_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3556 IrInstSrc *dest_child_type, IrInstSrc *target, ResultLoc *result_loc)
3557{
3558 IrInstSrcFromBytes *instruction = ir_build_instruction<IrInstSrcFromBytes>(irb, scope, source_node);
3559 instruction->dest_child_type = dest_child_type;
3560 instruction->target = target;
3561 instruction->result_loc = result_loc;
3562
3563 ir_ref_instruction(dest_child_type, irb->current_basic_block);
3564 ir_ref_instruction(target, irb->current_basic_block);
3565
3566 return &instruction->base;
3567}
3568
3569static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,3510static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3570 IrInstSrc *dest_type, IrInstSrc *target)3511 IrInstSrc *dest_type, IrInstSrc *target)
3571{3512{
...@@ -6597,31 +6538,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -6597,31 +6538,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
6597 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);6538 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);
6598 return ir_lval_wrap(irb, scope, result, lval, result_loc);6539 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6599 }6540 }
6600 case BuiltinFnIdFromBytes:
6601 {
6602 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6603 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6604 if (arg0_value == irb->codegen->invalid_inst_src)
6605 return arg0_value;
6606
6607 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6608 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6609 if (arg1_value == irb->codegen->invalid_inst_src)
6610 return arg1_value;
6611
6612 IrInstSrc *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc);
6613 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6614 }
6615 case BuiltinFnIdToBytes:
6616 {
6617 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6618 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6619 if (arg0_value == irb->codegen->invalid_inst_src)
6620 return arg0_value;
6621
6622 IrInstSrc *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc);
6623 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6624 }
6625 case BuiltinFnIdIntToFloat:6541 case BuiltinFnIdIntToFloat:
6626 {6542 {
6627 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);6543 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -25489,171 +25405,6 @@ static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcE...@@ -25489,171 +25405,6 @@ static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcE
25489 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type);25405 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type);
25490}25406}
2549125407
25492static IrInstGen *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstSrcFromBytes *instruction) {
25493 Error err;
25494
25495 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child);
25496 if (type_is_invalid(dest_child_type))
25497 return ira->codegen->invalid_inst_gen;
25498
25499 IrInstGen *target = instruction->target->child;
25500 if (type_is_invalid(target->value->type))
25501 return ira->codegen->invalid_inst_gen;
25502
25503 bool src_ptr_const;
25504 bool src_ptr_volatile;
25505 uint32_t src_ptr_align;
25506 if (target->value->type->id == ZigTypeIdPointer) {
25507 src_ptr_const = target->value->type->data.pointer.is_const;
25508 src_ptr_volatile = target->value->type->data.pointer.is_volatile;
25509
25510 if ((err = resolve_ptr_align(ira, target->value->type, &src_ptr_align)))
25511 return ira->codegen->invalid_inst_gen;
25512 } else if (is_slice(target->value->type)) {
25513 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry;
25514 src_ptr_const = src_ptr_type->data.pointer.is_const;
25515 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile;
25516
25517 if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align)))
25518 return ira->codegen->invalid_inst_gen;
25519 } else {
25520 src_ptr_const = true;
25521 src_ptr_volatile = false;
25522
25523 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusAlignmentKnown)))
25524 return ira->codegen->invalid_inst_gen;
25525
25526 src_ptr_align = get_abi_alignment(ira->codegen, target->value->type);
25527 }
25528
25529 if (src_ptr_align != 0) {
25530 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusAlignmentKnown)))
25531 return ira->codegen->invalid_inst_gen;
25532 }
25533
25534 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type,
25535 src_ptr_const, src_ptr_volatile, PtrLenUnknown,
25536 src_ptr_align, 0, 0, false);
25537 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
25538
25539 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
25540 src_ptr_const, src_ptr_volatile, PtrLenUnknown,
25541 src_ptr_align, 0, 0, false);
25542 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr);
25543
25544 IrInstGen *casted_value = ir_implicit_cast2(ira, &instruction->target->base, target, u8_slice);
25545 if (type_is_invalid(casted_value->value->type))
25546 return ira->codegen->invalid_inst_gen;
25547
25548 bool have_known_len = false;
25549 uint64_t known_len;
25550
25551 if (instr_is_comptime(casted_value)) {
25552 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad);
25553 if (!val)
25554 return ira->codegen->invalid_inst_gen;
25555
25556 ZigValue *len_val = val->data.x_struct.fields[slice_len_index];
25557 if (value_is_comptime(len_val)) {
25558 known_len = bigint_as_u64(&len_val->data.x_bigint);
25559 have_known_len = true;
25560 }
25561 }
25562
25563 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
25564 dest_slice_type, nullptr, true, true);
25565 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) {
25566 return result_loc;
25567 }
25568
25569 if (target->value->type->id == ZigTypeIdPointer &&
25570 target->value->type->data.pointer.ptr_len == PtrLenSingle &&
25571 target->value->type->data.pointer.child_type->id == ZigTypeIdArray)
25572 {
25573 known_len = target->value->type->data.pointer.child_type->data.array.len;
25574 have_known_len = true;
25575 } else if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) {
25576 known_len = casted_value->value->data.rh_slice.len;
25577 have_known_len = true;
25578 }
25579
25580 if (have_known_len) {
25581 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown)))
25582 return ira->codegen->invalid_inst_gen;
25583 uint64_t child_type_size = type_size(ira->codegen, dest_child_type);
25584 uint64_t remainder = known_len % child_type_size;
25585 if (remainder != 0) {
25586 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,
25587 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch",
25588 known_len, buf_ptr(&dest_slice_type->name)));
25589 add_error_note(ira->codegen, msg, instruction->dest_child_type->base.source_node,
25590 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64,
25591 buf_ptr(&dest_child_type->name), child_type_size, remainder));
25592 return ira->codegen->invalid_inst_gen;
25593 }
25594 }
25595
25596 return ir_build_resize_slice(ira, &instruction->base.base, casted_value, dest_slice_type, result_loc);
25597}
25598
25599static IrInstGen *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstSrcToBytes *instruction) {
25600 Error err;
25601
25602 IrInstGen *target = instruction->target->child;
25603 if (type_is_invalid(target->value->type))
25604 return ira->codegen->invalid_inst_gen;
25605
25606 if (!is_slice(target->value->type)) {
25607 ir_add_error(ira, &instruction->target->base,
25608 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value->type->name)));
25609 return ira->codegen->invalid_inst_gen;
25610 }
25611
25612 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry;
25613
25614 uint32_t alignment;
25615 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment)))
25616 return ira->codegen->invalid_inst_gen;
25617
25618 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
25619 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown,
25620 alignment, 0, 0, false);
25621 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
25622
25623 if (instr_is_comptime(target)) {
25624 ZigValue *target_val = ir_resolve_const(ira, target, UndefBad);
25625 if (target_val == nullptr)
25626 return ira->codegen->invalid_inst_gen;
25627
25628 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_slice_type);
25629 result->value->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2);
25630
25631 ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index];
25632 ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index];
25633 copy_const_val(ira->codegen, ptr_val, target_ptr_val);
25634 ptr_val->type = dest_ptr_type;
25635
25636 ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index];
25637 len_val->special = ConstValSpecialStatic;
25638 len_val->type = ira->codegen->builtin_types.entry_usize;
25639 ZigValue *target_len_val = target_val->data.x_struct.fields[slice_len_index];
25640 ZigType *elem_type = src_ptr_type->data.pointer.child_type;
25641 BigInt elem_size_bigint;
25642 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type));
25643 bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint);
25644
25645 return result;
25646 }
25647
25648 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
25649 dest_slice_type, nullptr, true, true);
25650 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
25651 return result_loc;
25652 }
25653
25654 return ir_build_resize_slice(ira, &instruction->base.base, target, dest_slice_type, result_loc);
25655}
25656
25657static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {25408static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {
25658 Error err;25409 Error err;
2565925410
...@@ -29783,10 +29534,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc...@@ -29783,10 +29534,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
29783 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction);29534 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction);
29784 case IrInstSrcIdErrSetCast:29535 case IrInstSrcIdErrSetCast:
29785 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction);29536 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction);
29786 case IrInstSrcIdFromBytes:
29787 return ir_analyze_instruction_from_bytes(ira, (IrInstSrcFromBytes *)instruction);
29788 case IrInstSrcIdToBytes:
29789 return ir_analyze_instruction_to_bytes(ira, (IrInstSrcToBytes *)instruction);
29790 case IrInstSrcIdIntToFloat:29537 case IrInstSrcIdIntToFloat:
29791 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction);29538 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction);
29792 case IrInstSrcIdFloatToInt:29539 case IrInstSrcIdFloatToInt:
...@@ -30113,7 +29860,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {...@@ -30113,7 +29860,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {
30113 case IrInstGenIdCmpxchg:29860 case IrInstGenIdCmpxchg:
30114 case IrInstGenIdAssertZero:29861 case IrInstGenIdAssertZero:
30115 case IrInstGenIdAssertNonNull:29862 case IrInstGenIdAssertNonNull:
30116 case IrInstGenIdResizeSlice:
30117 case IrInstGenIdPtrOfArrayToSlice:29863 case IrInstGenIdPtrOfArrayToSlice:
30118 case IrInstGenIdSlice:29864 case IrInstGenIdSlice:
30119 case IrInstGenIdOptionalWrap:29865 case IrInstGenIdOptionalWrap:
...@@ -30339,8 +30085,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {...@@ -30339,8 +30085,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
30339 case IrInstSrcIdIntToFloat:30085 case IrInstSrcIdIntToFloat:
30340 case IrInstSrcIdFloatToInt:30086 case IrInstSrcIdFloatToInt:
30341 case IrInstSrcIdBoolToInt:30087 case IrInstSrcIdBoolToInt:
30342 case IrInstSrcIdFromBytes:
30343 case IrInstSrcIdToBytes:
30344 case IrInstSrcIdEnumToInt:30088 case IrInstSrcIdEnumToInt:
30345 case IrInstSrcIdHasDecl:30089 case IrInstSrcIdHasDecl:
30346 case IrInstSrcIdAlloca:30090 case IrInstSrcIdAlloca:
src/ir_print.cpp-36
...@@ -307,10 +307,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {...@@ -307,10 +307,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
307 return "SrcAddImplicitReturnType";307 return "SrcAddImplicitReturnType";
308 case IrInstSrcIdErrSetCast:308 case IrInstSrcIdErrSetCast:
309 return "SrcErrSetCast";309 return "SrcErrSetCast";
310 case IrInstSrcIdToBytes:
311 return "SrcToBytes";
312 case IrInstSrcIdFromBytes:
313 return "SrcFromBytes";
314 case IrInstSrcIdCheckRuntimeScope:310 case IrInstSrcIdCheckRuntimeScope:
315 return "SrcCheckRuntimeScope";311 return "SrcCheckRuntimeScope";
316 case IrInstSrcIdHasDecl:312 case IrInstSrcIdHasDecl:
...@@ -383,8 +379,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {...@@ -383,8 +379,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {
383 return "GenReturn";379 return "GenReturn";
384 case IrInstGenIdCast:380 case IrInstGenIdCast:
385 return "GenCast";381 return "GenCast";
386 case IrInstGenIdResizeSlice:
387 return "GenResizeSlice";
388 case IrInstGenIdUnreachable:382 case IrInstGenIdUnreachable:
389 return "GenUnreachable";383 return "GenUnreachable";
390 case IrInstGenIdAsm:384 case IrInstGenIdAsm:
...@@ -1644,20 +1638,6 @@ static void ir_print_err_set_cast(IrPrintSrc *irp, IrInstSrcErrSetCast *instruct...@@ -1644,20 +1638,6 @@ static void ir_print_err_set_cast(IrPrintSrc *irp, IrInstSrcErrSetCast *instruct
1644 fprintf(irp->f, ")");1638 fprintf(irp->f, ")");
1645}1639}
16461640
1647static void ir_print_from_bytes(IrPrintSrc *irp, IrInstSrcFromBytes *instruction) {
1648 fprintf(irp->f, "@bytesToSlice(");
1649 ir_print_other_inst_src(irp, instruction->dest_child_type);
1650 fprintf(irp->f, ", ");
1651 ir_print_other_inst_src(irp, instruction->target);
1652 fprintf(irp->f, ")");
1653}
1654
1655static void ir_print_to_bytes(IrPrintSrc *irp, IrInstSrcToBytes *instruction) {
1656 fprintf(irp->f, "@sliceToBytes(");
1657 ir_print_other_inst_src(irp, instruction->target);
1658 fprintf(irp->f, ")");
1659}
1660
1661static void ir_print_int_to_float(IrPrintSrc *irp, IrInstSrcIntToFloat *instruction) {1641static void ir_print_int_to_float(IrPrintSrc *irp, IrInstSrcIntToFloat *instruction) {
1662 fprintf(irp->f, "@intToFloat(");1642 fprintf(irp->f, "@intToFloat(");
1663 ir_print_other_inst_src(irp, instruction->dest_type);1643 ir_print_other_inst_src(irp, instruction->dest_type);
...@@ -2142,13 +2122,6 @@ static void ir_print_assert_non_null(IrPrintGen *irp, IrInstGenAssertNonNull *in...@@ -2142,13 +2122,6 @@ static void ir_print_assert_non_null(IrPrintGen *irp, IrInstGenAssertNonNull *in
2142 fprintf(irp->f, ")");2122 fprintf(irp->f, ")");
2143}2123}
21442124
2145static void ir_print_resize_slice(IrPrintGen *irp, IrInstGenResizeSlice *instruction) {
2146 fprintf(irp->f, "@resizeSlice(");
2147 ir_print_other_inst_gen(irp, instruction->operand);
2148 fprintf(irp->f, ")result=");
2149 ir_print_other_inst_gen(irp, instruction->result_loc);
2150}
2151
2152static void ir_print_alloca_src(IrPrintSrc *irp, IrInstSrcAlloca *instruction) {2125static void ir_print_alloca_src(IrPrintSrc *irp, IrInstSrcAlloca *instruction) {
2153 fprintf(irp->f, "Alloca(align=");2126 fprintf(irp->f, "Alloca(align=");
2154 ir_print_other_inst_src(irp, instruction->align);2127 ir_print_other_inst_src(irp, instruction->align);
...@@ -2793,12 +2766,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai...@@ -2793,12 +2766,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
2793 case IrInstSrcIdErrSetCast:2766 case IrInstSrcIdErrSetCast:
2794 ir_print_err_set_cast(irp, (IrInstSrcErrSetCast *)instruction);2767 ir_print_err_set_cast(irp, (IrInstSrcErrSetCast *)instruction);
2795 break;2768 break;
2796 case IrInstSrcIdFromBytes:
2797 ir_print_from_bytes(irp, (IrInstSrcFromBytes *)instruction);
2798 break;
2799 case IrInstSrcIdToBytes:
2800 ir_print_to_bytes(irp, (IrInstSrcToBytes *)instruction);
2801 break;
2802 case IrInstSrcIdIntToFloat:2769 case IrInstSrcIdIntToFloat:
2803 ir_print_int_to_float(irp, (IrInstSrcIntToFloat *)instruction);2770 ir_print_int_to_float(irp, (IrInstSrcIntToFloat *)instruction);
2804 break;2771 break;
...@@ -3273,9 +3240,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai...@@ -3273,9 +3240,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
3273 case IrInstGenIdAssertNonNull:3240 case IrInstGenIdAssertNonNull:
3274 ir_print_assert_non_null(irp, (IrInstGenAssertNonNull *)instruction);3241 ir_print_assert_non_null(irp, (IrInstGenAssertNonNull *)instruction);
3275 break;3242 break;
3276 case IrInstGenIdResizeSlice:
3277 ir_print_resize_slice(irp, (IrInstGenResizeSlice *)instruction);
3278 break;
3279 case IrInstGenIdAlloca:3243 case IrInstGenIdAlloca:
3280 ir_print_alloca_gen(irp, (IrInstGenAlloca *)instruction);3244 ir_print_alloca_gen(irp, (IrInstGenAlloca *)instruction);
3281 break;3245 break;
test/compile_errors.zig-10
...@@ -4745,16 +4745,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4745,16 +4745,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4745 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",4745 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
4746 });4746 });
47474747
4748 cases.add("convert fixed size array to slice with invalid size",
4749 \\export fn f() void {
4750 \\ var array: [5]u8 = undefined;
4751 \\ var foo = @bytesToSlice(u32, &array)[0];
4752 \\}
4753 , &[_][]const u8{
4754 "tmp.zig:3:15: error: unable to convert [5]u8 to []align(1) u32: size mismatch",
4755 "tmp.zig:3:29: note: u32 has size 4; remaining bytes: 1",
4756 });
4757
4758 cases.add("non-pure function returns type",4748 cases.add("non-pure function returns type",
4759 \\var a: u32 = 0;4749 \\var a: u32 = 0;
4760 \\pub fn List(comptime T: type) type {4750 \\pub fn List(comptime T: type) type {
test/runtime_safety.zig+9-7
...@@ -553,15 +553,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -553,15 +553,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
553 );553 );
554554
555 cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",555 cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",
556 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {556 \\const std = @import("std");
557 \\ @import("std").os.exit(126);557 \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
558 \\ std.os.exit(126);
558 \\}559 \\}
559 \\pub fn main() !void {560 \\pub fn main() !void {
560 \\ const x = widenSlice(&[_]u8{1, 2, 3, 4, 5});561 \\ const x = widenSlice(&[_]u8{1, 2, 3, 4, 5});
561 \\ if (x.len == 0) return error.Whatever;562 \\ if (x.len == 0) return error.Whatever;
562 \\}563 \\}
563 \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {564 \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
564 \\ return @bytesToSlice(i32, slice);565 \\ return std.mem.bytesAsSlice(i32, slice);
565 \\}566 \\}
566 );567 );
567568
...@@ -656,17 +657,18 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -656,17 +657,18 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
656 );657 );
657658
658 cases.addRuntimeSafety("@alignCast misaligned",659 cases.addRuntimeSafety("@alignCast misaligned",
659 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {660 \\const std = @import("std");
660 \\ @import("std").os.exit(126);661 \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
662 \\ std.os.exit(126);
661 \\}663 \\}
662 \\pub fn main() !void {664 \\pub fn main() !void {
663 \\ var array align(4) = [_]u32{0x11111111, 0x11111111};665 \\ var array align(4) = [_]u32{0x11111111, 0x11111111};
664 \\ const bytes = @sliceToBytes(array[0..]);666 \\ const bytes = std.mem.sliceAsBytes(array[0..]);
665 \\ if (foo(bytes) != 0x11111111) return error.Wrong;667 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
666 \\}668 \\}
667 \\fn foo(bytes: []u8) u32 {669 \\fn foo(bytes: []u8) u32 {
668 \\ const slice4 = bytes[1..5];670 \\ const slice4 = bytes[1..5];
669 \\ const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));671 \\ const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
670 \\ return int_slice[0];672 \\ return int_slice[0];
671 \\}673 \\}
672 );674 );
test/stage1/behavior.zig-1
...@@ -93,7 +93,6 @@ comptime {...@@ -93,7 +93,6 @@ comptime {
93 _ = @import("behavior/shuffle.zig");93 _ = @import("behavior/shuffle.zig");
94 _ = @import("behavior/sizeof_and_typeof.zig");94 _ = @import("behavior/sizeof_and_typeof.zig");
95 _ = @import("behavior/slice.zig");95 _ = @import("behavior/slice.zig");
96 _ = @import("behavior/slicetobytes.zig");
97 _ = @import("behavior/struct.zig");96 _ = @import("behavior/struct.zig");
98 _ = @import("behavior/struct_contains_null_ptr_itself.zig");97 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
99 _ = @import("behavior/struct_contains_slice_of_itself.zig");98 _ = @import("behavior/struct_contains_slice_of_itself.zig");
test/stage1/behavior/align.zig-14
...@@ -81,20 +81,6 @@ fn testBytesAlign(b: u8) void {...@@ -81,20 +81,6 @@ fn testBytesAlign(b: u8) void {
81 expect(ptr.* == 0x33333333);81 expect(ptr.* == 0x33333333);
82}82}
8383
84test "specifying alignment allows slice cast" {
85 testBytesAlignSlice(0x33);
86}
87fn testBytesAlignSlice(b: u8) void {
88 var bytes align(4) = [_]u8{
89 b,
90 b,
91 b,
92 b,
93 };
94 const slice: []u32 = @bytesToSlice(u32, bytes[0..]);
95 expect(slice[0] == 0x33333333);
96}
97
98test "@alignCast pointers" {84test "@alignCast pointers" {
99 var x: u32 align(4) = 1;85 var x: u32 align(4) = 1;
100 expectsOnly1(&x);86 expectsOnly1(&x);
test/stage1/behavior/async_fn.zig+2-2
...@@ -334,7 +334,7 @@ test "async fn with inferred error set" {...@@ -334,7 +334,7 @@ test "async fn with inferred error set" {
334 var frame: [1]@Frame(middle) = undefined;334 var frame: [1]@Frame(middle) = undefined;
335 var fn_ptr = middle;335 var fn_ptr = middle;
336 var result: @TypeOf(fn_ptr).ReturnType.ErrorSet!void = undefined;336 var result: @TypeOf(fn_ptr).ReturnType.ErrorSet!void = undefined;
337 _ = @asyncCall(@sliceToBytes(frame[0..]), &result, fn_ptr);337 _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr);
338 resume global_frame;338 resume global_frame;
339 std.testing.expectError(error.Fail, result);339 std.testing.expectError(error.Fail, result);
340 }340 }
...@@ -954,7 +954,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {...@@ -954,7 +954,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {
954 fn doTheTest() void {954 fn doTheTest() void {
955 var frame: [1]@Frame(middle) = undefined;955 var frame: [1]@Frame(middle) = undefined;
956 var result: @TypeOf(middle).ReturnType.ErrorSet!void = undefined;956 var result: @TypeOf(middle).ReturnType.ErrorSet!void = undefined;
957 _ = @asyncCall(@sliceToBytes(frame[0..]), &result, middle);957 _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle);
958 resume global_frame;958 resume global_frame;
959 std.testing.expectError(error.Fail, result);959 std.testing.expectError(error.Fail, result);
960 }960 }
test/stage1/behavior/bugs/1851.zig+1-1
...@@ -13,7 +13,7 @@ test "allocation and looping over 3-byte integer" {...@@ -13,7 +13,7 @@ test "allocation and looping over 3-byte integer" {
13 x[0] = 0xFFFFFF;13 x[0] = 0xFFFFFF;
14 x[1] = 0xFFFFFF;14 x[1] = 0xFFFFFF;
1515
16 const bytes = @sliceToBytes(x);16 const bytes = std.mem.sliceAsBytes(x);
17 expect(@TypeOf(bytes) == []align(4) u8);17 expect(@TypeOf(bytes) == []align(4) u8);
18 expect(bytes.len == 8);18 expect(bytes.len == 8);
1919
test/stage1/behavior/cast.zig-20
...@@ -304,20 +304,6 @@ fn cast128Float(x: u128) f128 {...@@ -304,20 +304,6 @@ fn cast128Float(x: u128) f128 {
304 return @bitCast(f128, x);304 return @bitCast(f128, x);
305}305}
306306
307test "const slice widen cast" {
308 const bytes align(4) = [_]u8{
309 0x12,
310 0x12,
311 0x12,
312 0x12,
313 };
314
315 const u32_value = @bytesToSlice(u32, bytes[0..])[0];
316 expect(u32_value == 0x12121212);
317
318 expect(@bitCast(u32, bytes) == 0x12121212);
319}
320
321test "single-item pointer of array to slice and to unknown length pointer" {307test "single-item pointer of array to slice and to unknown length pointer" {
322 testCastPtrOfArrayToSliceAndPtr();308 testCastPtrOfArrayToSliceAndPtr();
323 comptime testCastPtrOfArrayToSliceAndPtr();309 comptime testCastPtrOfArrayToSliceAndPtr();
...@@ -392,12 +378,6 @@ test "comptime_int @intToFloat" {...@@ -392,12 +378,6 @@ test "comptime_int @intToFloat" {
392 }378 }
393}379}
394380
395test "@bytesToSlice keeps pointer alignment" {
396 var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 };
397 const numbers = @bytesToSlice(u32, bytes[0..]);
398 comptime expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32);
399}
400
401test "@intCast i32 to u7" {381test "@intCast i32 to u7" {
402 var x: u128 = maxInt(u128);382 var x: u128 = maxInt(u128);
403 var y: i32 = 120;383 var y: i32 = 120;
test/stage1/behavior/eval.zig-10
...@@ -711,16 +711,6 @@ test "bit shift a u1" {...@@ -711,16 +711,6 @@ test "bit shift a u1" {
711 expect(y == 1);711 expect(y == 1);
712}712}
713713
714test "@bytesToslice on a packed struct" {
715 const F = packed struct {
716 a: u8,
717 };
718
719 var b = [1]u8{9};
720 var f = @bytesToSlice(F, &b);
721 expect(f[0].a == 9);
722}
723
724test "comptime pointer cast array and then slice" {714test "comptime pointer cast array and then slice" {
725 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };715 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
726716
test/stage1/behavior/misc.zig-21
...@@ -3,7 +3,6 @@ const expect = std.testing.expect;...@@ -3,7 +3,6 @@ const expect = std.testing.expect;
3const expectEqualSlices = std.testing.expectEqualSlices;3const expectEqualSlices = std.testing.expectEqualSlices;
4const mem = std.mem;4const mem = std.mem;
5const builtin = @import("builtin");5const builtin = @import("builtin");
6const maxInt = std.math.maxInt;
76
8// normal comment7// normal comment
98
...@@ -377,26 +376,6 @@ test "string concatenation" {...@@ -377,26 +376,6 @@ test "string concatenation" {
377 expect(b[len] == 0);376 expect(b[len] == 0);
378}377}
379378
380test "cast slice to u8 slice" {
381 expect(@sizeOf(i32) == 4);
382 var big_thing_array = [_]i32{ 1, 2, 3, 4 };
383 const big_thing_slice: []i32 = big_thing_array[0..];
384 const bytes = @sliceToBytes(big_thing_slice);
385 expect(bytes.len == 4 * 4);
386 bytes[4] = 0;
387 bytes[5] = 0;
388 bytes[6] = 0;
389 bytes[7] = 0;
390 expect(big_thing_slice[1] == 0);
391 const big_thing_again = @bytesToSlice(i32, bytes);
392 expect(big_thing_again[2] == 3);
393 big_thing_again[2] = -1;
394 expect(bytes[8] == maxInt(u8));
395 expect(bytes[9] == maxInt(u8));
396 expect(bytes[10] == maxInt(u8));
397 expect(bytes[11] == maxInt(u8));
398}
399
400test "pointer to void return type" {379test "pointer to void return type" {
401 testPointerToVoidReturnType() catch unreachable;380 testPointerToVoidReturnType() catch unreachable;
402}381}
test/stage1/behavior/slicetobytes.zig deleted-29
...@@ -1,29 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4
5test "@sliceToBytes packed struct at runtime and comptime" {
6 const Foo = packed struct {
7 a: u4,
8 b: u4,
9 };
10 const S = struct {
11 fn doTheTest() void {
12 var foo: Foo = undefined;
13 var slice = @sliceToBytes(@as(*[1]Foo, &foo)[0..1]);
14 slice[0] = 0x13;
15 switch (builtin.endian) {
16 builtin.Endian.Big => {
17 expect(foo.a == 0x1);
18 expect(foo.b == 0x3);
19 },
20 builtin.Endian.Little => {
21 expect(foo.a == 0x3);
22 expect(foo.b == 0x1);
23 },
24 }
25 }
26 };
27 S.doTheTest();
28 comptime S.doTheTest();
29}
test/stage1/behavior/struct.zig+2-2
...@@ -315,7 +315,7 @@ test "packed array 24bits" {...@@ -315,7 +315,7 @@ test "packed array 24bits" {
315315
316 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);316 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
317 bytes[bytes.len - 1] = 0xaa;317 bytes[bytes.len - 1] = 0xaa;
318 const ptr = &@bytesToSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];318 const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
319 expect(ptr.a == 0);319 expect(ptr.a == 0);
320 expect(ptr.b[0].field == 0);320 expect(ptr.b[0].field == 0);
321 expect(ptr.b[1].field == 0);321 expect(ptr.b[1].field == 0);
...@@ -364,7 +364,7 @@ test "aligned array of packed struct" {...@@ -364,7 +364,7 @@ test "aligned array of packed struct" {
364 }364 }
365365
366 var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);366 var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
367 const ptr = &@bytesToSlice(FooArrayOfAligned, bytes[0..bytes.len])[0];367 const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
368368
369 expect(ptr.a[0].a == 0xbb);369 expect(ptr.a[0].a == 0xbb);
370 expect(ptr.a[0].b == 0xbb);370 expect(ptr.a[0].b == 0xbb);