authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-06-14 11:20:16+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-06-24 10:20:56+01:00
log10c97c26d964ea70230341468e05fdea533a77a3
tree56d96f2d1298bc437aca6769e2127792d994de83
parent6d2c8349c53707f9eeee7554bd7717667718ce4d
signaturelock-open Commit is signed but in an unrecognized format.

std: update for new `@bitCast` semantics


16 files changed, 276 insertions(+), 218 deletions(-)

lib/std/Build/Configuration.zig+4-2
...@@ -3215,7 +3215,8 @@ pub const Storage = enum {...@@ -3215,7 +3215,8 @@ pub const Storage = enum {
3215 .@"extern" => {3215 .@"extern" => {
3216 const n = @divExact(@sizeOf(Field), @sizeOf(u32));3216 const n = @divExact(@sizeOf(Field), @sizeOf(u32));
3217 defer i.* += n;3217 defer i.* += n;
3218 return @bitCast(buffer[i.*..][0..n].*);3218 const ptr: *align(@alignOf(u32)) const Field = @ptrCast(buffer[i.*..][0..n]);
3219 return ptr.*;
3219 },3220 },
3220 },3221 },
3221 else => comptime unreachable,3222 else => comptime unreachable,
...@@ -3381,7 +3382,8 @@ pub const Storage = enum {...@@ -3381,7 +3382,8 @@ pub const Storage = enum {
3381 },3382 },
3382 .@"extern" => {3383 .@"extern" => {
3383 const n = @divExact(@sizeOf(Field), @sizeOf(u32));3384 const n = @divExact(@sizeOf(Field), @sizeOf(u32));
3384 buffer[i..][0..n].* = @bitCast(value);3385 const ptr: *align(@alignOf(Field)) const [n]u32 = @ptrCast(&value);
3386 buffer[i..][0..n].* = ptr.*;
3385 return n;3387 return n;
3386 },3388 },
3387 },3389 },
lib/std/Io/Threaded.zig+6-2
...@@ -14188,9 +14188,11 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so...@@ -14188,9 +14188,11 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so
14188}14188}
1418914189
14190fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {14190fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {
14191 // The network byte order address in `in.addr` is already the byte order we want.
14192 const addr_bytes: *const [4]u8 = @ptrCast(&in.addr);
14191 return .{14193 return .{
14192 .port = std.mem.bigToNative(u16, in.port),14194 .port = std.mem.bigToNative(u16, in.port),
14193 .bytes = @bitCast(in.addr),14195 .bytes = addr_bytes.*,
14194 };14196 };
14195}14197}
1419614198
...@@ -14204,9 +14206,11 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address {...@@ -14204,9 +14206,11 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address {
14204}14206}
1420514207
14206fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in {14208fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in {
14209 // The byte order of `a.bytes` is already equivalent to a network byte order address.
14210 const addr_raw: *align(1) const u32 = @ptrCast(&a.bytes);
14207 return .{14211 return .{
14208 .port = std.mem.nativeToBig(u16, a.port),14212 .port = std.mem.nativeToBig(u16, a.port),
14209 .addr = @bitCast(a.bytes),14213 .addr = addr_raw.*,
14210 };14214 };
14211}14215}
1421214216
lib/std/Io/net.zig+1-5
...@@ -592,11 +592,7 @@ pub const Ip6Address = struct {...@@ -592,11 +592,7 @@ pub const Ip6Address = struct {
592 if (remaining != 0) return .incomplete;592 if (remaining != 0) return .incomplete;
593 }593 }
594594
595 // Workaround that can be removed when this proposal is595 for (&parts) |*part| part.* = @byteSwap(part.*);
596 // implemented https://github.com/ziglang/zig/issues/19755
597 if ((comptime @import("builtin").cpu.arch.endian()) != .big) {
598 for (&parts) |*part| part.* = @byteSwap(part.*);
599 }
600596
601 return .{ .success = .{597 return .{ .success = .{
602 .bytes = @bitCast(parts),598 .bytes = @bitCast(parts),
lib/std/Random/RomuTrio.zig+2-2
...@@ -33,7 +33,7 @@ fn next(self: *RomuTrio) u64 {...@@ -33,7 +33,7 @@ fn next(self: *RomuTrio) u64 {
33}33}
3434
35pub fn seedWithBuf(self: *RomuTrio, buf: [24]u8) void {35pub fn seedWithBuf(self: *RomuTrio, buf: [24]u8) void {
36 const seed_buf = @as([3]u64, @bitCast(buf));36 const seed_buf: [3]u64 = @bitCast(buf);
37 self.x_state = seed_buf[0];37 self.x_state = seed_buf[0];
38 self.y_state = seed_buf[1];38 self.y_state = seed_buf[1];
39 self.z_state = seed_buf[2];39 self.z_state = seed_buf[2];
...@@ -121,7 +121,7 @@ test fill {...@@ -121,7 +121,7 @@ test fill {
121}121}
122122
123test "buf seeding test" {123test "buf seeding test" {
124 const buf0 = @as([24]u8, @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 }));124 const buf0: [24]u8 = @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 });
125 const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 };125 const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 };
126 var r = RomuTrio.init(0);126 var r = RomuTrio.init(0);
127 r.seedWithBuf(buf0);127 r.seedWithBuf(buf0);
lib/std/Random/Xoshiro256.zig+2-2
...@@ -46,12 +46,12 @@ pub fn jump(self: *Xoshiro256) void {...@@ -46,12 +46,12 @@ pub fn jump(self: *Xoshiro256) void {
4646
47 while (table != 0) : (table >>= 1) {47 while (table != 0) : (table >>= 1) {
48 if (@as(u1, @truncate(table)) != 0) {48 if (@as(u1, @truncate(table)) != 0) {
49 s ^= @as(u256, @bitCast(self.s));49 s ^= @bitCast(self.s);
50 }50 }
51 _ = self.next();51 _ = self.next();
52 }52 }
5353
54 self.s = @as([4]u64, @bitCast(s));54 self.s = @bitCast(s);
55}55}
5656
57pub fn seed(self: *Xoshiro256, init_s: u64) void {57pub fn seed(self: *Xoshiro256, init_s: u64) void {
lib/std/crypto/tls/Client.zig+5-5
...@@ -376,7 +376,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client...@@ -376,7 +376,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client
376 const nonce = nonce: {376 const nonce = nonce: {
377 const V = @Vector(P.AEAD.nonce_length, u8);377 const V = @Vector(P.AEAD.nonce_length, u8);
378 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);378 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);
379 const operand: V = pad ++ @as([8]u8, @bitCast(big(read_seq)));379 const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(read_seq)));
380 break :nonce @as(V, pv.server_handshake_iv) ^ operand;380 break :nonce @as(V, pv.server_handshake_iv) ^ operand;
381 };381 };
382 P.AEAD.decrypt(cleartext, ciphertext, auth_tag, record_header, nonce, pv.server_handshake_key) catch382 P.AEAD.decrypt(cleartext, ciphertext, auth_tag, record_header, nonce, pv.server_handshake_key) catch
...@@ -416,7 +416,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client...@@ -416,7 +416,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client
416 const nonce: [P.AEAD.nonce_length]u8 = nonce: {416 const nonce: [P.AEAD.nonce_length]u8 = nonce: {
417 const V = @Vector(P.AEAD.nonce_length, u8);417 const V = @Vector(P.AEAD.nonce_length, u8);
418 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);418 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);
419 const operand: V = pad ++ @as([8]u8, @bitCast(big(masked_read_seq)));419 const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(masked_read_seq)));
420 break :nonce @as(V, pv.app_cipher.server_write_IV ++ record_iv) ^ operand;420 break :nonce @as(V, pv.app_cipher.server_write_IV ++ record_iv) ^ operand;
421 };421 };
422 const ciphertext = record_decoder.slice(message_len);422 const ciphertext = record_decoder.slice(message_len);
...@@ -792,7 +792,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client...@@ -792,7 +792,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client
792 const nonce: [P.AEAD.nonce_length]u8 = nonce: {792 const nonce: [P.AEAD.nonce_length]u8 = nonce: {
793 const V = @Vector(P.AEAD.nonce_length, u8);793 const V = @Vector(P.AEAD.nonce_length, u8);
794 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);794 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);
795 const operand: V = pad ++ @as([8]u8, @bitCast(big(write_seq)));795 const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(write_seq)));
796 break :nonce @as(V, pv.app_cipher.client_write_IV ++ pv.app_cipher.client_salt) ^ operand;796 break :nonce @as(V, pv.app_cipher.client_write_IV ++ pv.app_cipher.client_salt) ^ operand;
797 };797 };
798 var client_verify_msg = .{@intFromEnum(tls.ContentType.handshake)} ++798 var client_verify_msg = .{@intFromEnum(tls.ContentType.handshake)} ++
...@@ -1105,7 +1105,7 @@ fn prepareCiphertextRecord(...@@ -1105,7 +1105,7 @@ fn prepareCiphertextRecord(
1105 const nonce: [P.AEAD.nonce_length]u8 = nonce: {1105 const nonce: [P.AEAD.nonce_length]u8 = nonce: {
1106 const V = @Vector(P.AEAD.nonce_length, u8);1106 const V = @Vector(P.AEAD.nonce_length, u8);
1107 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);1107 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);
1108 const operand: V = pad ++ @as([8]u8, @bitCast(big(c.write_seq)));1108 const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(c.write_seq)));
1109 break :nonce @as(V, pv.client_write_IV ++ pv.client_salt) ^ operand;1109 break :nonce @as(V, pv.client_write_IV ++ pv.client_salt) ^ operand;
1110 };1110 };
1111 record_iv.* = nonce[P.fixed_iv_length..].*;1111 record_iv.* = nonce[P.fixed_iv_length..].*;
...@@ -1214,7 +1214,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {...@@ -1214,7 +1214,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {
1214 const nonce: [P.AEAD.nonce_length]u8 = nonce: {1214 const nonce: [P.AEAD.nonce_length]u8 = nonce: {
1215 const V = @Vector(P.AEAD.nonce_length, u8);1215 const V = @Vector(P.AEAD.nonce_length, u8);
1216 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);1216 const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0);
1217 const operand: V = pad ++ @as([8]u8, @bitCast(big(masked_read_seq)));1217 const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(masked_read_seq)));
1218 break :nonce @as(V, pv.server_write_IV ++ record_iv) ^ operand;1218 break :nonce @as(V, pv.server_write_IV ++ record_iv) ^ operand;
1219 };1219 };
1220 const ciphertext = input.take(message_len) catch unreachable; // already peeked1220 const ciphertext = input.take(message_len) catch unreachable; // already peeked
lib/std/hash/xxhash.zig+65-56
...@@ -421,7 +421,18 @@ pub const XxHash32 = struct {...@@ -421,7 +421,18 @@ pub const XxHash32 = struct {
421};421};
422422
423pub const XxHash3 = struct {423pub const XxHash3 = struct {
424 const block_bytes = 64;
424 const Block = @Vector(8, u64);425 const Block = @Vector(8, u64);
426 const InputBlock = extern struct {
427 raw: [block_bytes]u8,
428 inline fn load(ptr: *const InputBlock) Block {
429 return @bitCast(ptr.raw);
430 }
431 inline fn store(ptr: *InputBlock, val: Block) void {
432 ptr.raw = @bitCast(val);
433 }
434 };
435
425 const default_secret: [192]u8 = .{436 const default_secret: [192]u8 = .{
426 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,437 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
427 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,438 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
...@@ -464,10 +475,6 @@ pub const XxHash3 = struct {...@@ -464,10 +475,6 @@ pub const XxHash3 = struct {
464 return wide[0] ^ wide[1];475 return wide[0] ^ wide[1];
465 }476 }
466477
467 inline fn swap(x: anytype) @TypeOf(x) {
468 return if (native_endian == .big) @byteSwap(x) else x;
469 }
470
471 inline fn disableAutoVectorization(x: anytype) void {478 inline fn disableAutoVectorization(x: anytype) void {
472 if (!@inComptime()) asm volatile (""479 if (!@inComptime()) asm volatile (""
473 :480 :
...@@ -476,20 +483,20 @@ pub const XxHash3 = struct {...@@ -476,20 +483,20 @@ pub const XxHash3 = struct {
476 }483 }
477484
478 inline fn mix16(seed: u64, input: []const u8, secret: []const u8) u64 {485 inline fn mix16(seed: u64, input: []const u8, secret: []const u8) u64 {
479 const blk: [4]u64 = @bitCast([_][16]u8{ input[0..16].*, secret[0..16].* });486 const blk: [4]u64 = @bitCast([2][16]u8{ input[0..16].*, secret[0..16].* });
480 disableAutoVectorization(seed);487 disableAutoVectorization(seed);
481488
482 return fold(489 return fold(
483 swap(blk[0]) ^ (swap(blk[2]) +% seed),490 blk[0] ^ (blk[2] +% seed),
484 swap(blk[1]) ^ (swap(blk[3]) -% seed),491 blk[1] ^ (blk[3] -% seed),
485 );492 );
486 }493 }
487494
488 const Accumulator = extern struct {495 const Accumulator = struct {
489 consumed: usize = 0,496 consumed: usize = 0,
490 seed: u64,497 seed: u64,
491 secret: [192]u8 = undefined,498 secret: [192]u8,
492 state: Block = Block{499 state: Block = .{
493 XxHash32.prime_3,500 XxHash32.prime_3,
494 XxHash64.prime_1,501 XxHash64.prime_1,
495 XxHash64.prime_2,502 XxHash64.prime_2,
...@@ -501,33 +508,35 @@ pub const XxHash3 = struct {...@@ -501,33 +508,35 @@ pub const XxHash3 = struct {
501 },508 },
502509
503 inline fn init(seed: u64) Accumulator {510 inline fn init(seed: u64) Accumulator {
504 var self = Accumulator{ .seed = seed };511 const seed_block: Block = .{
505 for (512 seed, @as(u64, 0) -% seed,
506 std.mem.bytesAsSlice(Block, &self.secret),513 seed, @as(u64, 0) -% seed,
507 std.mem.bytesAsSlice(Block, &default_secret),514 seed, @as(u64, 0) -% seed,
508 ) |*dst, src| {515 seed, @as(u64, 0) -% seed,
509 dst.* = swap(swap(src) +% Block{516 };
510 seed, @as(u64, 0) -% seed,517
511 seed, @as(u64, 0) -% seed,518 var secret: [192]u8 = undefined;
512 seed, @as(u64, 0) -% seed,519 const secret_blocks: []InputBlock = @ptrCast(&secret);
513 seed, @as(u64, 0) -% seed,520 const default_secret_blocks: []const InputBlock = @ptrCast(&default_secret);
514 });521 for (secret_blocks, default_secret_blocks) |*dst, *src| {
522 dst.store(src.load() +% seed_block);
515 }523 }
516 return self;524
525 return .{ .seed = seed, .secret = secret };
517 }526 }
518527
519 inline fn round(528 inline fn round(
520 noalias state: *Block,529 noalias state: *Block,
521 noalias input_block: *align(1) const Block,530 noalias input_block: *const InputBlock,
522 noalias secret_block: *align(1) const Block,531 noalias secret_block: *const InputBlock,
523 ) void {532 ) void {
524 const data = swap(input_block.*);533 const data = input_block.load();
525 const mixed = data ^ swap(secret_block.*);534 const mixed = data ^ secret_block.load();
526 state.* +%= (mixed & @as(Block, @splat(0xffffffff))) *% (mixed >> @splat(32));535 state.* +%= (mixed & @as(Block, @splat(0xffffffff))) *% (mixed >> @splat(32));
527 state.* +%= @shuffle(u64, data, undefined, [_]i32{ 1, 0, 3, 2, 5, 4, 7, 6 });536 state.* +%= @shuffle(u64, data, undefined, [_]i32{ 1, 0, 3, 2, 5, 4, 7, 6 });
528 }537 }
529538
530 fn accumulate(noalias self: *Accumulator, blocks: []align(1) const Block) void {539 fn accumulate(noalias self: *Accumulator, blocks: []const InputBlock) void {
531 const secret = std.mem.bytesAsSlice(u64, self.secret[self.consumed * 8 ..]);540 const secret = std.mem.bytesAsSlice(u64, self.secret[self.consumed * 8 ..]);
532 for (blocks, secret[0..blocks.len]) |*input_block, *secret_block| {541 for (blocks, secret[0..blocks.len]) |*input_block, *secret_block| {
533 @prefetch(@as([*]const u8, @ptrCast(input_block)) + 320, .{});542 @prefetch(@as([*]const u8, @ptrCast(input_block)) + 320, .{});
...@@ -536,14 +545,14 @@ pub const XxHash3 = struct {...@@ -536,14 +545,14 @@ pub const XxHash3 = struct {
536 }545 }
537546
538 fn scramble(self: *Accumulator) void {547 fn scramble(self: *Accumulator) void {
539 const secret_block: Block = @bitCast(self.secret[192 - @sizeOf(Block) .. 192].*);548 const secret_block: Block = @bitCast(self.secret[192 - block_bytes .. 192].*);
540 self.state ^= self.state >> @splat(47);549 self.state ^= self.state >> @splat(47);
541 self.state ^= swap(secret_block);550 self.state ^= secret_block;
542 self.state *%= @as(Block, @splat(XxHash32.prime_1));551 self.state *%= @as(Block, @splat(XxHash32.prime_1));
543 }552 }
544553
545 fn consume(noalias self: *Accumulator, input_blocks: []align(1) const Block) void {554 fn consume(noalias self: *Accumulator, input_blocks: []const InputBlock) void {
546 const blocks_per_scramble = 1024 / @sizeOf(Block);555 const blocks_per_scramble = 1024 / block_bytes;
547 std.debug.assert(self.consumed <= blocks_per_scramble);556 std.debug.assert(self.consumed <= blocks_per_scramble);
548557
549 var blocks = input_blocks;558 var blocks = input_blocks;
...@@ -561,12 +570,12 @@ pub const XxHash3 = struct {...@@ -561,12 +570,12 @@ pub const XxHash3 = struct {
561 self.consumed += blocks.len;570 self.consumed += blocks.len;
562 }571 }
563572
564 fn digest(noalias self: *Accumulator, total_len: u64, noalias last_block: *align(1) const Block) u64 {573 fn digest(noalias self: *Accumulator, total_len: u64, noalias last_block: *const InputBlock) u64 {
565 const secret_block = self.secret[192 - @sizeOf(Block) - 7 ..][0..@sizeOf(Block)];574 const secret_block = self.secret[192 - block_bytes - 7 ..][0..block_bytes];
566 round(&self.state, last_block, @ptrCast(secret_block));575 round(&self.state, last_block, @ptrCast(secret_block));
567576
568 const merge_block: Block = @bitCast(self.secret[11 .. 11 + @sizeOf(Block)].*);577 const merge_block: Block = @bitCast(self.secret[11 .. 11 + block_bytes].*);
569 self.state ^= swap(merge_block);578 self.state ^= merge_block;
570579
571 var result = XxHash64.prime_1 *% total_len;580 var result = XxHash64.prime_1 *% total_len;
572 inline for (0..4) |i| {581 inline for (0..4) |i| {
...@@ -588,7 +597,7 @@ pub const XxHash3 = struct {...@@ -588,7 +597,7 @@ pub const XxHash3 = struct {
588 if (input.len > 0) return hash3(seed, input, secret);597 if (input.len > 0) return hash3(seed, input, secret);
589598
590 const flip: [2]u64 = @bitCast(secret[56..72].*);599 const flip: [2]u64 = @bitCast(secret[56..72].*);
591 const key = swap(flip[0]) ^ swap(flip[1]);600 const key = flip[0] ^ flip[1];
592 return avalanche(.h64, seed ^ key);601 return avalanche(.h64, seed ^ key);
593 }602 }
594603
...@@ -604,8 +613,8 @@ pub const XxHash3 = struct {...@@ -604,8 +613,8 @@ pub const XxHash3 = struct {
604 input[input.len / 2],613 input[input.len / 2],
605 });614 });
606615
607 const key = @as(u64, swap(flip[0]) ^ swap(flip[1])) +% seed;616 const key = @as(u64, flip[0] ^ flip[1]) +% seed;
608 return avalanche(.h64, key ^ swap(blk));617 return avalanche(.h64, key ^ blk);
609 }618 }
610619
611 fn hash8(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 {620 fn hash8(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 {
...@@ -619,8 +628,8 @@ pub const XxHash3 = struct {...@@ -619,8 +628,8 @@ pub const XxHash3 = struct {
619 });628 });
620629
621 const mixed = seed ^ (@as(u64, @byteSwap(@as(u32, @truncate(seed)))) << 32);630 const mixed = seed ^ (@as(u64, @byteSwap(@as(u32, @truncate(seed)))) << 32);
622 const key = (swap(flip[0]) ^ swap(flip[1])) -% mixed;631 const key = (flip[0] ^ flip[1]) -% mixed;
623 const combined = (@as(u64, swap(blk[0])) << 32) +% swap(blk[1]);632 const combined = (@as(u64, blk[0]) << 32) +% blk[1];
624 return avalanche(.{ .rrmxmx = input.len }, key ^ combined);633 return avalanche(.{ .rrmxmx = input.len }, key ^ combined);
625 }634 }
626635
...@@ -634,8 +643,8 @@ pub const XxHash3 = struct {...@@ -634,8 +643,8 @@ pub const XxHash3 = struct {
634 input[input.len - 8 ..][0..8].*,643 input[input.len - 8 ..][0..8].*,
635 });644 });
636645
637 const lo = swap(blk[0]) ^ ((swap(flip[0]) ^ swap(flip[1])) +% seed);646 const lo = blk[0] ^ ((flip[0] ^ flip[1]) +% seed);
638 const hi = swap(blk[1]) ^ ((swap(flip[2]) ^ swap(flip[3])) -% seed);647 const hi = blk[1] ^ ((flip[2] ^ flip[3]) -% seed);
639 const combined = @as(u64, input.len) +% @byteSwap(lo) +% hi +% fold(lo, hi);648 const combined = @as(u64, input.len) +% @byteSwap(lo) +% hi +% fold(lo, hi);
640 return avalanche(.h3, combined);649 return avalanche(.h3, combined);
641 }650 }
...@@ -679,11 +688,11 @@ pub const XxHash3 = struct {...@@ -679,11 +688,11 @@ pub const XxHash3 = struct {
679 @branchHint(.unlikely);688 @branchHint(.unlikely);
680 std.debug.assert(input.len >= 240);689 std.debug.assert(input.len >= 240);
681690
682 const block_count = ((input.len - 1) / @sizeOf(Block)) * @sizeOf(Block);691 const block_count = ((input.len - 1) / block_bytes) * block_bytes;
683 const last_block = input[input.len - @sizeOf(Block) ..][0..@sizeOf(Block)];692 const last_block = input[input.len - block_bytes ..][0..block_bytes];
684693
685 var acc = Accumulator.init(seed);694 var acc = Accumulator.init(seed);
686 acc.consume(std.mem.bytesAsSlice(Block, input[0..block_count]));695 acc.consume(std.mem.bytesAsSlice(InputBlock, input[0..block_count]));
687 return acc.digest(input.len, @ptrCast(last_block));696 return acc.digest(input.len, @ptrCast(last_block));
688 }697 }
689698
...@@ -716,21 +725,21 @@ pub const XxHash3 = struct {...@@ -716,21 +725,21 @@ pub const XxHash3 = struct {
716 @memcpy(self.buffer[self.buffered..], consumable[0..remaining]);725 @memcpy(self.buffer[self.buffered..], consumable[0..remaining]);
717 consumable = consumable[remaining..];726 consumable = consumable[remaining..];
718727
719 self.accumulator.consume(std.mem.bytesAsSlice(Block, &self.buffer));728 self.accumulator.consume(std.mem.bytesAsSlice(InputBlock, &self.buffer));
720 self.buffered = 0;729 self.buffered = 0;
721 }730 }
722731
723 // The input isn't small enough to fit in the buffer. Consume it directly.732 // The input isn't small enough to fit in the buffer. Consume it directly.
724 if (consumable.len > self.buffer.len) {733 if (consumable.len > self.buffer.len) {
725 const block_count = ((consumable.len - 1) / @sizeOf(Block)) * @sizeOf(Block);734 const block_count = ((consumable.len - 1) / block_bytes) * block_bytes;
726 self.accumulator.consume(std.mem.bytesAsSlice(Block, consumable[0..block_count]));735 self.accumulator.consume(std.mem.bytesAsSlice(InputBlock, consumable[0..block_count]));
727 consumable = consumable[block_count..];736 consumable = consumable[block_count..];
728737
729 // In case we consume all remaining input, write the last block to end of the buffer738 // In case we consume all remaining input, write the last block to end of the buffer
730 // to populate the last_block_copy in final() similar to hashLong()'s last_block.739 // to populate the last_block_copy in final() similar to hashLong()'s last_block.
731 @memcpy(740 @memcpy(
732 self.buffer[self.buffer.len - @sizeOf(Block) .. self.buffer.len],741 self.buffer[self.buffer.len - block_bytes .. self.buffer.len],
733 (consumable.ptr - @sizeOf(Block))[0..@sizeOf(Block)],742 (consumable.ptr - block_bytes)[0..block_bytes],
734 );743 );
735 }744 }
736745
...@@ -751,16 +760,16 @@ pub const XxHash3 = struct {...@@ -751,16 +760,16 @@ pub const XxHash3 = struct {
751760
752 // Make a copy of the Accumulator state in case `self` needs to update() / be used later.761 // Make a copy of the Accumulator state in case `self` needs to update() / be used later.
753 var accumulator_copy = self.accumulator;762 var accumulator_copy = self.accumulator;
754 var last_block_copy: [@sizeOf(Block)]u8 = undefined;763 var last_block_copy: [block_bytes]u8 = undefined;
755764
756 // Digest the last block onthe Accumulator copy.765 // Digest the last block onthe Accumulator copy.
757 return accumulator_copy.digest(self.total_len, last_block: {766 return accumulator_copy.digest(self.total_len, last_block: {
758 if (self.buffered >= @sizeOf(Block)) {767 if (self.buffered >= block_bytes) {
759 const block_count = ((self.buffered - 1) / @sizeOf(Block)) * @sizeOf(Block);768 const block_count = ((self.buffered - 1) / block_bytes) * block_bytes;
760 accumulator_copy.consume(std.mem.bytesAsSlice(Block, self.buffer[0..block_count]));769 accumulator_copy.consume(std.mem.bytesAsSlice(InputBlock, self.buffer[0..block_count]));
761 break :last_block @ptrCast(self.buffer[self.buffered - @sizeOf(Block) ..][0..@sizeOf(Block)]);770 break :last_block @ptrCast(self.buffer[self.buffered - block_bytes ..][0..block_bytes]);
762 } else {771 } else {
763 const remaining = @sizeOf(Block) - self.buffered;772 const remaining = block_bytes - self.buffered;
764 @memcpy(last_block_copy[0..remaining], self.buffer[self.buffer.len - remaining ..][0..remaining]);773 @memcpy(last_block_copy[0..remaining], self.buffer[self.buffer.len - remaining ..][0..remaining]);
765 @memcpy(last_block_copy[remaining..][0..self.buffered], self.buffer[0..self.buffered]);774 @memcpy(last_block_copy[remaining..][0..self.buffered], self.buffer[0..self.buffered]);
766 break :last_block @ptrCast(&last_block_copy);775 break :last_block @ptrCast(&last_block_copy);
lib/std/hash_map.zig+2-2
...@@ -593,8 +593,8 @@ fn Custom(...@@ -593,8 +593,8 @@ fn Custom(
593 fingerprint: FingerPrint = free,593 fingerprint: FingerPrint = free,
594 used: u1 = 0,594 used: u1 = 0,
595595
596 const slot_free = @as(u8, @bitCast(Metadata{ .fingerprint = free }));596 const slot_free: u8 = @bitCast(Metadata{ .fingerprint = free });
597 const slot_tombstone = @as(u8, @bitCast(Metadata{ .fingerprint = tombstone }));597 const slot_tombstone: u8 = @bitCast(Metadata{ .fingerprint = tombstone });
598598
599 pub fn isUsed(self: Metadata) bool {599 pub fn isUsed(self: Metadata) bool {
600 return self.used == 1;600 return self.used == 1;
lib/std/http/HeadParser.zig+5-8
...@@ -116,11 +116,8 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize {...@@ -116,11 +116,8 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize {
116116
117 const chunk = bytes[index..][0..vector_len];117 const chunk = bytes[index..][0..vector_len];
118 const v: Vector = chunk.*;118 const v: Vector = chunk.*;
119 // depends on https://github.com/ziglang/zig/issues/19755119 const matches_r: BitVector = @bitCast(v == @as(Vector, @splat('\r')));
120 // const matches_r: BitVector = @bitCast(v == @as(Vector, @splat('\r')));120 const matches_n: BitVector = @bitCast(v == @as(Vector, @splat('\n')));
121 // const matches_n: BitVector = @bitCast(v == @as(Vector, @splat('\n')));
122 const matches_r: BitVector = @select(u1, v == @as(Vector, @splat('\r')), @as(Vector, @splat(1)), @as(Vector, @splat(0)));
123 const matches_n: BitVector = @select(u1, v == @as(Vector, @splat('\n')), @as(Vector, @splat(1)), @as(Vector, @splat(0)));
124 const matches_or: SizeVector = matches_r | matches_n;121 const matches_or: SizeVector = matches_r | matches_n;
125122
126 const matches = @reduce(.Add, matches_or);123 const matches = @reduce(.Add, matches_or);
...@@ -331,15 +328,15 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize {...@@ -331,15 +328,15 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize {
331}328}
332329
333inline fn int16(array: *const [2]u8) u16 {330inline fn int16(array: *const [2]u8) u16 {
334 return @bitCast(array.*);331 return std.mem.toNative(u16, @bitCast(array.*), .little);
335}332}
336333
337inline fn int24(array: *const [3]u8) u24 {334inline fn int24(array: *const [3]u8) u24 {
338 return @bitCast(array.*);335 return std.mem.toNative(u24, @bitCast(array.*), .little);
339}336}
340337
341inline fn int32(array: *const [4]u8) u32 {338inline fn int32(array: *const [4]u8) u32 {
342 return @bitCast(array.*);339 return std.mem.toNative(u32, @bitCast(array.*), .little);
343}340}
344341
345inline fn intShift(comptime T: type, x: anytype) T {342inline fn intShift(comptime T: type, x: anytype) T {
lib/std/http/Server.zig+10-5
...@@ -726,7 +726,7 @@ pub const WebSocket = struct {...@@ -726,7 +726,7 @@ pub const WebSocket = struct {
726 else => @intFromEnum(h1.payload_len),726 else => @intFromEnum(h1.payload_len),
727 };727 };
728 if (len > in.buffer.len) return error.MessageOversize;728 if (len > in.buffer.len) return error.MessageOversize;
729 const mask: u32 = @bitCast((try in.takeArray(4)).*);729 const mask: [4]u8 = (try in.takeArray(4)).*;
730 const payload = try in.take(len);730 const payload = try in.take(len);
731731
732 // Skip pongs.732 // Skip pongs.
...@@ -734,11 +734,16 @@ pub const WebSocket = struct {...@@ -734,11 +734,16 @@ pub const WebSocket = struct {
734734
735 // The last item may contain a partial word of unused data.735 // The last item may contain a partial word of unused data.
736 const floored_len = (payload.len / 4) * 4;736 const floored_len = (payload.len / 4) * 4;
737 const u32_payload: []align(1) u32 = @ptrCast(payload[0..floored_len]);737
738 for (u32_payload) |*elem| elem.* ^= mask;738 const payload_chunks: [][4]u8 = @ptrCast(payload[0..floored_len]);
739 const mask_bytes: []const u8 = @ptrCast(&mask);739 for (payload_chunks) |*chunk| {
740 for (payload[floored_len..], mask_bytes[0 .. payload.len - floored_len]) |*leftover, m|740 const mask_i: u32 = @bitCast(mask);
741 const chunk_i: u32 = @bitCast(chunk.*);
742 chunk.* = @bitCast(chunk_i ^ mask_i);
743 }
744 for (payload[floored_len..], mask[0 .. payload.len - floored_len]) |*leftover, m| {
741 leftover.* ^= m;745 leftover.* ^= m;
746 }
742747
743 return .{748 return .{
744 .opcode = h0.opcode,749 .opcode = h0.opcode,
lib/std/mem.zig+80-58
...@@ -1848,18 +1848,18 @@ pub fn readVarPackedInt(...@@ -1848,18 +1848,18 @@ pub fn readVarPackedInt(
1848 if (@bitSizeOf(T) <= 8) {1848 if (@bitSizeOf(T) <= 8) {
1849 // These are the same shifts/masks we perform below, but adds `@truncate`/`@intCast`1849 // These are the same shifts/masks we perform below, but adds `@truncate`/`@intCast`
1850 // where needed since int is smaller than a byte.1850 // where needed since int is smaller than a byte.
1851 const value = if (read_size == 1) b: {1851 const value: uN = if (read_size == 1) b: {
1852 break :b @as(uN, @truncate(read_bytes[0] >> bit_shift));1852 break :b @truncate(read_bytes[0] >> bit_shift);
1853 } else b: {1853 } else b: {
1854 const i: u1 = @intFromBool(endian == .big);1854 const i: u1 = @intFromBool(endian == .big);
1855 const head = @as(uN, @truncate(read_bytes[i] >> bit_shift));1855 const head: uN = @truncate(read_bytes[i] >> bit_shift);
1856 const tail_shift = @as(Log2N, @intCast(@as(u4, 8) - bit_shift));1856 const tail_shift: Log2N = @intCast(@as(u4, 8) - bit_shift);
1857 const tail = @as(uN, @truncate(read_bytes[1 - i]));1857 const tail: uN = @truncate(read_bytes[1 - i]);
1858 break :b (tail << tail_shift) | head;1858 break :b (tail << tail_shift) | head;
1859 };1859 };
1860 switch (signedness) {1860 switch (signedness) {
1861 .signed => return @as(T, @intCast((@as(iN, @bitCast(value)) << pad) >> pad)),1861 .signed => return @intCast((@as(iN, @bitCast(value)) << pad) >> pad),
1862 .unsigned => return @as(T, @intCast((@as(uN, @bitCast(value)) << pad) >> pad)),1862 .unsigned => return @intCast((value << pad) >> pad),
1863 }1863 }
1864 }1864 }
18651865
...@@ -1880,8 +1880,8 @@ pub fn readVarPackedInt(...@@ -1880,8 +1880,8 @@ pub fn readVarPackedInt(
1880 },1880 },
1881 }1881 }
1882 switch (signedness) {1882 switch (signedness) {
1883 .signed => return @as(T, @intCast((@as(iN, @bitCast(int)) << pad) >> pad)),1883 .signed => return @intCast((@as(iN, @bitCast(int)) << pad) >> pad),
1884 .unsigned => return @as(T, @intCast((@as(uN, @bitCast(int)) << pad) >> pad)),1884 .unsigned => return @intCast((int << pad) >> pad),
1885 }1885 }
1886}1886}
18871887
...@@ -1896,8 +1896,13 @@ test readVarPackedInt {...@@ -1896,8 +1896,13 @@ test readVarPackedInt {
1896/// The bit count of T must be evenly divisible by 8.1896/// The bit count of T must be evenly divisible by 8.
1897/// This function cannot fail and cannot cause undefined behavior.1897/// This function cannot fail and cannot cause undefined behavior.
1898pub inline fn readInt(comptime T: type, buffer: *const [@divExact(@typeInfo(T).int.bits, 8)]u8, endian: Endian) T {1898pub inline fn readInt(comptime T: type, buffer: *const [@divExact(@typeInfo(T).int.bits, 8)]u8, endian: Endian) T {
1899 const value: T = @bitCast(buffer.*);1899 // Zig's logical bit order aligns with a little-endian byte array, so when reading in big-endian
1900 return if (endian == native_endian) value else @byteSwap(value);1900 // we must `@byteSwap` the int after we `@bitCast` to it.
1901 const little_val: T = @bitCast(buffer.*);
1902 return switch (endian) {
1903 .little => little_val,
1904 .big => @byteSwap(little_val),
1905 };
1901}1906}
19021907
1903test readInt {1908test readInt {
...@@ -1940,13 +1945,15 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T...@@ -1940,13 +1945,15 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T
1940 // Read by loading a LoadInt, and then follow it up with a 1-byte read1945 // Read by loading a LoadInt, and then follow it up with a 1-byte read
1941 // of the tail if bit_offset pushed us over a byte boundary.1946 // of the tail if bit_offset pushed us over a byte boundary.
1942 const read_bytes = bytes[bit_offset / 8 ..];1947 const read_bytes = bytes[bit_offset / 8 ..];
1943 const val = @as(uN, @truncate(readInt(LoadInt, read_bytes[0..load_size], .little) >> bit_shift));1948 const val: uN = @truncate(readInt(LoadInt, read_bytes[0..load_size], .little) >> bit_shift);
1944 if (bit_shift > load_tail_bits) {1949 if (bit_shift > load_tail_bits) {
1945 const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits));1950 const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits));
1946 const tail_byte = read_bytes[load_size];1951 const tail_byte = read_bytes[load_size];
1947 const tail_truncated = if (bit_count < 8) @as(uN, @truncate(tail_byte)) else @as(uN, tail_byte);1952 const tail_truncated = if (bit_count < 8) @as(uN, @truncate(tail_byte)) else @as(uN, tail_byte);
1948 return @as(T, @bitCast(val | (tail_truncated << (@as(Log2N, @truncate(bit_count)) -% tail_bits))));1953 return @bitCast(val | (tail_truncated << (@as(Log2N, @truncate(bit_count)) -% tail_bits)));
1949 } else return @as(T, @bitCast(val));1954 } else {
1955 return @bitCast(val);
1956 }
1950}1957}
19511958
1952fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {1959fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {
...@@ -1972,8 +1979,10 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {...@@ -1972,8 +1979,10 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {
1972 if (bit_shift > load_tail_bits) {1979 if (bit_shift > load_tail_bits) {
1973 const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits));1980 const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits));
1974 const tail_byte = if (bit_count < 8) @as(uN, @truncate(read_bytes[0])) else @as(uN, read_bytes[0]);1981 const tail_byte = if (bit_count < 8) @as(uN, @truncate(read_bytes[0])) else @as(uN, read_bytes[0]);
1975 return @as(T, @bitCast(val | (tail_byte << (@as(Log2N, @truncate(bit_count)) -% tail_bits))));1982 return @bitCast(val | (tail_byte << (@as(Log2N, @truncate(bit_count)) -% tail_bits)));
1976 } else return @as(T, @bitCast(val));1983 } else {
1984 return @bitCast(val);
1985 }
1977}1986}
19781987
1979/// Loads an integer from packed memory.1988/// Loads an integer from packed memory.
...@@ -2011,7 +2020,12 @@ test "comptime read/write int" {...@@ -2011,7 +2020,12 @@ test "comptime read/write int" {
2011/// This function always succeeds, has defined behavior for all inputs, but2020/// This function always succeeds, has defined behavior for all inputs, but
2012/// the integer bit width must be divisible by 8.2021/// the integer bit width must be divisible by 8.
2013pub inline fn writeInt(comptime T: type, buffer: *[@divExact(@typeInfo(T).int.bits, 8)]u8, value: T, endian: Endian) void {2022pub inline fn writeInt(comptime T: type, buffer: *[@divExact(@typeInfo(T).int.bits, 8)]u8, value: T, endian: Endian) void {
2014 buffer.* = @bitCast(if (endian == native_endian) value else @byteSwap(value));2023 // Zig's logical bit order aligns with a little-endian byte array, so when writing in big-endian
2024 // we must `@byteSwap` the int before we `@bitCast` to an array.
2025 buffer.* = switch (endian) {
2026 .little => @bitCast(value),
2027 .big => @bitCast(@byteSwap(value)),
2028 };
2015}2029}
20162030
2017test writeInt {2031test writeInt {
...@@ -2209,10 +2223,10 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void {...@@ -2209,10 +2223,10 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void {
2209/// (Changing their endianness)2223/// (Changing their endianness)
2210pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *align(a.toByteUnits()) S) void {2224pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *align(a.toByteUnits()) S) void {
2211 switch (@typeInfo(S)) {2225 switch (@typeInfo(S)) {
2212 .@"struct" => |struct_info| {2226 .@"struct" => |@"struct"| {
2213 if (struct_info.backing_integer) |Int| {2227 if (@"struct".backing_integer) |Int| {
2214 ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*))));2228 ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*))));
2215 } else inline for (struct_info.field_types, struct_info.field_names, struct_info.field_attrs) |f_type, f_name, f_attr| {2229 } else inline for (@"struct".field_types, @"struct".field_names, @"struct".field_attrs) |f_type, f_name, f_attr| {
2216 switch (@typeInfo(f_type)) {2230 switch (@typeInfo(f_type)) {
2217 .@"struct" => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)),2231 .@"struct" => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)),
2218 .@"union", .array => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)),2232 .@"union", .array => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)),
...@@ -2220,8 +2234,8 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a...@@ -2220,8 +2234,8 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a
2220 @field(ptr, f_name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f_name))));2234 @field(ptr, f_name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f_name))));
2221 },2235 },
2222 .bool => {},2236 .bool => {},
2223 .float => |float_info| {2237 .float => |float| {
2224 @field(ptr, f_name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float_info.bits), @bitCast(@field(ptr, f_name)))));2238 @field(ptr, f_name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float.bits), @bitCast(@field(ptr, f_name)))));
2225 },2239 },
2226 else => {2240 else => {
2227 @field(ptr, f_name) = @byteSwap(@field(ptr, f_name));2241 @field(ptr, f_name) = @byteSwap(@field(ptr, f_name));
...@@ -2229,23 +2243,26 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a...@@ -2229,23 +2243,26 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a
2229 }2243 }
2230 }2244 }
2231 },2245 },
2232 .@"union" => |union_info| {2246 .@"union" => |@"union"| if (@"union".backing_integer) |Int| {
2233 if (union_info.tag_type != null) {2247 ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*))));
2234 @compileError("byteSwapAllFields expects an untagged union");2248 } else {
2249 if (@"union".layout != .@"extern") {
2250 @compileError("byteSwapAllFields expects a packed or extern union");
2235 }2251 }
22362252
2237 const first_size = @bitSizeOf(union_info.field_types[0]);2253 const first_size = @bitSizeOf(@"union".field_types[0]);
2238 inline for (union_info.field_types) |field_type| {2254 inline for (@"union".field_types) |field_type| {
2239 if (@bitSizeOf(field_type) != first_size) {2255 if (@bitSizeOf(field_type) != first_size) {
2240 @compileError("Unable to byte-swap unions with varying field sizes");2256 @compileError("Unable to byte-swap unions with varying field sizes");
2241 }2257 }
2242 }2258 }
22432259
2244 const BackingInt = @Int(.unsigned, @bitSizeOf(S));2260 const FieldInt = @Int(.unsigned, first_size);
2245 ptr.* = @bitCast(@byteSwap(@as(BackingInt, @bitCast(ptr.*))));2261 const field_ptr = &@field(ptr, @"union".field_names[0]);
2262 field_ptr.* = @bitCast(@byteSwap(@as(FieldInt, @bitCast(field_ptr.*))));
2246 },2263 },
2247 .array => |info| {2264 .array => |array| {
2248 byteSwapAllElements(info.child, ptr);2265 byteSwapAllElements(array.child, ptr);
2249 },2266 },
2250 else => {2267 else => {
2251 ptr.* = @byteSwap(ptr.*);2268 ptr.* = @byteSwap(ptr.*);
...@@ -2291,7 +2308,7 @@ test byteSwapAllFields {...@@ -2291,7 +2308,7 @@ test byteSwapAllFields {
2291 .f2 = 0x12345678,2308 .f2 = 0x12345678,
2292 .f3 = .{0x12},2309 .f3 = .{0x12},
2293 .f4 = true,2310 .f4 = true,
2294 .f5 = @as(f32, @bitCast(@as(u32, 0x4640e400))),2311 .f5 = @bitCast(@as(u32, 0x4640e400)),
2295 .f6 = .{ .f0 = 0x1234 },2312 .f6 = .{ .f0 = 0x1234 },
2296 };2313 };
2297 var k = K{2314 var k = K{
...@@ -2300,7 +2317,7 @@ test byteSwapAllFields {...@@ -2300,7 +2317,7 @@ test byteSwapAllFields {
2300 .f2 = 0x1234,2317 .f2 = 0x1234,
2301 .f3 = .{0x12},2318 .f3 = .{0x12},
2302 .f4 = false,2319 .f4 = false,
2303 .f5 = @as(f32, @bitCast(@as(u32, 0x45d42800))),2320 .f5 = @bitCast(@as(u32, 0x45d42800)),
2304 };2321 };
2305 var p: P = @bitCast(@as(u32, 0x01234567));2322 var p: P = @bitCast(@as(u32, 0x01234567));
2306 var a: A = A{2323 var a: A = A{
...@@ -2318,7 +2335,7 @@ test byteSwapAllFields {...@@ -2318,7 +2335,7 @@ test byteSwapAllFields {
2318 .f2 = 0x78563412,2335 .f2 = 0x78563412,
2319 .f3 = .{0x12},2336 .f3 = .{0x12},
2320 .f4 = true,2337 .f4 = true,
2321 .f5 = @as(f32, @bitCast(@as(u32, 0x00e44046))),2338 .f5 = @bitCast(@as(u32, 0x00e44046)),
2322 .f6 = .{ .f0 = 0x3412 },2339 .f6 = .{ .f0 = 0x3412 },
2323 }, s);2340 }, s);
2324 try std.testing.expectEqual(K{2341 try std.testing.expectEqual(K{
...@@ -2327,7 +2344,7 @@ test byteSwapAllFields {...@@ -2327,7 +2344,7 @@ test byteSwapAllFields {
2327 .f2 = 0x3412,2344 .f2 = 0x3412,
2328 .f3 = .{0x12},2345 .f3 = .{0x12},
2329 .f4 = false,2346 .f4 = false,
2330 .f5 = @as(f32, @bitCast(@as(u32, 0x0028d445))),2347 .f5 = @bitCast(@as(u32, 0x0028d445)),
2331 }, k);2348 }, k);
2332 try std.testing.expectEqual(@as(P, @bitCast(@as(u32, 0x67452301))), p);2349 try std.testing.expectEqual(@as(P, @bitCast(@as(u32, 0x67452301))), p);
2333 try std.testing.expectEqual(A{2350 try std.testing.expectEqual(A{
...@@ -2348,8 +2365,9 @@ pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void {...@@ -2348,8 +2365,9 @@ pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void {
2348 elem.* = @enumFromInt(@byteSwap(@intFromEnum(elem.*)));2365 elem.* = @enumFromInt(@byteSwap(@intFromEnum(elem.*)));
2349 },2366 },
2350 .bool => {},2367 .bool => {},
2351 .float => |float_info| {2368 .float => |float| {
2352 elem.* = @bitCast(@byteSwap(@as(@Int(.unsigned, float_info.bits), @bitCast(elem.*))));2369 const int_repr: @Int(.unsigned, float.bits) = @bitCast(elem.*);
2370 elem.* = @bitCast(@byteSwap(int_repr));
2353 },2371 },
2354 else => {2372 else => {
2355 elem.* = @byteSwap(elem.*);2373 elem.* = @byteSwap(elem.*);
...@@ -3870,25 +3888,29 @@ inline fn reverseVector(comptime N: usize, comptime T: type, a: []T) [N]T {...@@ -3870,25 +3888,29 @@ inline fn reverseVector(comptime N: usize, comptime T: type, a: []T) [N]T {
3870pub fn reverse(comptime T: type, items: []T) void {3888pub fn reverse(comptime T: type, items: []T) void {
3871 var i: usize = 0;3889 var i: usize = 0;
3872 const end = items.len / 2;3890 const end = items.len / 2;
3873 if (use_vectors and3891
3874 !@inComptime() and3892 vec: {
3875 @bitSizeOf(T) > 0 and3893 if (!use_vectors) break :vec;
3876 std.math.isPowerOfTwo(@bitSizeOf(T)))3894 if (@inComptime()) break :vec;
3877 {3895 switch (@typeInfo(T)) {
3878 if (std.simd.suggestVectorLength(T)) |simd_size| {3896 .int, .float => {},
3879 if (simd_size <= end) {3897 .pointer => |pointer| if (pointer.size == .slice) break :vec,
3880 const simd_end = end - (simd_size - 1);3898 else => break :vec,
3881 while (i < simd_end) : (i += simd_size) {3899 }
3882 const left_slice = items[i .. i + simd_size];3900 if (@bitSizeOf(T) == 0 or !comptime std.math.isPowerOfTwo(@bitSizeOf(T))) break :vec;
3883 const right_slice = items[items.len - i - simd_size .. items.len - i];3901 const simd_size = std.simd.suggestVectorLength(T) orelse break :vec;
38843902 if (simd_size > end) break :vec;
3885 const left_shuffled: [simd_size]T = reverseVector(simd_size, T, left_slice);3903
3886 const right_shuffled: [simd_size]T = reverseVector(simd_size, T, right_slice);3904 const simd_end = end - (simd_size - 1);
38873905 while (i < simd_end) : (i += simd_size) {
3888 @memcpy(right_slice, &left_shuffled);3906 const left_slice = items[i .. i + simd_size];
3889 @memcpy(left_slice, &right_shuffled);3907 const right_slice = items[items.len - i - simd_size .. items.len - i];
3890 }3908
3891 }3909 const left_shuffled: [simd_size]T = reverseVector(simd_size, T, left_slice);
3910 const right_shuffled: [simd_size]T = reverseVector(simd_size, T, right_slice);
3911
3912 @memcpy(right_slice, &left_shuffled);
3913 @memcpy(left_slice, &right_shuffled);
3892 }3914 }
3893 }3915 }
38943916
...@@ -5009,8 +5031,8 @@ test "read/write(Var)PackedInt" {...@@ -5009,8 +5031,8 @@ test "read/write(Var)PackedInt" {
5009 for ([_]PackedType{5031 for ([_]PackedType{
5010 ~@as(PackedType, 0), // all ones: -1 iN / maxInt uN5032 ~@as(PackedType, 0), // all ones: -1 iN / maxInt uN
5011 @as(PackedType, 0), // all zeros: 0 iN / 0 uN5033 @as(PackedType, 0), // all zeros: 0 iN / 0 uN
5012 @as(PackedType, @bitCast(@as(iPackedType, math.maxInt(iPackedType)))), // maxInt iN5034 @bitCast(@as(iPackedType, math.maxInt(iPackedType))), // maxInt iN
5013 @as(PackedType, @bitCast(@as(iPackedType, math.minInt(iPackedType)))), // maxInt iN5035 @bitCast(@as(iPackedType, math.minInt(iPackedType))), // maxInt iN
5014 random.int(PackedType), // random5036 random.int(PackedType), // random
5015 random.int(PackedType), // random5037 random.int(PackedType), // random
5016 }) |write_value| {5038 }) |write_value| {
lib/std/os/linux/IoUring/test.zig+24-8
...@@ -526,7 +526,9 @@ test "sendmsg/recvmsg" {...@@ -526,7 +526,9 @@ test "sendmsg/recvmsg" {
526526
527 var address_server: linux.sockaddr.in = .{527 var address_server: linux.sockaddr.in = .{
528 .port = 0,528 .port = 0,
529 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),529 .addr = @as(*align(1) const u32, @ptrCast(
530 &@as([4]u8, .{ 127, 0, 0, 1 }),
531 )).*,
530 };532 };
531533
532 const server = try socket(address_server.family, posix.SOCK.DGRAM, 0);534 const server = try socket(address_server.family, posix.SOCK.DGRAM, 0);
...@@ -1028,7 +1030,9 @@ test "shutdown" {...@@ -1028,7 +1030,9 @@ test "shutdown" {
10281030
1029 var address: linux.sockaddr.in = .{1031 var address: linux.sockaddr.in = .{
1030 .port = 0,1032 .port = 0,
1031 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),1033 .addr = @as(*align(1) const u32, @ptrCast(
1034 &@as([4]u8, .{ 127, 0, 0, 1 }),
1035 )).*,
1032 };1036 };
10331037
1034 // Socket bound, expect shutdown to work1038 // Socket bound, expect shutdown to work
...@@ -1740,7 +1744,9 @@ test "accept multishot" {...@@ -1740,7 +1744,9 @@ test "accept multishot" {
17401744
1741 var address: linux.sockaddr.in = .{1745 var address: linux.sockaddr.in = .{
1742 .port = 0,1746 .port = 0,
1743 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),1747 .addr = @as(*align(1) const u32, @ptrCast(
1748 &@as([4]u8, .{ 127, 0, 0, 1 }),
1749 )).*,
1744 };1750 };
1745 const listener_socket = try createListenerSocket(&address);1751 const listener_socket = try createListenerSocket(&address);
1746 defer _ = linux.close(listener_socket);1752 defer _ = linux.close(listener_socket);
...@@ -1842,7 +1848,9 @@ test "accept_direct" {...@@ -1842,7 +1848,9 @@ test "accept_direct" {
1842 defer ring.deinit();1848 defer ring.deinit();
1843 var address: linux.sockaddr.in = .{1849 var address: linux.sockaddr.in = .{
1844 .port = 0,1850 .port = 0,
1845 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),1851 .addr = @as(*align(1) const u32, @ptrCast(
1852 &@as([4]u8, .{ 127, 0, 0, 1 }),
1853 )).*,
1846 };1854 };
18471855
1848 // register direct file descriptors1856 // register direct file descriptors
...@@ -1931,7 +1939,9 @@ test "accept_multishot_direct" {...@@ -1931,7 +1939,9 @@ test "accept_multishot_direct" {
19311939
1932 var address: linux.sockaddr.in = .{1940 var address: linux.sockaddr.in = .{
1933 .port = 0,1941 .port = 0,
1934 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),1942 .addr = @as(*align(1) const u32, @ptrCast(
1943 &@as([4]u8, .{ 127, 0, 0, 1 }),
1944 )).*,
1935 };1945 };
19361946
1937 var registered_fds: [2]linux.fd_t = @splat(-1);1947 var registered_fds: [2]linux.fd_t = @splat(-1);
...@@ -2041,7 +2051,9 @@ test "socket_direct/socket_direct_alloc/close_direct" {...@@ -2041,7 +2051,9 @@ test "socket_direct/socket_direct_alloc/close_direct" {
2041 // use sockets from registered_fds in connect operation2051 // use sockets from registered_fds in connect operation
2042 var address: linux.sockaddr.in = .{2052 var address: linux.sockaddr.in = .{
2043 .port = 0,2053 .port = 0,
2044 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),2054 .addr = @as(*align(1) const u32, @ptrCast(
2055 &@as([4]u8, .{ 127, 0, 0, 1 }),
2056 )).*,
2045 };2057 };
2046 const listener_socket = try createListenerSocket(&address);2058 const listener_socket = try createListenerSocket(&address);
2047 defer _ = linux.close(listener_socket);2059 defer _ = linux.close(listener_socket);
...@@ -2426,7 +2438,9 @@ test "bind/listen/connect" {...@@ -2426,7 +2438,9 @@ test "bind/listen/connect" {
24262438
2427 var addr: linux.sockaddr.in = .{2439 var addr: linux.sockaddr.in = .{
2428 .port = 0,2440 .port = 0,
2429 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),2441 .addr = @as(*align(1) const u32, @ptrCast(
2442 &@as([4]u8, .{ 127, 0, 0, 1 }),
2443 )).*,
2430 };2444 };
2431 const proto: u32 = if (addr.family == linux.AF.UNIX) 0 else linux.IPPROTO.TCP;2445 const proto: u32 = if (addr.family == linux.AF.UNIX) 0 else linux.IPPROTO.TCP;
24322446
...@@ -2614,7 +2628,9 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness {...@@ -2614,7 +2628,9 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness {
2614 // Create a TCP server socket2628 // Create a TCP server socket
2615 var address: linux.sockaddr.in = .{2629 var address: linux.sockaddr.in = .{
2616 .port = 0,2630 .port = 0,
2617 .addr = @bitCast([4]u8{ 127, 0, 0, 1 }),2631 .addr = @as(*align(1) const u32, @ptrCast(
2632 &@as([4]u8, .{ 127, 0, 0, 1 }),
2633 )).*,
2618 };2634 };
2619 const listener_socket = try createListenerSocket(&address);2635 const listener_socket = try createListenerSocket(&address);
2620 errdefer _ = linux.close(listener_socket);2636 errdefer _ = linux.close(listener_socket);
lib/std/os/uefi.zig+1-1
...@@ -218,7 +218,7 @@ pub const TimeCapabilities = extern struct {...@@ -218,7 +218,7 @@ pub const TimeCapabilities = extern struct {
218pub const FileHandle = *opaque {};218pub const FileHandle = *opaque {};
219219
220test "GUID formatting" {220test "GUID formatting" {
221 const bytes = [_]u8{ 137, 60, 203, 50, 128, 128, 124, 66, 186, 19, 80, 73, 135, 59, 194, 135 };221 const bytes: [16]u8 = .{ 137, 60, 203, 50, 128, 128, 124, 66, 186, 19, 80, 73, 135, 59, 194, 135 };
222 const guid: Guid = @bitCast(bytes);222 const guid: Guid = @bitCast(bytes);
223223
224 const str = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{guid});224 const str = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{guid});
lib/std/os/windows.zig+37-36
...@@ -4189,19 +4189,11 @@ pub const GUID = extern struct {...@@ -4189,19 +4189,11 @@ pub const GUID = extern struct {
4189 Data3: u16,4189 Data3: u16,
4190 Data4: [8]u8,4190 Data4: [8]u8,
41914191
4192 const hex_offsets = switch (builtin.target.cpu.arch.endian()) {4192 const hex_offsets: [16]u6 = .{
4193 .big => [16]u6{4193 6, 4, 2, 0,
4194 0, 2, 4, 6,4194 11, 9, 16, 14,
4195 9, 11, 14, 16,4195 19, 21, 24, 26,
4196 19, 21, 24, 26,4196 28, 30, 32, 34,
4197 28, 30, 32, 34,
4198 },
4199 .little => [16]u6{
4200 6, 4, 2, 0,
4201 11, 9, 16, 14,
4202 19, 21, 24, 26,
4203 28, 30, 32, 34,
4204 },
4205 };4197 };
42064198
4207 pub fn parse(s: []const u8) GUID {4199 pub fn parse(s: []const u8) GUID {
...@@ -4216,12 +4208,21 @@ pub const GUID = extern struct {...@@ -4216,12 +4208,21 @@ pub const GUID = extern struct {
4216 assert(s[13] == '-');4208 assert(s[13] == '-');
4217 assert(s[18] == '-');4209 assert(s[18] == '-');
4218 assert(s[23] == '-');4210 assert(s[23] == '-');
4219 var bytes: [16]u8 = undefined;4211 var raw1: [4]u8 = undefined;
4220 for (hex_offsets, 0..) |hex_offset, i| {4212 var raw2: [2]u8 = undefined;
4221 bytes[i] = (try std.fmt.charToDigit(s[hex_offset], 16)) << 4 |4213 var raw3: [2]u8 = undefined;
4222 try std.fmt.charToDigit(s[hex_offset + 1], 16);4214 var raw4: [8]u8 = undefined;
4223 }4215 assert((try std.fmt.hexToBytes(&raw1, s[0..8])).len == raw1.len);
4224 return @as(GUID, @bitCast(bytes));4216 assert((try std.fmt.hexToBytes(&raw2, s[9..13])).len == raw2.len);
4217 assert((try std.fmt.hexToBytes(&raw3, s[14..18])).len == raw3.len);
4218 assert((try std.fmt.hexToBytes(raw4[0..2], s[19..23])).len == 2);
4219 assert((try std.fmt.hexToBytes(raw4[2..8], s[24..36])).len == 6);
4220 return .{
4221 .Data1 = @byteSwap(@as(u32, @bitCast(raw1))),
4222 .Data2 = @byteSwap(@as(u16, @bitCast(raw2))),
4223 .Data3 = @byteSwap(@as(u16, @bitCast(raw3))),
4224 .Data4 = raw4,
4225 };
4225 }4226 }
42264227
4227 pub fn format(self: GUID, w: *std.Io.Writer) std.Io.Writer.Error!void {4228 pub fn format(self: GUID, w: *std.Io.Writer) std.Io.Writer.Error!void {
...@@ -4233,28 +4234,28 @@ pub const GUID = extern struct {...@@ -4233,28 +4234,28 @@ pub const GUID = extern struct {
4233 self.Data4[2..8],4234 self.Data4[2..8],
4234 });4235 });
4235 }4236 }
4236};
42374237
4238test GUID {4238 test parse {
4239 try std.testing.expectEqual(4239 const expected: GUID = .{
4240 GUID{
4241 .Data1 = 0x01234567,4240 .Data1 = 0x01234567,
4242 .Data2 = 0x89ab,4241 .Data2 = 0x89ab,
4243 .Data3 = 0xef10,4242 .Data3 = 0xef10,
4244 .Data4 = "\x32\x54\x76\x98\xba\xdc\xfe\x91".*,4243 .Data4 = "\x32\x54\x76\x98\xba\xdc\xfe\x91".*,
4245 },4244 };
4246 GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}"),4245 try std.testing.expectEqual(expected, GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}"));
4247 );4246 }
4248 try std.testing.expectFmt(4247
4249 "{01234567-89ab-ef10-3254-7698badcfe91}",4248 test format {
4250 "{f}",4249 const guid0: GUID = .{ .Data1 = 1, .Data2 = 1, .Data3 = 1, .Data4 = .{ 0, 1, 0, 0, 0, 0, 0, 1 } };
4251 .{GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}")},4250 try std.testing.expectFmt("{00000001-0001-0001-0001-000000000001}", "{f}", .{guid0});
4252 );4251
4253 try std.testing.expectFmt(4252 const guid1: GUID = .parse("{01234567-89AB-EF10-3254-7698badcfe91}");
4254 "{00000001-0001-0001-0001-000000000001}",4253 try std.testing.expectFmt("{01234567-89ab-ef10-3254-7698badcfe91}", "{f}", .{guid1});
4255 "{f}",4254 }
4256 .{GUID{ .Data1 = 1, .Data2 = 1, .Data3 = 1, .Data4 = [_]u8{ 0, 1, 0, 0, 0, 0, 0, 1 } }},4255};
4257 );4256
4257test {
4258 _ = GUID;
4258}4259}
42594260
4260pub const COORD = extern struct {4261pub const COORD = extern struct {
lib/std/testing.zig+30-24
...@@ -141,39 +141,45 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {...@@ -141,39 +141,45 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {
141 try expectEqualSlices(info.child, &expect_array, &actual_array);141 try expectEqualSlices(info.child, &expect_array, &actual_array);
142 },142 },
143143
144 .@"struct" => |structType| {144 .@"struct" => |@"struct"| {
145 inline for (structType.field_names) |field_name| {145 inline for (@"struct".field_names) |field_name| {
146 try expectEqual(@field(expected, field_name), @field(actual, field_name));146 try expectEqual(@field(expected, field_name), @field(actual, field_name));
147 }147 }
148 },148 },
149149
150 .@"union" => |union_info| {150 .@"union" => |@"union"| if (@"union".backing_integer) |Int| {
151 if (union_info.tag_type == null) {151 try expectEqual(@as(Int, @bitCast(expected)), @as(Int, @bitCast(actual)));
152 const first_size = @bitSizeOf(union_info.field_types[0]);152 } else switch (@"union".layout) {
153 inline for (union_info.field_types) |field_type| {153 .@"packed" => {
154 const Int = @Int(.unsigned, @bitSizeOf(T));
155 try expectEqual(@as(Int, @bitCast(expected)), @as(Int, @bitCast(actual)));
156 },
157 .@"extern" => {
158 const first_size = @bitSizeOf(@"union".field_types[0]);
159 inline for (@"union".field_types) |field_type| {
154 if (@bitSizeOf(field_type) != first_size) {160 if (@bitSizeOf(field_type) != first_size) {
155 @compileError("Unable to compare untagged unions with varying field sizes for type " ++ @typeName(@TypeOf(actual)));161 @compileError("Unable to compare extern unions with varying field sizes for type " ++ @typeName(T));
156 }162 }
157 }163 }
158164 const FieldInt = @Int(.unsigned, first_size);
159 const BackingInt = @Int(.unsigned, @bitSizeOf(T));165 const expected_field = @field(expected, @"union".field_names[0]);
166 const actual_field = @field(actual, @"union".field_names[0]);
160 return expectEqual(167 return expectEqual(
161 @as(BackingInt, @bitCast(expected)),168 @as(FieldInt, @bitCast(expected_field)),
162 @as(BackingInt, @bitCast(actual)),169 @as(FieldInt, @bitCast(actual_field)),
163 );170 );
164 }171 },
165172 .auto => {
166 const Tag = std.meta.Tag(@TypeOf(expected));173 const Tag = @"union".tag_type orelse @compileError("byteSwapAllFields expects packed, extern, or tagged union");
167174
168 const expectedTag = @as(Tag, expected);175 try expectEqual(@as(Tag, expected), @as(Tag, actual));
169 const actualTag = @as(Tag, actual);176 switch (expected) {
170177 inline else => |expected_payload, tag| {
171 try expectEqual(expectedTag, actualTag);178 const actual_payload = @field(actual, @tagName(tag));
172179 try expectEqual(expected_payload, actual_payload);
173 // we only reach this switch if the tags are equal180 },
174 switch (expected) {181 }
175 inline else => |val, tag| try expectEqual(val, @field(actual, @tagName(tag))),182 },
176 }
177 },183 },
178184
179 .optional => {185 .optional => {
lib/std/zig/llvm/Builder.zig+2-2
...@@ -1816,7 +1816,7 @@ pub const Linkage = enum(u4) {...@@ -1816,7 +1816,7 @@ pub const Linkage = enum(u4) {
1816 }1816 }
1817};1817};
18181818
1819pub const Preemption = enum {1819pub const Preemption = enum(u2) {
1820 dso_preemptable,1820 dso_preemptable,
1821 dso_local,1821 dso_local,
1822 implicit_dso_local,1822 implicit_dso_local,
...@@ -2011,7 +2011,7 @@ pub const AddrSpace = enum(u24) {...@@ -2011,7 +2011,7 @@ pub const AddrSpace = enum(u24) {
2011 }2011 }
2012};2012};
20132013
2014pub const ExternallyInitialized = enum {2014pub const ExternallyInitialized = enum(u1) {
2015 default,2015 default,
2016 externally_initialized,2016 externally_initialized,
20172017