zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit fdac89d6cd65fa19bd5c6d381b62d980d97e5852 (tree)
parent 57634b7809d07c8a07a015bec55829937d5795e1
Author: Matthew Lugg <mlugg@mlugg.co.uk>
Date:   Wed, 29 Apr 2026 19:30:34 +0100

remove uses of array multiplication

In preparation for its removal as accepted in
https://github.com/ziglang/zig/issues/24738.

Diffstat:
Mlib/compiler/build_runner.zig | 2+-
Mlib/compiler/resinator/cvtres.zig | 8++++----
Mlib/compiler/resinator/ico.zig | 8++++----
Mlib/compiler/resinator/parse.zig | 4++--
Mlib/compiler/resinator/res.zig | 2+-
Mlib/compiler/translate-c/ast.zig | 32+++++++++++---------------------
Mlib/compiler_rt/atomics.zig | 2+-
Mlib/compiler_rt/ssp.zig | 4++--
Mlib/std/Io/Threaded.zig | 8++++----
Mlib/std/Io/Writer.zig | 2+-
Mlib/std/Io/net/HostName.zig | 17+++++++++++------
Mlib/std/Random/ChaCha.zig | 4++--
Mlib/std/Random/benchmark.zig | 4++--
Mlib/std/Random/test.zig | 8++++----
Mlib/std/Thread.zig | 4++--
Mlib/std/base64.zig | 10+++++-----
Mlib/std/bit_set.zig | 14+++++++-------
Mlib/std/c.zig | 34+++++++++++++++++-----------------
Mlib/std/compress/flate/Decompress.zig | 2+-
Mlib/std/crypto.zig | 6+++---
Mlib/std/crypto/25519/curve25519.zig | 4++--
Mlib/std/crypto/25519/edwards25519.zig | 6+++---
Mlib/std/crypto/25519/ristretto255.zig | 4++--
Mlib/std/crypto/25519/scalar.zig | 12++++++------
Mlib/std/crypto/25519/x25519.zig | 2+-
Mlib/std/crypto/Certificate.zig | 2+-
Mlib/std/crypto/Sha1.zig | 2+-
Mlib/std/crypto/aegis.zig | 84++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mlib/std/crypto/aes_ccm.zig | 40++++++++++++++++++++--------------------
Mlib/std/crypto/aes_gcm.zig | 22++++++++++------------
Mlib/std/crypto/aes_ocb.zig | 18+++++++++---------
Mlib/std/crypto/argon2.zig | 30+++++++++++++++---------------
Mlib/std/crypto/bcrypt.zig | 30++++++++++++++++++++----------
Mlib/std/crypto/benchmark.zig | 14+++++++-------
Mlib/std/crypto/blake2.zig | 164++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mlib/std/crypto/cbc_mac.zig | 2+-
Mlib/std/crypto/chacha20.zig | 20++++++++++----------
Mlib/std/crypto/cmac.zig | 4++--
Mlib/std/crypto/codecs/asn1.zig | 2+-
Mlib/std/crypto/ecdsa.zig | 18+++++++++---------
Mlib/std/crypto/ff.zig | 4++--
Mlib/std/crypto/ghash_polyval.zig | 8++++----
Mlib/std/crypto/hkdf.zig | 2+-
Mlib/std/crypto/isap.zig | 6+++---
Mlib/std/crypto/kangarootwelve.zig | 2+-
Mlib/std/crypto/keccak_p.zig | 14+++++++-------
Mlib/std/crypto/md5.zig | 2+-
Mlib/std/crypto/ml_dsa.zig | 66+++++++++++++++++++++++++++++++++---------------------------------
Mlib/std/crypto/ml_kem.zig | 8++++----
Mlib/std/crypto/modes.zig | 2+-
Mlib/std/crypto/pbkdf2.zig | 2+-
Mlib/std/crypto/pcurves/p256/scalar.zig | 6+++---
Mlib/std/crypto/pcurves/p384/scalar.zig | 4++--
Mlib/std/crypto/pcurves/secp256k1/scalar.zig | 6+++---
Mlib/std/crypto/pcurves/tests/p256.zig | 10+++++-----
Mlib/std/crypto/pcurves/tests/p384.zig | 10+++++-----
Mlib/std/crypto/pcurves/tests/secp256k1.zig | 6+++---
Mlib/std/crypto/salsa20.zig | 16++++++++--------
Mlib/std/crypto/sha2.zig | 4++--
Mlib/std/crypto/sha3.zig | 4++--
Mlib/std/crypto/siphash.zig | 2+-
Mlib/std/crypto/timing_safe.zig | 9+++++----
Mlib/std/crypto/tls/Client.zig | 19++++++++++---------
Mlib/std/debug.zig | 10++++++----
Mlib/std/debug/Dwarf.zig | 2+-
Mlib/std/elf.zig | 2+-
Mlib/std/enums.zig | 2+-
Mlib/std/fmt.zig | 6+++++-
Mlib/std/fmt/parse_float/decimal.zig | 2+-
Mlib/std/fs/test.zig | 10+++++++---
Mlib/std/hash/Adler32.zig | 6+++---
Mlib/std/hash/benchmark.zig | 4++--
Mlib/std/hash/wyhash.zig | 2+-
Mlib/std/heap/debug_allocator.zig | 2+-
Mlib/std/http.zig | 2+-
Mlib/std/json/JSONTestSuite_test.zig | 15++++++++++-----
Mlib/std/json/scanner_test.zig | 45++++++++++++++++++++++++++++-----------------
Mlib/std/json/static.zig | 4++--
Mlib/std/math/big/int.zig | 6+++---
Mlib/std/math/big/int_test.zig | 26+++++++++++++-------------
Mlib/std/mem.zig | 15+++++++++------
Mlib/std/os/emscripten.zig | 4++--
Mlib/std/os/linux.zig | 8++++----
Mlib/std/os/linux/IoUring/test.zig | 64++++++++++++++++++++++++++++++++++------------------------------
Mlib/std/os/linux/test.zig | 2+-
Mlib/std/os/uefi/hii.zig | 2+-
Mlib/std/posix/test.zig | 4++--
Mlib/std/tar.zig | 12++++++++----
Mlib/std/tar/Writer.zig | 72+++++++++++++++++++++++++++++++++++++++---------------------------------
Mlib/std/tar/test.zig | 8++++++--
Mlib/std/unicode.zig | 21+++++++++++++--------
Mlib/std/unicode/throughput_test.zig | 12+++++++++---
Mlib/std/zig/AstGen.zig | 2+-
Mlib/std/zig/LibCInstallation.zig | 2+-
Mlib/std/zig/WindowsSdk.zig | 2+-
Mlib/std/zig/llvm/Builder.zig | 10+++-------
Msrc/Air/Liveness.zig | 8++++----
Msrc/codegen/aarch64/Select.zig | 4++--
Msrc/codegen/llvm.zig | 8++++++--
Msrc/codegen/llvm/FuncGen.zig | 2+-
Msrc/codegen/riscv64/CodeGen.zig | 10+++++-----
Msrc/codegen/riscv64/abi.zig | 2+-
Msrc/codegen/sparc64/CodeGen.zig | 6+++---
Msrc/codegen/x86_64/CodeGen.zig | 10++++++----
Msrc/codegen/x86_64/Encoding.zig | 12++++++++++--
Msrc/codegen/x86_64/encoder.zig | 4++--
Msrc/libs/mingw/implib.zig | 2+-
Msrc/link/Coff.zig | 24++++++++++++++++++++----
Msrc/link/Dwarf.zig | 2+-
Msrc/link/Elf.zig | 2+-
Msrc/link/Elf/Symbol.zig | 2+-
Msrc/link/MachO.zig | 4++--
Msrc/link/MachO/CodeSignature.zig | 2+-
Msrc/link/MachO/DebugSymbols.zig | 2+-
Msrc/link/MachO/InternalObject.zig | 2+-
Msrc/link/MachO/Symbol.zig | 2+-
Mtest/behavior/array.zig | 20++++----------------
Mtest/behavior/basic.zig | 9+--------
Mtest/behavior/bit_shifting.zig | 2+-
Mtest/behavior/cast.zig | 2+-
Mtest/behavior/eval.zig | 46+---------------------------------------------
Mtest/behavior/extern_struct_zero_size_fields.zig | 4++--
Mtest/behavior/for.zig | 6+++++-
Mtest/behavior/memset.zig | 4++--
Mtest/behavior/optional.zig | 2+-
Mtest/behavior/packed-struct.zig | 2+-
Mtest/behavior/pointers.zig | 2+-
Mtest/behavior/popcount.zig | 8++++----
Mtest/behavior/slice.zig | 12+-----------
Mtest/behavior/slice_sentinel_comptime.zig | 59+++++++++++++++++++++++++++++++----------------------------
Mtest/behavior/struct.zig | 2+-
Mtest/behavior/tuple.zig | 25+------------------------
Mtest/behavior/tuple_declarations.zig | 6------
Mtest/behavior/undefined.zig | 2+-
Mtest/behavior/union.zig | 4++--
Mtest/behavior/void.zig | 2+-
Mtest/c/unistd.zig | 6+++---
Dtest/cases/compile_errors/Issue_6823_dont_allow_._to_be_followed_by_.zig | 8--------
Dtest/cases/compile_errors/array_mult_with_number_type.zig | 9---------
Mtest/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig | 15++++++++-------
Mtest/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig | 15++++++++-------
Mtest/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig | 27++++++++++++++-------------
Mtest/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_terminated.zig | 15++++++++-------
Mtest/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig | 15++++++++-------
Dtest/cases/compile_errors/dereference_bad_pointer_via_array_mul.zig | 11-----------
Mtest/cases/compile_errors/function_call_assigned_to_incorrect_type.zig | 2+-
Mtest/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig | 2+-
Mtest/cases/safety/memcpy_alias.zig | 2+-
Mtest/cases/safety/memcpy_len_mismatch.zig | 2+-
Mtest/cases/safety/memmove_len_mismatch.zig | 2+-
Mtools/fetch_them_macos_headers.zig | 2+-
Mtools/gen_spirv_spec.zig | 2+-
Mtools/gen_stubs.zig | 6+++---
Mtools/generate_JSONTestSuite.zig | 35++++++++++++++++++++++++-----------
154 files changed, 892 insertions(+), 866 deletions(-)

diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig @@ -1557,7 +1557,7 @@ fn printUsage(b: *std.Build, w: *Writer) !void { const name = try fmt.allocPrint(arena, " -D{s}=[{t}]", .{ option.name, option.type_id }); try w.print("{s:<30} {s}\n", .{ name, option.description }); if (option.enum_options) |enum_options| { - const padding = " " ** 33; + const padding: [33]u8 = @splat(' '); try w.writeAll(padding ++ "Supported Values:\n"); for (enum_options) |enum_option| { try w.print(padding ++ " {s}\n", .{enum_option}); diff --git a/lib/compiler/resinator/cvtres.zig b/lib/compiler/resinator/cvtres.zig @@ -321,7 +321,7 @@ pub fn writeCoff( .checksum = 0, .number = 0, .selection = .NONE, - .unused = .{0} ** 3, + .unused = @splat(0), }); try writeSymbol(writer, .{ @@ -342,7 +342,7 @@ pub fn writeCoff( .checksum = 0, .number = 0, .selection = .NONE, - .unused = .{0} ** 3, + .unused = @splat(0), }); for (resource_symbols) |resource_symbol| { @@ -353,11 +353,11 @@ pub fn writeCoff( const name_bytes: [8]u8 = name_bytes: { if (external_symbol_name.len > 8) { const string_table_offset: u32 = try string_table.put(allocator, external_symbol_name); - var bytes = [_]u8{0} ** 8; + var bytes: [8]u8 = @splat(0); std.mem.writeInt(u32, bytes[4..8], string_table_offset, .little); break :name_bytes bytes; } else { - var symbol_shortname = [_]u8{0} ** 8; + var symbol_shortname: [8]u8 = @splat(0); @memcpy(symbol_shortname[0..external_symbol_name.len], external_symbol_name); break :name_bytes symbol_shortname; } diff --git a/lib/compiler/resinator/ico.zig b/lib/compiler/resinator/ico.zig @@ -183,7 +183,7 @@ pub const Entry = struct { }; test "icon" { - const data = "\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x00\x00\x00\x16\x00\x00\x00" ++ [_]u8{0} ** 16; + const data = "\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x00\x00\x00\x16\x00\x00\x00" ++ @as([16]u8, @splat(0)); var fbs: std.Io.Reader = .fixed(data); const icon = try read(std.testing.allocator, &fbs, data.len); defer icon.deinit(); @@ -196,19 +196,19 @@ test "icon too many images" { // Note that with verifying that all data sizes are within the file bounds and >= 16, // it's not possible to hit EOF when looking for more RESDIR structures, since they are // themselves 16 bytes long, so we'll always hit ImpossibleDataSize instead. - const data = "\x00\x00\x01\x00\x02\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x00\x00\x00\x16\x00\x00\x00" ++ [_]u8{0} ** 16; + const data = "\x00\x00\x01\x00\x02\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x00\x00\x00\x16\x00\x00\x00" ++ @as([16]u8, @splat(0)); var fbs: std.Io.Reader = .fixed(data); try std.testing.expectError(error.ImpossibleDataSize, read(std.testing.allocator, &fbs, data.len)); } test "icon data size past EOF" { - const data = "\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x01\x00\x00\x16\x00\x00\x00" ++ [_]u8{0} ** 16; + const data = "\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x01\x00\x00\x16\x00\x00\x00" ++ @as([16]u8, @splat(0)); var fbs: std.Io.Reader = .fixed(data); try std.testing.expectError(error.ImpossibleDataSize, read(std.testing.allocator, &fbs, data.len)); } test "icon data offset past EOF" { - const data = "\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x00\x00\x00\x17\x00\x00\x00" ++ [_]u8{0} ** 16; + const data = "\x00\x00\x01\x00\x01\x00\x10\x10\x00\x00\x01\x00\x10\x00\x10\x00\x00\x00\x17\x00\x00\x00" ++ @as([16]u8, @splat(0)); var fbs: std.Io.Reader = .fixed(data); try std.testing.expectError(error.ImpossibleDataSize, read(std.testing.allocator, &fbs, data.len)); } diff --git a/lib/compiler/resinator/parse.zig b/lib/compiler/resinator/parse.zig @@ -138,8 +138,8 @@ pub const Parser = struct { var optional_statements: std.ArrayList(*Node) = .empty; const num_statement_types = @typeInfo(rc.OptionalStatements).@"enum".fields.len; - var statement_type_has_duplicates = [_]bool{false} ** num_statement_types; - var last_statement_per_type = [_]?*Node{null} ** num_statement_types; + var statement_type_has_duplicates: [num_statement_types]bool = @splat(false); + var last_statement_per_type: [num_statement_types]?*Node = @splat(null); while (true) { const lookahead_token = try self.lookaheadToken(.normal); diff --git a/lib/compiler/resinator/res.zig b/lib/compiler/resinator/res.zig @@ -1068,7 +1068,7 @@ pub const FixedFileInfo = struct { pub const key = std.unicode.utf8ToUtf16LeStringLiteral("VS_VERSION_INFO"); pub const Version = struct { - parts: [4]u16 = [_]u16{0} ** 4, + parts: [4]u16 = @splat(0), pub fn mostSignificantCombinedParts(self: Version) u32 { return (@as(u32, self.parts[0]) << 16) + self.parts[1]; diff --git a/lib/compiler/translate-c/ast.zig b/lib/compiler/translate-c/ast.zig @@ -242,7 +242,7 @@ pub const Node = extern union { /// array_type{} empty_array, - /// [1]type{val} ** count + /// @as([count]type, @splat(val)) array_filler, /// comptime { if (!(lhs)) @compileError(rhs); } @@ -1976,28 +1976,18 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { .array_filler => { const payload = node.castTag(.array_filler).?.data; - const type_expr = try renderArrayType(c, 1, payload.type); - const l_brace = try c.addToken(.l_brace, "{"); - const val = try renderNode(c, payload.filler); - _ = try c.addToken(.r_brace, "}"); + const as_tok = try c.addToken(.builtin, "@as"); + _ = try c.addToken(.l_paren, "("); + const type_node = try renderArrayType(c, payload.count, payload.type); + _ = try c.addToken(.comma, ","); + const splat_node = try renderBuiltinCall(c, "@splat", &.{payload.filler}); + _ = try c.addToken(.r_paren, ")"); - const init = try c.addNode(.{ - .tag = .array_init_one, - .main_token = l_brace, - .data = .{ .node_and_node = .{ - type_expr, val, - } }, - }); return c.addNode(.{ - .tag = .array_cat, - .main_token = try c.addToken(.asterisk_asterisk, "**"), - .data = .{ .node_and_node = .{ - init, - try c.addNode(.{ - .tag = .number_literal, - .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.count}), - .data = undefined, - }), + .tag = .builtin_call_two, + .main_token = as_tok, + .data = .{ .opt_node_and_opt_node = .{ + .fromOptional(type_node), .fromOptional(splat_node), } }, }); }, diff --git a/lib/compiler_rt/atomics.zig b/lib/compiler_rt/atomics.zig @@ -94,7 +94,7 @@ const SpinlockTable = struct { } }; - list: [max_spinlocks]Spinlock = [_]Spinlock{.{}} ** max_spinlocks, + list: [max_spinlocks]Spinlock = @splat(.{}), // The spinlock table behaves as a really simple hash table, mapping // addresses to spinlocks. The mapping is not unique but that's only a diff --git a/lib/compiler_rt/ssp.zig b/lib/compiler_rt/ssp.zig @@ -44,10 +44,10 @@ fn __chk_fail() callconv(.c) noreturn { // TODO: Initialize the canary with random data var __stack_chk_guard: usize = blk: { - var buf = [1]u8{0} ** @sizeOf(usize); + var buf: [@sizeOf(usize)]u8 = @splat(0); buf[@sizeOf(usize) - 1] = 255; buf[@sizeOf(usize) - 2] = '\n'; - break :blk @as(usize, @bitCast(buf)); + break :blk @bitCast(buf); }; fn __strcpy_chk(dest: [*:0]u8, src: [*:0]const u8, dest_n: usize) callconv(.c) [*:0]u8 { diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig @@ -6329,7 +6329,7 @@ pub fn GetFinalPathNameByHandle( const MIN_SIZE = @sizeOf(windows.MOUNTMGR_MOUNT_POINT) + windows.MAX_PATH; // We initialize the input buffer to all zeros for convenience since // `DeviceIoControl` with `IOCTL_MOUNTMGR_QUERY_POINTS` expects this. - var input_buf: [MIN_SIZE]u8 align(@alignOf(windows.MOUNTMGR_MOUNT_POINT)) = [_]u8{0} ** MIN_SIZE; + var input_buf: [MIN_SIZE]u8 align(@alignOf(windows.MOUNTMGR_MOUNT_POINT)) = @splat(0); var output_buf: [MIN_SIZE * 4]u8 align(@alignOf(windows.MOUNTMGR_MOUNT_POINTS)) = undefined; // This surprising path is a filesystem path to the mount manager on Windows. @@ -6409,7 +6409,7 @@ pub fn GetFinalPathNameByHandle( // 49 is the maximum length accepted by mountmgrIsVolumeName const vol_input_size = @sizeOf(windows.MOUNTMGR_TARGET_NAME) + (49 * 2); - var vol_input_buf: [vol_input_size]u8 align(@alignOf(windows.MOUNTMGR_TARGET_NAME)) = [_]u8{0} ** vol_input_size; + var vol_input_buf: [vol_input_size]u8 align(@alignOf(windows.MOUNTMGR_TARGET_NAME)) = @splat(0); // Note: If the path exceeds MAX_PATH, the Disk Management GUI doesn't accept the full path, // and instead if must be specified using a shortened form (e.g. C:\FOO~1\BAR~1\<...>). // However, just to be sure we can handle any path length, we use PATH_MAX_WIDE here. @@ -8914,7 +8914,7 @@ fn isCygwinPty(file: File) Io.Cancelable!bool { // we can use this smaller buffer and just return false on any error from // NtQueryInformationFile. const num_name_bytes = windows.MAX_PATH * 2; - var name_info_bytes align(@alignOf(windows.FILE.NAME_INFORMATION)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes); + var name_info_bytes: [name_bytes_offset + num_name_bytes]u8 align(@alignOf(windows.FILE.NAME_INFORMATION)) = @splat(0); var io_status_block: windows.IO_STATUS_BLOCK = undefined; const syscall: Syscall = try .start(); @@ -16191,7 +16191,7 @@ fn windowsCreateProcessPathExt( var io_status: windows.IO_STATUS_BLOCK = undefined; const num_supported_pathext = @typeInfo(process.WindowsExtension).@"enum".fields.len; - var pathext_seen = [_]bool{false} ** num_supported_pathext; + var pathext_seen: [num_supported_pathext]bool = @splat(false); var any_pathext_seen = false; var unappended_exists = false; diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig @@ -781,7 +781,7 @@ test splatByteAll { defer aw.deinit(); try aw.writer.splatByteAll('7', 45); - try testing.expectEqualStrings("7" ** 45, aw.writer.buffered()); + try testing.expectEqualStrings(&@as([45]u8, @splat('7')), aw.writer.buffered()); } pub fn splatBytePreserve(w: *Writer, preserve: usize, byte: u8, n: usize) Error!void { diff --git a/lib/std/Io/net/HostName.zig b/lib/std/Io/net/HostName.zig @@ -76,9 +76,14 @@ test validate { try validate("a-b.com"); try validate("a.b.c.d.e.f.g"); try validate("127.0.0.1"); // Also a valid hostname - try validate("a" ** 63 ++ ".com"); // Label exactly 63 chars (valid) - try validate("a." ** 127 ++ "a"); // Total length 255 (valid) - try validate("a." ** 127 ++ "a."); // Total length 255 + trailing dot (valid) + + const many_a: [63]u8 = @splat('a'); + try validate(&many_a ++ ".com"); // Label exactly 63 chars (valid) + + const many_a_dot_buf: [127][2]u8 = @splat(.{ 'a', '.' }); + const many_a_dot: []const u8 = @ptrCast(&many_a_dot_buf); + try validate(many_a_dot ++ "a"); // Total length 255 (valid) + try validate(many_a_dot ++ "a."); // Total length 255 + trailing dot (valid) // Invalid hostnames try std.testing.expectError(error.InvalidHostName, validate("")); @@ -92,9 +97,9 @@ test validate { try std.testing.expectError(error.InvalidHostName, validate("host_name.com")); try std.testing.expectError(error.InvalidHostName, validate(".")); try std.testing.expectError(error.InvalidHostName, validate("..")); - try std.testing.expectError(error.InvalidHostName, validate("a" ** 64 ++ ".com")); // Label length 64 (too long) - try std.testing.expectError(error.NameTooLong, validate("a." ** 127 ++ "ab")); // Total length 256 (too long) - try std.testing.expectError(error.NameTooLong, validate("a." ** 127 ++ "ab.")); // Total length 256 + trailing dot (too long) + try std.testing.expectError(error.InvalidHostName, validate(&many_a ++ "a.com")); // Label length 64 (too long) + try std.testing.expectError(error.NameTooLong, validate(many_a_dot ++ "ab")); // Total length 256 (too long) + try std.testing.expectError(error.NameTooLong, validate(many_a_dot ++ "ab.")); // Total length 256 + trailing dot (too long) } pub fn init(bytes: []const u8) ValidateError!HostName { diff --git a/lib/std/Random/ChaCha.zig b/lib/std/Random/ChaCha.zig @@ -14,7 +14,7 @@ const State = [8 * Cipher.block_length]u8; state: State, offset: usize, -const nonce = [_]u8{0} ** Cipher.nonce_length; +const nonce: [Cipher.nonce_length]u8 = @splat(0); pub const secret_seed_length = Cipher.key_length; @@ -38,7 +38,7 @@ pub fn addEntropy(self: *Self, bytes: []const u8) void { ); } if (i < bytes.len) { - var k = [_]u8{0} ** Cipher.key_length; + var k: [Cipher.key_length]u8 = @splat(0); const src = bytes[i..]; @memcpy(k[0..src.len], src); Cipher.xor( diff --git a/lib/std/Random/benchmark.zig b/lib/std/Random/benchmark.zig @@ -55,12 +55,12 @@ const csprngs = [_]Rng{ Rng{ .ty = Random.Ascon, .name = "ascon", - .init_u8s = &[_]u8{0} ** 32, + .init_u8s = &@as([32]u8, @splat(0)), }, Rng{ .ty = Random.ChaCha, .name = "chacha", - .init_u8s = &[_]u8{0} ** 32, + .init_u8s = &@as([32]u8, @splat(0)), }, }; diff --git a/lib/std/Random/test.zig b/lib/std/Random/test.zig @@ -383,8 +383,8 @@ test "Random shuffle" { var prng = DefaultPrng.init(0); const random = prng.random(); - var seq = [_]u8{ 0, 1, 2, 3, 4 }; - var seen = [_]bool{false} ** 5; + var seq: [5]u8 = .{ 0, 1, 2, 3, 4 }; + var seen: [5]bool = @splat(false); var i: usize = 0; while (i < 1000) : (i += 1) { @@ -421,8 +421,8 @@ fn testRange(r: Random, start: i8, end: i8) !void { try testRangeBias(r, start, end, false); } fn testRangeBias(r: Random, start: i8, end: i8, biased: bool) !void { - const count = @as(usize, @intCast(@as(i32, end) - @as(i32, start))); - var values_buffer = [_]bool{false} ** 0x100; + const count: usize = @intCast(@as(i32, end) - @as(i32, start)); + var values_buffer: [0x100]bool = @splat(false); const values = values_buffer[0..count]; var i: usize = 0; while (i < count) { diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig @@ -1574,9 +1574,9 @@ const LinuxThreadImpl = struct { }; fn testThreadName(io: Io, thread: *Thread) !void { - const testCases = &[_][]const u8{ + const testCases: []const []const u8 = &.{ "mythread", - "b" ** max_name_len, + &@as([max_name_len]u8, @splat('b')), }; inline for (testCases) |tc| { diff --git a/lib/std/base64.zig b/lib/std/base64.zig @@ -86,7 +86,7 @@ pub const Base64Encoder = struct { /// A bunch of assertions, then simply pass the data right through. pub fn init(alphabet_chars: [64]u8, pad_char: ?u8) Base64Encoder { assert(alphabet_chars.len == 64); - var char_in_alphabet = [_]bool{false} ** 256; + var char_in_alphabet: [256]bool = @splat(false); for (alphabet_chars) |c| { assert(!char_in_alphabet[c]); assert(pad_char == null or c != pad_char.?); @@ -176,12 +176,12 @@ pub const Base64Decoder = struct { pub fn init(alphabet_chars: [64]u8, pad_char: ?u8) Base64Decoder { var result = Base64Decoder{ - .char_to_index = [_]u8{invalid_char} ** 256, - .fast_char_to_index = .{[_]u32{invalid_char_tst} ** 256} ** 4, + .char_to_index = @splat(invalid_char), + .fast_char_to_index = @splat(@splat(invalid_char_tst)), .pad_char = pad_char, }; - var char_in_alphabet = [_]bool{false} ** 256; + var char_in_alphabet: [256]bool = @splat(false); for (alphabet_chars, 0..) |c, i| { assert(!char_in_alphabet[c]); assert(pad_char == null or c != pad_char.?); @@ -302,7 +302,7 @@ pub const Base64DecoderWithIgnore = struct { pub fn init(alphabet_chars: [64]u8, pad_char: ?u8, ignore_chars: []const u8) Base64DecoderWithIgnore { var result = Base64DecoderWithIgnore{ .decoder = Base64Decoder.init(alphabet_chars, pad_char), - .char_is_ignored = [_]bool{false} ** 256, + .char_is_ignored = @splat(false), }; for (ignore_chars) |c| { assert(result.decoder.char_to_index[c] == Base64Decoder.invalid_char); diff --git a/lib/std/bit_set.zig b/lib/std/bit_set.zig @@ -406,24 +406,24 @@ pub fn Array(comptime MaskIntType: type, comptime size: usize) type { /// Deprecated: use `.empty`. /// Creates a bit set with no elements present. pub fn initEmpty() Self { - return .{ .masks = [_]MaskInt{0} ** num_masks }; + return .empty; } /// Deprecated: use `.full`. /// Creates a bit set with all elements present. pub fn initFull() Self { - if (num_masks == 0) { - return .{ .masks = .{} }; - } else { - return .{ .masks = [_]MaskInt{~@as(MaskInt, 0)} ** (num_masks - 1) ++ [_]MaskInt{last_item_mask} }; - } + return .full; } /// A bit set with no elements present. pub const empty: Self = .{ .masks = @splat(0) }; /// A bit set with all elements present. - pub const full: Self = .{ .masks = if (num_masks == 0) .{} else ([_]MaskInt{~@as(MaskInt, 0)} ** (num_masks - 1) ++ [_]MaskInt{last_item_mask}) }; + pub const full: Self = full: { + var masks: [num_masks]MaskInt = @splat(~@as(MaskInt, 0)); + if (num_masks > 0) masks[num_masks - 1] = last_item_mask; + break :full .{ .masks = masks }; + }; /// Returns the number of bits in this bit set pub inline fn capacity(self: Self) usize { diff --git a/lib/std/c.zig b/lib/std/c.zig @@ -7914,7 +7914,7 @@ pub const pthread_spinlock_t = switch (native_os) { pub const pthread_mutex_t = switch (native_os) { .linux => extern struct { - data: [data_len]u8 align(@alignOf(usize)) = [_]u8{0} ** data_len, + data: [data_len]u8 align(@alignOf(usize)) = @splat(0), const data_len = switch (native_abi) { .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24, @@ -7930,7 +7930,7 @@ pub const pthread_mutex_t = switch (native_os) { }, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct { sig: c_long = 0x32AAABA7, - data: [data_len]u8 = [_]u8{0} ** data_len, + data: [data_len]u8 = @splat(0), const data_len = if (@sizeOf(usize) == 8) 56 else 40; }, @@ -7966,10 +7966,10 @@ pub const pthread_mutex_t = switch (native_os) { data: u64 = 0, }, .fuchsia => extern struct { - data: [40]u8 align(@alignOf(usize)) = [_]u8{0} ** 40, + data: [40]u8 align(@alignOf(usize)) = @splat(0), }, .emscripten => extern struct { - data: [24]u8 align(4) = [_]u8{0} ** 24, + data: [24]u8 align(4) = @splat(0), }, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L68-L73 .serenity => extern struct { @@ -7983,11 +7983,11 @@ pub const pthread_mutex_t = switch (native_os) { pub const pthread_cond_t = switch (native_os) { .linux => extern struct { - data: [48]u8 align(@alignOf(usize)) = [_]u8{0} ** 48, + data: [48]u8 align(@alignOf(usize)) = @splat(0), }, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct { sig: c_long = 0x3CB0B1BB, - data: [data_len]u8 = [_]u8{0} ** data_len, + data: [data_len]u8 = @splat(0), const data_len = if (@sizeOf(usize) == 8) 40 else 24; }, .freebsd, .dragonfly, .openbsd => extern struct { @@ -8012,13 +8012,13 @@ pub const pthread_cond_t = switch (native_os) { lock: i32 = 0, }, .illumos => extern struct { - flag: [4]u8 = [_]u8{0} ** 4, + flag: [4]u8 = @splat(0), type: u16 = 0, magic: u16 = 0x4356, data: u64 = 0, }, .fuchsia, .emscripten => extern struct { - data: [48]u8 align(@alignOf(usize)) = [_]u8{0} ** 48, + data: [48]u8 align(@alignOf(usize)) = @splat(0), }, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L80-L84 .serenity => extern struct { @@ -8033,20 +8033,20 @@ pub const pthread_rwlock_t = switch (native_os) { .linux => switch (native_abi) { .android, .androideabi => switch (@sizeOf(usize)) { 4 => extern struct { - data: [40]u8 align(@alignOf(usize)) = [_]u8{0} ** 40, + data: [40]u8 align(@alignOf(usize)) = @splat(0), }, 8 => extern struct { - data: [56]u8 align(@alignOf(usize)) = [_]u8{0} ** 56, + data: [56]u8 align(@alignOf(usize)) = @splat(0), }, else => @compileError("impossible pointer size"), }, else => extern struct { - data: [56]u8 align(@alignOf(usize)) = [_]u8{0} ** 56, + data: [56]u8 align(@alignOf(usize)) = @splat(0), }, }, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => extern struct { sig: c_long = 0x2DA8B3B4, - data: [192]u8 = [_]u8{0} ** 192, + data: [192]u8 = @splat(0), }, .freebsd, .dragonfly, .openbsd => extern struct { ptr: ?*anyopaque = null, @@ -8079,10 +8079,10 @@ pub const pthread_rwlock_t = switch (native_os) { writercv: pthread_cond_t = .{}, }, .fuchsia => extern struct { - size: [56]u8 align(@alignOf(usize)) = [_]u8{0} ** 56, + size: [56]u8 align(@alignOf(usize)) = @splat(0), }, .emscripten => extern struct { - size: [32]u8 align(4) = [_]u8{0} ** 32, + size: [32]u8 align(4) = @splat(0), }, // https://github.com/SerenityOS/serenity/blob/b98f537f117b341788023ab82e0c11ca9ae29a57/Kernel/API/POSIX/sys/types.h#L86 .serenity => extern struct { @@ -8170,8 +8170,8 @@ pub const sem_t = switch (native_os) { count: u32 = 0, type: u16 = 0, magic: u16 = 0x534d, - __pad1: [3]u64 = [_]u64{0} ** 3, - __pad2: [2]u64 = [_]u64{0} ** 2, + __pad1: [3]u64 = @splat(0), + __pad2: [2]u64 = @splat(0), }, .openbsd, .netbsd, .dragonfly => ?*opaque {}, .haiku => extern struct { @@ -8235,7 +8235,7 @@ pub const Kevent = switch (native_os) { /// Opaque user data identifier. udata: usize, /// Future extensions. - _ext: [4]u64 = [_]u64{0} ** 4, + _ext: [4]u64 = @splat(0), }, .dragonfly => extern struct { ident: usize, diff --git a/lib/std/compress/flate/Decompress.zig b/lib/std/compress/flate/Decompress.zig @@ -723,7 +723,7 @@ fn HuffmanDecoder( if (alphabet_size == 286) if (lens[256] == 0) return error.MissingEndOfBlockCode; - var count = [_]u16{0} ** (@as(usize, max_code_bits) + 1); + var count: [@as(usize, max_code_bits) + 1]u16 = @splat(0); var max: usize = 0; for (lens) |n| { if (n == 0) continue; diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig @@ -394,7 +394,7 @@ test "issue #4532: no index out of bounds" { }; inline for (types) |Hasher| { - var block = [_]u8{'#'} ** Hasher.block_length; + var block: [Hasher.block_length]u8 = @splat('#'); var out1: [Hasher.digest_length]u8 = undefined; var out2: [Hasher.digest_length]u8 = undefined; const h0 = Hasher.init(.{}); @@ -417,8 +417,8 @@ pub fn secureZero(comptime T: type, s: []volatile T) void { } test secureZero { - var a = [_]u8{0xfe} ** 8; - var b = [_]u8{0xfe} ** 8; + var a: [8]u8 = @splat(0xFE); + var b: [8]u8 = @splat(0xFE); @memset(&a, 0); secureZero(u8, &b); diff --git a/lib/std/crypto/25519/curve25519.zig b/lib/std/crypto/25519/curve25519.zig @@ -41,7 +41,7 @@ pub const Curve25519 = struct { /// Multiply a point by the cofactor, returning WeakPublicKey if the element is in a small-order group. pub fn clearCofactor(p: Curve25519) WeakPublicKeyError!Curve25519 { - const cofactor = [_]u8{8} ++ [_]u8{0} ** 31; + const cofactor = [_]u8{8} ++ @as([31]u8, @splat(0)); return ladder(p, cofactor, 4) catch return error.WeakPublicKey; } @@ -168,7 +168,7 @@ test "elligator2" { } test "small order check" { - var s: [32]u8 = [_]u8{1} ++ [_]u8{0} ** 31; + var s: [32]u8 = [_]u8{1} ++ @as([31]u8, @splat(0)); const small_order_ss: [7][32]u8 = .{ .{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 (order 4) diff --git a/lib/std/crypto/25519/edwards25519.zig b/lib/std/crypto/25519/edwards25519.zig @@ -470,7 +470,7 @@ pub const Edwards25519 = struct { st.final(&hctx); xctx = hctx[0..]; } - const empty_block = [_]u8{0} ** H.block_length; + const empty_block: [H.block_length]u8 = @splat(0); var t = [3]u8{ 0, n * h_l, 0 }; var xctx_len_u8 = [1]u8{@as(u8, @intCast(xctx.len))}; var st = H.init(.{}); @@ -539,7 +539,7 @@ pub const Edwards25519 = struct { const htest = @import("../test.zig"); test "packing/unpacking" { - const s = [_]u8{170} ++ [_]u8{0} ** 31; + const s = [1]u8{170} ++ @as([31]u8, @splat(0)); var b = Edwards25519.basePoint; const pk = try b.mul(s); var buf: [128]u8 = undefined; @@ -609,7 +609,7 @@ test "hash-to-curve operation" { } test "implicit reduction of invalid scalars" { - const s = [_]u8{0} ** 31 ++ [_]u8{255}; + const s = @as([31]u8, @splat(0)) ++ [1]u8{255}; const p1 = try Edwards25519.basePoint.mulPublic(s); const p2 = try Edwards25519.basePoint.mul(s); const p3 = try p1.mulPublic(s); diff --git a/lib/std/crypto/25519/ristretto255.zig b/lib/std/crypto/25519/ristretto255.zig @@ -183,13 +183,13 @@ test "ristretto255" { q = q.dbl().add(p); try std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{&q.toBytes()}), "E882B131016B52C1D3337080187CF768423EFCCBB517BB495AB812C4160FF44E"); - const s = [_]u8{15} ++ [_]u8{0} ** 31; + const s = [_]u8{15} ++ @as([31]u8, @splat(0)); const w = try p.mul(s); try std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{&w.toBytes()}), "E0C418F7C8D9C4CDD7395B93EA124F3AD99021BB681DFC3302A9D99A2E53E64E"); try std.testing.expect(p.dbl().dbl().dbl().dbl().equivalent(w.add(p))); - const h = [_]u8{69} ** 32 ++ [_]u8{42} ** 32; + const h = @as([32]u8, @splat(69)) ++ @as([32]u8, @splat(42)); const ph = Ristretto255.fromUniform(h); try std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{&ph.toBytes()}), "DCCA54E037A4311EFBEEF413ACD21D35276518970B7A61DC88F8587B493D5E19"); } diff --git a/lib/std/crypto/25519/scalar.zig b/lib/std/crypto/25519/scalar.zig @@ -11,7 +11,7 @@ pub const field_order: u256 = 72370055773322622139731865630429942408571163593799 pub const CompressedScalar = [32]u8; /// Zero -pub const zero = [_]u8{0} ** 32; +pub const zero: [32]u8 = @splat(0); const field_order_s = s: { var s: [32]u8 = undefined; @@ -81,7 +81,7 @@ pub fn add(a: CompressedScalar, b: CompressedScalar) CompressedScalar { /// Return -s (mod L) pub fn neg(s: CompressedScalar) CompressedScalar { - const fs: [64]u8 = field_order_s ++ [_]u8{0} ** 32; + const fs: [64]u8 = field_order_s ++ @as([32]u8, @splat(0)); var sx: [64]u8 = undefined; sx[0..32].* = s; @memset(sx[32..], 0); @@ -862,9 +862,9 @@ test "non-canonical scalar25519" { } test "mulAdd overflow check" { - const a: [32]u8 = [_]u8{0xff} ** 32; - const b: [32]u8 = [_]u8{0xff} ** 32; - const c: [32]u8 = [_]u8{0xff} ** 32; + const a: [32]u8 = @splat(0xff); + const b: [32]u8 = @splat(0xff); + const c: [32]u8 = @splat(0xff); const x = mulAdd(a, b, c); var buf: [128]u8 = undefined; try std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{&x}), "D14DF91389432C25AD60FF9791B9FD1D67BEF517D273ECCE3D9A307C1B419903"); @@ -886,7 +886,7 @@ test "random scalar" { } test "64-bit reduction" { - const bytes = field_order_s ++ [_]u8{0} ** 32; + const bytes = field_order_s ++ @as([32]u8, @splat(0)); const x = Scalar.fromBytes64(bytes); try std.testing.expect(x.isZero()); } diff --git a/lib/std/crypto/25519/x25519.zig b/lib/std/crypto/25519/x25519.zig @@ -181,7 +181,7 @@ test "rfc7748 1,000,000 iterations" { } test "edwards25519 -> curve25519 map" { - const ed_kp = try crypto.sign.Ed25519.KeyPair.generateDeterministic([_]u8{0x42} ** 32); + const ed_kp = try crypto.sign.Ed25519.KeyPair.generateDeterministic(@splat(0x42)); const mont_kp = try X25519.KeyPair.fromEd25519(ed_kp); try htest.assertEqual("90e7595fc89e52fdfddce9c6a43d74dbf6047025ee0462d2d172e8b6a2841d6e", &mont_kp.secret_key); try htest.assertEqual("cc4f2cdb695dd766f34118eb67b98652fed1d8bc49c330b119bbfa8a64989378", &mont_kp.public_key); diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig @@ -1092,7 +1092,7 @@ pub const rsa = struct { } var m_p_buf: [8 + Hash.digest_length + Hash.digest_length]u8 = undefined; var m_p = m_p_buf[0 .. 8 + Hash.digest_length + sLen]; - std.mem.copyForwards(u8, m_p, &([_]u8{0} ** 8)); + std.mem.copyForwards(u8, m_p, @as(*const [8]u8, @splat(0))); std.mem.copyForwards(u8, m_p[8..], &mHash); std.mem.copyForwards(u8, m_p[(8 + Hash.digest_length)..], salt); diff --git a/lib/std/crypto/Sha1.zig b/lib/std/crypto/Sha1.zig @@ -297,7 +297,7 @@ test "sha1 streaming" { } test "sha1 aligned final" { - var block = [_]u8{0} ** Sha1.block_length; + var block: [Sha1.block_length]u8 = @splat(0); var out: [Sha1.digest_length]u8 = undefined; var h = Sha1.init(.{}); diff --git a/lib/std/crypto/aegis.zig b/lib/std/crypto/aegis.zig @@ -55,6 +55,14 @@ pub const Aegis256X2_256 = Aegis256XGeneric(2, 256); /// AEGIS-256 with a 256 bit tag pub const Aegis256_256 = Aegis256XGeneric(1, 256); +/// `inline` to avoid needless binary bloat from generic instantiations since the arguments are +/// usually comptime-known and the function is a trivial leaf function. +inline fn repeat16u8(comptime count: usize, part: [16]u8) [16 * count]u8 { + const buf: [count][part.len]u8 = @splat(part); + const ptr: *const [16 * count]u8 = @ptrCast(&buf); + return ptr.*; +} + fn State128X(comptime degree: u7) type { return struct { const AesBlockVec = crypto.core.aes.BlockVec(degree); @@ -67,10 +75,10 @@ fn State128X(comptime degree: u7) type { const alignment = AesBlockVec.native_word_size; fn init(key: [16]u8, nonce: [16]u8) State { - const c1 = AesBlockVec.fromBytes(&[16]u8{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd } ** degree); - const c2 = AesBlockVec.fromBytes(&[16]u8{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 } ** degree); - const key_block = AesBlockVec.fromBytes(&(key ** degree)); - const nonce_block = AesBlockVec.fromBytes(&(nonce ** degree)); + const c1 = AesBlockVec.fromBytes(&repeat16u8(degree, .{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd })); + const c2 = AesBlockVec.fromBytes(&repeat16u8(degree, .{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 })); + const key_block = AesBlockVec.fromBytes(&repeat16u8(degree, key)); + const nonce_block = AesBlockVec.fromBytes(&repeat16u8(degree, nonce)); const blocks = [8]AesBlockVec{ key_block.xorBlocks(nonce_block), c1, @@ -84,7 +92,7 @@ fn State128X(comptime degree: u7) type { var state = State{ .blocks = blocks }; if (degree > 1) { const context_block = ctx: { - var contexts_bytes = [_]u8{0} ** aes_block_length; + var contexts_bytes: [aes_block_length]u8 = @splat(0); for (0..degree) |i| { contexts_bytes[i * 16] = @intCast(i); contexts_bytes[i * 16 + 1] = @intCast(degree - 1); @@ -150,7 +158,7 @@ fn State128X(comptime degree: u7) type { const blocks = &state.blocks; const z0 = blocks[6].xorBlocks(blocks[1]).xorBlocks(blocks[2].andBlocks(blocks[3])); const z1 = blocks[2].xorBlocks(blocks[5]).xorBlocks(blocks[6].andBlocks(blocks[7])); - var pad = [_]u8{0} ** rate; + var pad: [rate]u8 = @splat(0); pad[0..aes_block_length].* = z0.toBytes(); pad[aes_block_length..].* = z1.toBytes(); for (pad[0..src.len], src) |*p, x| p.* ^= x; @@ -214,7 +222,7 @@ fn State128X(comptime degree: u7) type { state.update(t, t); } if (degree > 1) { - var v = [_]u8{0} ** rate; + var v: [rate]u8 = @splat(0); switch (tag_bits) { 128 => { const tags = blocks[0].xorBlocks(blocks[1]).xorBlocks(blocks[2]).xorBlocks(blocks[3]).xorBlocks(blocks[4]).xorBlocks(blocks[5]).xorBlocks(blocks[6]).toBytes(); @@ -362,12 +370,12 @@ fn State256X(comptime degree: u7) type { const alignment = AesBlockVec.native_word_size; fn init(key: [32]u8, nonce: [32]u8) State { - const c1 = AesBlockVec.fromBytes(&[16]u8{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd } ** degree); - const c2 = AesBlockVec.fromBytes(&[16]u8{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 } ** degree); - const key_block1 = AesBlockVec.fromBytes(key[0..16] ** degree); - const key_block2 = AesBlockVec.fromBytes(key[16..32] ** degree); - const nonce_block1 = AesBlockVec.fromBytes(nonce[0..16] ** degree); - const nonce_block2 = AesBlockVec.fromBytes(nonce[16..32] ** degree); + const c1 = AesBlockVec.fromBytes(&repeat16u8(degree, .{ 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd })); + const c2 = AesBlockVec.fromBytes(&repeat16u8(degree, .{ 0x0, 0x1, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 })); + const key_block1 = AesBlockVec.fromBytes(&repeat16u8(degree, key[0..16].*)); + const key_block2 = AesBlockVec.fromBytes(&repeat16u8(degree, key[16..32].*)); + const nonce_block1 = AesBlockVec.fromBytes(&repeat16u8(degree, nonce[0..16].*)); + const nonce_block2 = AesBlockVec.fromBytes(&repeat16u8(degree, nonce[16..32].*)); const kxn1 = key_block1.xorBlocks(nonce_block1); const kxn2 = key_block2.xorBlocks(nonce_block2); const blocks = [6]AesBlockVec{ @@ -381,7 +389,7 @@ fn State256X(comptime degree: u7) type { var state = State{ .blocks = blocks }; if (degree > 1) { const context_block = ctx: { - var contexts_bytes = [_]u8{0} ** aes_block_length; + var contexts_bytes: [aes_block_length]u8 = @splat(0); for (0..degree) |i| { contexts_bytes[i * 16] = @intCast(i); contexts_bytes[i * 16 + 1] = @intCast(degree - 1); @@ -509,7 +517,7 @@ fn State256X(comptime degree: u7) type { state.update(t); } if (degree > 1) { - var v = [_]u8{0} ** rate; + var v: [rate]u8 = @splat(0); switch (tag_bits) { 128 => { const tags = blocks[0].xorBlocks(blocks[1]).xorBlocks(blocks[2]).xorBlocks(blocks[3]).xorBlocks(blocks[4]).xorBlocks(blocks[5]).toBytes(); @@ -746,9 +754,7 @@ fn AegisMac(comptime T: type) type { /// Initialize a state for the MAC function, with a default nonce pub fn init(key: *const [key_length]u8) Mac { - return Mac{ - .state = T.State.init(key.*, [_]u8{0} ** nonce_length), - }; + return .{ .state = .init(key.*, @splat(0)) }; } /// Add data to the state @@ -781,7 +787,7 @@ fn AegisMac(comptime T: type) type { /// Return an authentication tag for the current state pub fn final(self: *Mac, out: *[mac_length]u8) void { if (self.off > 0) { - var pad = [_]u8{0} ** block_length; + var pad: [block_length]u8 = @splat(0); @memcpy(pad[0..self.off], self.buf[0..self.off]); self.state.absorb(&pad); } @@ -808,8 +814,8 @@ const htest = @import("test.zig"); const testing = std.testing; test "Aegis128L test vector 1" { - const key: [Aegis128L.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** 14; - const nonce: [Aegis128L.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** 13; + const key: [Aegis128L.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ @as([14]u8, @splat(0x00)); + const nonce: [Aegis128L.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ @as([13]u8, @splat(0x00)); const ad = [8]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; const m = [32]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; var c: [m.len]u8 = undefined; @@ -831,10 +837,10 @@ test "Aegis128L test vector 1" { } test "Aegis128L test vector 2" { - const key: [Aegis128L.key_length]u8 = [_]u8{0x00} ** 16; - const nonce: [Aegis128L.nonce_length]u8 = [_]u8{0x00} ** 16; - const ad = [_]u8{}; - const m = [_]u8{0x00} ** 16; + const key: [Aegis128L.key_length]u8 = @splat(0x00); + const nonce: [Aegis128L.nonce_length]u8 = @splat(0x00); + const ad: [0]u8 = .{}; + const m: [16]u8 = @splat(0x00); var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; var tag: [Aegis128L.tag_length]u8 = undefined; @@ -848,8 +854,8 @@ test "Aegis128L test vector 2" { } test "Aegis128L test vector 3" { - const key: [Aegis128L.key_length]u8 = [_]u8{0x00} ** 16; - const nonce: [Aegis128L.nonce_length]u8 = [_]u8{0x00} ** 16; + const key: [Aegis128L.key_length]u8 = @splat(0x00); + const nonce: [Aegis128L.nonce_length]u8 = @splat(0x00); const ad = [_]u8{}; const m = [_]u8{}; var c: [m.len]u8 = undefined; @@ -881,8 +887,8 @@ test "Aegis128X2 test vector 1" { } test "Aegis256 test vector 1" { - const key: [Aegis256.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** 30; - const nonce: [Aegis256.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** 29; + const key: [Aegis256.key_length]u8 = [_]u8{ 0x10, 0x01 } ++ @as([30]u8, @splat(0x00)); + const nonce: [Aegis256.nonce_length]u8 = [_]u8{ 0x10, 0x00, 0x02 } ++ @as([29]u8, @splat(0x00)); const ad = [8]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; const m = [32]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; var c: [m.len]u8 = undefined; @@ -904,10 +910,10 @@ test "Aegis256 test vector 1" { } test "Aegis256 test vector 2" { - const key: [Aegis256.key_length]u8 = [_]u8{0x00} ** 32; - const nonce: [Aegis256.nonce_length]u8 = [_]u8{0x00} ** 32; + const key: [Aegis256.key_length]u8 = @splat(0x00); + const nonce: [Aegis256.nonce_length]u8 = @splat(0x00); const ad = [_]u8{}; - const m = [_]u8{0x00} ** 16; + const m: [16]u8 = @splat(0x00); var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; var tag: [Aegis256.tag_length]u8 = undefined; @@ -921,8 +927,8 @@ test "Aegis256 test vector 2" { } test "Aegis256 test vector 3" { - const key: [Aegis256.key_length]u8 = [_]u8{0x00} ** 32; - const nonce: [Aegis256.nonce_length]u8 = [_]u8{0x00} ** 32; + const key: [Aegis256.key_length]u8 = @splat(0x00); + const nonce: [Aegis256.nonce_length]u8 = @splat(0x00); const ad = [_]u8{}; const m = [_]u8{}; var c: [m.len]u8 = undefined; @@ -954,7 +960,7 @@ test "Aegis256X4 test vector 1" { } test "Aegis MAC" { - const key = [_]u8{0x00} ** Aegis128LMac.key_length; + const key: [Aegis128LMac.key_length]u8 = @splat(0x00); var msg: [64]u8 = undefined; for (&msg, 0..) |*m, i| { m.* = @as(u8, @truncate(i)); @@ -989,8 +995,8 @@ test "Aegis MAC" { } test "AEGISMAC-128* test vectors" { - const key = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** (16 - 2); - const nonce = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** (16 - 3); + const key = [_]u8{ 0x10, 0x01 } ++ @as([16 - 2]u8, @splat(0x00)); + const nonce = [_]u8{ 0x10, 0x00, 0x02 } ++ @as([16 - 3]u8, @splat(0x00)); var msg: [35]u8 = undefined; for (&msg, 0..) |*byte, i| byte.* = @truncate(i); var mac128: [16]u8 = undefined; @@ -1013,8 +1019,8 @@ test "AEGISMAC-128* test vectors" { } test "AEGISMAC-256* test vectors" { - const key = [_]u8{ 0x10, 0x01 } ++ [_]u8{0x00} ** (32 - 2); - const nonce = [_]u8{ 0x10, 0x00, 0x02 } ++ [_]u8{0x00} ** (32 - 3); + const key = [_]u8{ 0x10, 0x01 } ++ @as([32 - 2]u8, @splat(0x00)); + const nonce = [_]u8{ 0x10, 0x00, 0x02 } ++ @as([32 - 3]u8, @splat(0x00)); var msg: [35]u8 = undefined; for (&msg, 0..) |*byte, i| byte.* = @truncate(i); var mac128: [16]u8 = undefined; diff --git a/lib/std/crypto/aes_ccm.zig b/lib/std/crypto/aes_ccm.zig @@ -201,7 +201,7 @@ fn AesCcm(comptime BlockCipher: type, comptime tag_len: usize, comptime nonce_le const total_ad_size = ad_len_size + ad.len; const remainder = total_ad_size % block_length; if (remainder > 0) { - const padding = [_]u8{0} ** block_length; + const padding: [block_length]u8 = @splat(0); ctx.update(padding[0 .. block_length - remainder]); } } @@ -264,8 +264,8 @@ const fmt = std.fmt; const hexToBytes = fmt.hexToBytes; test "Aes256Ccm8 - Encrypt decrypt round-trip" { - const key: [32]u8 = [_]u8{0x42} ** 32; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [32]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = "Hello, World! This is a test message."; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; @@ -279,8 +279,8 @@ test "Aes256Ccm8 - Encrypt decrypt round-trip" { } test "Aes256Ccm8 - Associated data" { - const key: [32]u8 = [_]u8{0x42} ** 32; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [32]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = "secret message"; const ad = "additional authenticated data"; var c: [m.len]u8 = undefined; @@ -299,9 +299,9 @@ test "Aes256Ccm8 - Associated data" { } test "Aes256Ccm8 - Wrong key" { - const key: [32]u8 = [_]u8{0x42} ** 32; - const wrong_key: [32]u8 = [_]u8{0x43} ** 32; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [32]u8 = @splat(0x42); + const wrong_key: [32]u8 = @splat(0x43); + const nonce: [13]u8 = @splat(0x11); const m = "secret"; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; @@ -314,8 +314,8 @@ test "Aes256Ccm8 - Wrong key" { } test "Aes256Ccm8 - Corrupted ciphertext" { - const key: [32]u8 = [_]u8{0x42} ** 32; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [32]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = "secret message"; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; @@ -330,8 +330,8 @@ test "Aes256Ccm8 - Corrupted ciphertext" { } test "Aes256Ccm8 - Empty plaintext" { - const key: [32]u8 = [_]u8{0x42} ** 32; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [32]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = ""; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; @@ -345,8 +345,8 @@ test "Aes256Ccm8 - Empty plaintext" { } test "Aes128Ccm8 - Basic functionality" { - const key: [16]u8 = [_]u8{0x42} ** 16; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [16]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = "Test AES-128-CCM"; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; @@ -360,8 +360,8 @@ test "Aes128Ccm8 - Basic functionality" { } test "Aes256Ccm16 - 16-byte tag" { - const key: [32]u8 = [_]u8{0x42} ** 32; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [32]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = "Test 16-byte tag"; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; @@ -845,8 +845,8 @@ test "Aes128Ccm0 - IEEE 802.15.4 Data Frame (Encryption-only)" { } test "Aes128Ccm0 - Zero-length plaintext with encryption-only" { - const key: [16]u8 = [_]u8{0x42} ** 16; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [16]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = ""; const ad = "some associated data"; var c: [m.len]u8 = undefined; @@ -861,8 +861,8 @@ test "Aes128Ccm0 - Zero-length plaintext with encryption-only" { } test "Aes256Ccm0 - Basic encryption-only round-trip" { - const key: [32]u8 = [_]u8{0x42} ** 32; - const nonce: [13]u8 = [_]u8{0x11} ** 13; + const key: [32]u8 = @splat(0x42); + const nonce: [13]u8 = @splat(0x11); const m = "Hello, CCM* encryption-only mode!"; var c: [m.len]u8 = undefined; var m2: [m.len]u8 = undefined; diff --git a/lib/std/crypto/aes_gcm.zig b/lib/std/crypto/aes_gcm.zig @@ -19,8 +19,6 @@ fn AesGcm(comptime Aes: anytype) type { pub const nonce_length = 12; pub const key_length = Aes.key_bits / 8; - const zeros = [_]u8{0} ** 16; - /// `c`: The ciphertext buffer to write the encrypted data to. /// `tag`: The authentication tag buffer to write the computed tag to. /// `m`: The plaintext message to encrypt. @@ -33,7 +31,7 @@ fn AesGcm(comptime Aes: anytype) type { const aes = Aes.initEnc(key); var h: [16]u8 = undefined; - aes.encrypt(&h, &zeros); + aes.encrypt(&h, &@splat(0)); var t: [16]u8 = undefined; var j: [16]u8 = undefined; @@ -75,7 +73,7 @@ fn AesGcm(comptime Aes: anytype) type { const aes = Aes.initEnc(key); var h: [16]u8 = undefined; - aes.encrypt(&h, &zeros); + aes.encrypt(&h, &@splat(0)); var t: [16]u8 = undefined; var j: [16]u8 = undefined; @@ -118,8 +116,8 @@ const htest = @import("test.zig"); const testing = std.testing; test "Aes256Gcm - Empty message and no associated data" { - const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; - const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; + const key: [Aes256Gcm.key_length]u8 = @splat(0x69); + const nonce: [Aes256Gcm.nonce_length]u8 = @splat(0x42); const ad = ""; const m = ""; var c: [m.len]u8 = undefined; @@ -130,8 +128,8 @@ test "Aes256Gcm - Empty message and no associated data" { } test "Aes256Gcm - Associated data only" { - const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; - const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; + const key: [Aes256Gcm.key_length]u8 = @splat(0x69); + const nonce: [Aes256Gcm.nonce_length]u8 = @splat(0x42); const m = ""; const ad = "Test with associated data"; var c: [m.len]u8 = undefined; @@ -142,8 +140,8 @@ test "Aes256Gcm - Associated data only" { } test "Aes256Gcm - Message only" { - const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; - const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; + const key: [Aes256Gcm.key_length]u8 = @splat(0x69); + const nonce: [Aes256Gcm.nonce_length]u8 = @splat(0x42); const m = "Test with message only"; const ad = ""; var c: [m.len]u8 = undefined; @@ -159,8 +157,8 @@ test "Aes256Gcm - Message only" { } test "Aes256Gcm - Message and associated data" { - const key: [Aes256Gcm.key_length]u8 = [_]u8{0x69} ** Aes256Gcm.key_length; - const nonce: [Aes256Gcm.nonce_length]u8 = [_]u8{0x42} ** Aes256Gcm.nonce_length; + const key: [Aes256Gcm.key_length]u8 = @splat(0x69); + const nonce: [Aes256Gcm.nonce_length]u8 = @splat(0x42); const m = "Test with message"; const ad = "Test with associated data"; var c: [m.len]u8 = undefined; diff --git a/lib/std/crypto/aes_ocb.zig b/lib/std/crypto/aes_ocb.zig @@ -48,7 +48,7 @@ fn AesOcb(comptime Aes: anytype) type { } fn init(aes_enc_ctx: EncryptCtx) Lx { - const zeros = [_]u8{0} ** 16; + const zeros: [16]u8 = @splat(0); var star: Block = undefined; aes_enc_ctx.encrypt(&star, &zeros); const dol = double(star); @@ -62,8 +62,8 @@ fn AesOcb(comptime Aes: anytype) type { const full_blocks: usize = a.len / 16; const x_max = if (full_blocks > 0) math.log2_int(usize, full_blocks) else 0; const lt = lx.precomp(x_max); - var sum = [_]u8{0} ** 16; - var offset = [_]u8{0} ** 16; + var sum: [16]u8 = @splat(0); + var offset: [16]u8 = @splat(0); var i: usize = 0; while (i < full_blocks) : (i += 1) { xorWith(&offset, lt[@ctz(i + 1)]); @@ -74,7 +74,7 @@ fn AesOcb(comptime Aes: anytype) type { const leftover = a.len % 16; if (leftover > 0) { xorWith(&offset, lx.star); - var padded = [_]u8{0} ** 16; + var padded: [16]u8 = @splat(0); @memcpy(padded[0..leftover], a[i * 16 ..][0..leftover]); padded[leftover] = 0x80; var e = xorBlocks(offset, padded); @@ -85,7 +85,7 @@ fn AesOcb(comptime Aes: anytype) type { } fn getOffset(aes_enc_ctx: EncryptCtx, npub: [nonce_length]u8) Block { - var nx = [_]u8{0} ** 16; + var nx: [16]u8 = @splat(0); nx[0] = @as(u8, @intCast(@as(u7, @truncate(tag_length * 8)) << 1)); nx[16 - nonce_length - 1] = 1; nx[nx.len - nonce_length ..].* = npub; @@ -121,7 +121,7 @@ fn AesOcb(comptime Aes: anytype) type { const lt = lx.precomp(x_max); var offset = getOffset(aes_enc_ctx, npub); - var sum = [_]u8{0} ** 16; + var sum: [16]u8 = @splat(0); var i: usize = 0; while (wb > 0 and i + wb <= full_blocks) : (i += wb) { @@ -155,7 +155,7 @@ fn AesOcb(comptime Aes: anytype) type { xorWith(&offset, lx.star); var pad = offset; aes_enc_ctx.encrypt(&pad, &pad); - var e = [_]u8{0} ** 16; + var e: [16]u8 = @splat(0); @memcpy(e[0..leftover], m[i * 16 ..][0..leftover]); e[leftover] = 0x80; for (m[i * 16 ..], 0..) |x, j| { @@ -188,7 +188,7 @@ fn AesOcb(comptime Aes: anytype) type { const lt = lx.precomp(x_max); var offset = getOffset(aes_enc_ctx, npub); - var sum = [_]u8{0} ** 16; + var sum: [16]u8 = @splat(0); var i: usize = 0; while (wb > 0 and i + wb <= full_blocks) : (i += wb) { @@ -226,7 +226,7 @@ fn AesOcb(comptime Aes: anytype) type { for (c[i * 16 ..], 0..) |x, j| { m[i * 16 + j] = pad[j] ^ x; } - var e = [_]u8{0} ** 16; + var e: [16]u8 = @splat(0); @memcpy(e[0..leftover], m[i * 16 ..][0..leftover]); e[leftover] = 0x80; xorWith(&sum, e); diff --git a/lib/std/crypto/argon2.zig b/lib/std/crypto/argon2.zig @@ -281,9 +281,9 @@ fn processSegment( slice: u32, lane: u24, ) void { - var addresses align(16) = [_]u64{0} ** block_length; - var in align(16) = [_]u64{0} ** block_length; - const zero align(16) = [_]u64{0} ** block_length; + var addresses: [block_length]u64 align(16) = @splat(0); + var in: [block_length]u64 align(16) = @splat(0); + const zero: [block_length]u64 align(16) = @splat(0); if (mode == .argon2i or (mode == .argon2id and n == 0 and slice < sync_points / 2)) { in[0] = n; in[1] = lane; @@ -629,10 +629,10 @@ pub fn strVerify( test "argon2d" { if (true) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/30074 - const password = [_]u8{0x01} ** 32; - const salt = [_]u8{0x02} ** 16; - const secret = [_]u8{0x03} ** 8; - const ad = [_]u8{0x04} ** 12; + const password: [32]u8 = @splat(0x01); + const salt: [16]u8 = @splat(0x02); + const secret: [8]u8 = @splat(0x03); + const ad: [12]u8 = @splat(0x04); var dk: [32]u8 = undefined; try kdf( @@ -655,10 +655,10 @@ test "argon2d" { } test "argon2i" { - const password = [_]u8{0x01} ** 32; - const salt = [_]u8{0x02} ** 16; - const secret = [_]u8{0x03} ** 8; - const ad = [_]u8{0x04} ** 12; + const password: [32]u8 = @splat(0x01); + const salt: [16]u8 = @splat(0x02); + const secret: [8]u8 = @splat(0x03); + const ad: [12]u8 = @splat(0x04); var dk: [32]u8 = undefined; try kdf( @@ -681,10 +681,10 @@ test "argon2i" { } test "argon2id" { - const password = [_]u8{0x01} ** 32; - const salt = [_]u8{0x02} ** 16; - const secret = [_]u8{0x03} ** 8; - const ad = [_]u8{0x04} ** 12; + const password: [32]u8 = @splat(0x01); + const salt: [16]u8 = @splat(0x02); + const secret: [8]u8 = @splat(0x03); + const ad: [12]u8 = @splat(0x04); var dk: [32]u8 = undefined; try kdf( diff --git a/lib/std/crypto/bcrypt.zig b/lib/std/crypto/bcrypt.zig @@ -868,20 +868,25 @@ test "bcrypt crypt format" { strVerify(s, "invalid password", verify_options), ); + const password_100: []const u8 = password: { + const arr: [100][8]u8 = @splat("password".*); + break :password @ptrCast(&arr); + }; + var long_buf: [hash_length]u8 = undefined; - var long_s = try strHash("password" ** 100, hash_options, &long_buf, io); + var long_s = try strHash(password_100, hash_options, &long_buf, io); try testing.expect(mem.startsWith(u8, long_s, crypt_format.prefix)); - try strVerify(long_s, "password" ** 100, verify_options); + try strVerify(long_s, password_100, verify_options); try testing.expectError( error.PasswordVerificationFailed, - strVerify(long_s, "password" ** 101, verify_options), + strVerify(long_s, password_100 ++ "password", verify_options), ); hash_options.params.silently_truncate_password = true; verify_options.silently_truncate_password = true; - long_s = try strHash("password" ** 100, hash_options, &long_buf, io); - try strVerify(long_s, "password" ** 101, verify_options); + long_s = try strHash(password_100, hash_options, &long_buf, io); + try strVerify(long_s, password_100 ++ "password", verify_options); try strVerify( "$2b$08$WUQKyBCaKpziCwUXHiMVvu40dYVjkTxtWJlftl0PpjY2BxWSvFIEe", @@ -909,20 +914,25 @@ test "bcrypt phc format" { strVerify(s, "invalid password", verify_options), ); + const password_100: []const u8 = password: { + const arr: [100][8]u8 = @splat("password".*); + break :password @ptrCast(&arr); + }; + var long_buf: [hash_length * 2]u8 = undefined; - var long_s = try strHash("password" ** 100, hash_options, &long_buf, io); + var long_s = try strHash(password_100, hash_options, &long_buf, io); try testing.expect(mem.startsWith(u8, long_s, prefix)); - try strVerify(long_s, "password" ** 100, verify_options); + try strVerify(long_s, password_100, verify_options); try testing.expectError( error.PasswordVerificationFailed, - strVerify(long_s, "password" ** 101, verify_options), + strVerify(long_s, password_100 ++ "password", verify_options), ); hash_options.params.silently_truncate_password = true; verify_options.silently_truncate_password = true; - long_s = try strHash("password" ** 100, hash_options, &long_buf, io); - try strVerify(long_s, "password" ** 101, verify_options); + long_s = try strHash(password_100, hash_options, &long_buf, io); + try strVerify(long_s, password_100 ++ "password", verify_options); try strVerify( "$bcrypt$r=5$2NopntlgE2lX3cTwr4qz8A$r3T7iKYQNnY4hAhGjk9RmuyvgrYJZwc", diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig @@ -173,7 +173,7 @@ const signatures = [_]Crypto{ }; pub fn benchmarkSignature(comptime Signature: anytype, comptime signatures_count: comptime_int, io: std.Io) !u64 { - const msg = [_]u8{0} ** 64; + const msg: [64]u8 = @splat(0); const key_pair = Signature.KeyPair.generate(io); const start = benchTime(io); @@ -200,7 +200,7 @@ const signature_verifications = [_]Crypto{ }; pub fn benchmarkSignatureVerification(comptime Signature: anytype, comptime signatures_count: comptime_int, io: std.Io) !u64 { - const msg = [_]u8{0} ** 64; + const msg: [64]u8 = @splat(0); const key_pair = Signature.KeyPair.generate(io); const sig = try key_pair.sign(&msg, null); @@ -223,7 +223,7 @@ pub fn benchmarkSignatureVerification(comptime Signature: anytype, comptime sign const batch_signature_verifications = [_]Crypto{Crypto{ .ty = crypto.sign.Ed25519, .name = "ed25519" }}; pub fn benchmarkBatchSignatureVerification(comptime Signature: anytype, comptime signatures_count: comptime_int, io: std.Io) !u64 { - const msg = [_]u8{0} ** 64; + const msg: [64]u8 = @splat(0); const key_pair = Signature.KeyPair.generate(io); const sig = try key_pair.sign(&msg, null); @@ -367,7 +367,7 @@ pub fn benchmarkAes(comptime Aes: anytype, comptime count: comptime_int, io: Io) random.bytes(key[0..]); const ctx = Aes.initEnc(key); - var in = [_]u8{0} ** 16; + var in: [16]u8 = @splat(0); const start = benchTime(io); { @@ -395,7 +395,7 @@ pub fn benchmarkAes8(comptime Aes: anytype, comptime count: comptime_int, io: Io random.bytes(key[0..]); const ctx = Aes.initEnc(key); - var in = [_]u8{0} ** (8 * 16); + var in: [8 * 16]u8 = @splat(0); const start = benchTime(io); { @@ -444,7 +444,7 @@ fn benchmarkPwhash( comptime count: comptime_int, io: std.Io, ) !f64 { - const password = "testpass" ** 2; + const password = "testpasstestpass"; const opts = ty.HashOptions{ .allocator = allocator, .params = @as(*const ty.Params, @ptrCast(@alignCast(params))).*, @@ -456,7 +456,7 @@ fn benchmarkPwhash( const strHashFnInfo = @typeInfo(@TypeOf(strHash)).@"fn"; const needs_io = strHashFnInfo.params.len == 4 and strHashFnInfo.params[3].type == std.Io; const needs_salt = strHashFnInfo.params.len == 4 and strHashFnInfo.params[3].type != std.Io; - const salt: [16]u8 = .{0} ** 16; + const salt: [16]u8 = @splat(0); const start = benchTime(io); { diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig @@ -199,7 +199,9 @@ test "blake2s160 single" { try htest.assertEqualHash(Blake2s160, h3, "The quick brown fox jumps over the lazy dog"); const h4 = "b60c4dc60e2681e58fbc24e77f07e02c69e72ed0"; - try htest.assertEqualHash(Blake2s160, h4, "a" ** 32 ++ "b" ** 32); + const repeat_a_32: [32]u8 = @splat('a'); + const repeat_b_32: [32]u8 = @splat('b'); + try htest.assertEqualHash(Blake2s160, h4, &repeat_a_32 ++ &repeat_b_32); } test "blake2s160 streaming" { @@ -227,27 +229,30 @@ test "blake2s160 streaming" { const h3 = "b60c4dc60e2681e58fbc24e77f07e02c69e72ed0"; + const repeat_a_32: [32]u8 = @splat('a'); + const repeat_b_32: [32]u8 = @splat('b'); + h = Blake2s160.init(.{}); - h.update("a" ** 32); - h.update("b" ** 32); + h.update(&repeat_a_32); + h.update(&repeat_b_32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2s160.init(.{}); - h.update("a" ** 32 ++ "b" ** 32); + h.update(&repeat_a_32 ++ &repeat_b_32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); const h4 = "4667fd60791a7fe41f939bca646b4529e296bd68"; - h = Blake2s160.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); - h.update("a" ** 32); - h.update("b" ** 32); + h = Blake2s160.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_32); + h.update(&repeat_b_32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2s160.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); - h.update("a" ** 32 ++ "b" ** 32); + h = Blake2s160.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_32 ++ &repeat_b_32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); } @@ -256,7 +261,7 @@ test "comptime blake2s160" { //comptime { @setEvalBranchQuota(10000); - var block = [_]u8{0} ** Blake2s160.block_length; + var block: [Blake2s160.block_length]u8 = @splat(0); var out: [Blake2s160.digest_length]u8 = undefined; const h1 = "2c56ad9d0b2c8b474aafa93ab307db2f0940105f"; @@ -282,7 +287,9 @@ test "blake2s224 single" { try htest.assertEqualHash(Blake2s224, h3, "The quick brown fox jumps over the lazy dog"); const h4 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01"; - try htest.assertEqualHash(Blake2s224, h4, "a" ** 32 ++ "b" ** 32); + const repeat_a_32: [32]u8 = @splat('a'); + const repeat_b_32: [32]u8 = @splat('b'); + try htest.assertEqualHash(Blake2s224, h4, &repeat_a_32 ++ &repeat_b_32); } test "blake2s224 streaming" { @@ -308,29 +315,32 @@ test "blake2s224 streaming" { h.final(out[0..]); try htest.assertEqual(h2, out[0..]); + const repeat_a_32: [32]u8 = @splat('a'); + const repeat_b_32: [32]u8 = @splat('b'); + const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01"; h = Blake2s224.init(.{}); - h.update("a" ** 32); - h.update("b" ** 32); + h.update(&repeat_a_32); + h.update(&repeat_b_32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2s224.init(.{}); - h.update("a" ** 32 ++ "b" ** 32); + h.update(&repeat_a_32 ++ &repeat_b_32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); const h4 = "a4d6a9d253441b80e5dfd60a04db169ffab77aec56a2855c402828c3"; - h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); - h.update("a" ** 32); - h.update("b" ** 32); + h = Blake2s224.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_32); + h.update(&repeat_b_32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); - h.update("a" ** 32 ++ "b" ** 32); + h = Blake2s224.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_32 ++ &repeat_b_32); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); } @@ -338,7 +348,7 @@ test "blake2s224 streaming" { test "comptime blake2s224" { comptime { @setEvalBranchQuota(10000); - var block = [_]u8{0} ** Blake2s224.block_length; + var block: [Blake2s224.block_length]u8 = @splat(0); var out: [Blake2s224.digest_length]u8 = undefined; const h1 = "86b7611563293f8c73627df7a6d6ba25ca0548c2a6481f7d116ee576"; @@ -364,7 +374,9 @@ test "blake2s256 single" { try htest.assertEqualHash(Blake2s256, h3, "The quick brown fox jumps over the lazy dog"); const h4 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977"; - try htest.assertEqualHash(Blake2s256, h4, "a" ** 32 ++ "b" ** 32); + const repeat_a_32: [32]u8 = @splat('a'); + const repeat_b_32: [32]u8 = @splat('b'); + try htest.assertEqualHash(Blake2s256, h4, &repeat_a_32 ++ &repeat_b_32); } test "blake2s256 streaming" { @@ -390,16 +402,19 @@ test "blake2s256 streaming" { h.final(out[0..]); try htest.assertEqual(h2, out[0..]); + const repeat_a_32: [32]u8 = @splat('a'); + const repeat_b_32: [32]u8 = @splat('b'); + const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977"; h = Blake2s256.init(.{}); - h.update("a" ** 32); - h.update("b" ** 32); + h.update(&repeat_a_32); + h.update(&repeat_b_32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2s256.init(.{}); - h.update("a" ** 32 ++ "b" ** 32); + h.update(&repeat_a_32 ++ &repeat_b_32); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); } @@ -410,18 +425,21 @@ test "blake2s256 keyed" { const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6"; const key = "secret_key"; - Blake2s256.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + + Blake2s256.hash(&repeat_a_64 ++ &repeat_b_64, &out, .{ .key = key }); try htest.assertEqual(h1, out[0..]); var h = Blake2s256.init(.{ .key = key }); - h.update("a" ** 64 ++ "b" ** 64); + h.update(&repeat_a_64 ++ &repeat_b_64); h.final(out[0..]); try htest.assertEqual(h1, out[0..]); h = Blake2s256.init(.{ .key = key }); - h.update("a" ** 64); - h.update("b" ** 64); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h1, out[0..]); @@ -430,7 +448,7 @@ test "blake2s256 keyed" { test "comptime blake2s256" { comptime { @setEvalBranchQuota(10000); - var block = [_]u8{0} ** Blake2s256.block_length; + var block: [Blake2s256.block_length]u8 = @splat(0); var out: [Blake2s256.digest_length]u8 = undefined; const h1 = "ae09db7cd54f42b490ef09b6bc541af688e4959bb8c53f359a6f56e38ab454a3"; @@ -623,7 +641,9 @@ test "blake2b160 single" { try htest.assertEqualHash(Blake2b160, h3, "The quick brown fox jumps over the lazy dog"); const h4 = "43758f5de1740f651f1ae39de92260fe8bd5a11f"; - try htest.assertEqualHash(Blake2b160, h4, "a" ** 64 ++ "b" ** 64); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + try htest.assertEqualHash(Blake2b160, h4, &repeat_a_64 ++ &repeat_b_64); } test "blake2b160 streaming" { @@ -649,36 +669,39 @@ test "blake2b160 streaming" { h.final(out[0..]); try htest.assertEqual(h2, out[0..]); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + const h3 = "43758f5de1740f651f1ae39de92260fe8bd5a11f"; h = Blake2b160.init(.{}); - h.update("a" ** 64 ++ "b" ** 64); + h.update(&repeat_a_64 ++ &repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2b160.init(.{}); - h.update("a" ** 64); - h.update("b" ** 64); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2b160.init(.{}); - h.update("a" ** 64); - h.update("b" ** 64); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); const h4 = "72328f8a8200663752fc302d372b5dd9b49dd8dc"; - h = Blake2b160.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); - h.update("a" ** 64); - h.update("b" ** 64); + h = Blake2b160.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2b160.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); - h.update("a" ** 64); - h.update("b" ** 64); + h = Blake2b160.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); } @@ -686,7 +709,7 @@ test "blake2b160 streaming" { test "comptime blake2b160" { comptime { @setEvalBranchQuota(10000); - var block = [_]u8{0} ** Blake2b160.block_length; + var block: [Blake2b160.block_length]u8 = @splat(0); var out: [Blake2b160.digest_length]u8 = undefined; const h1 = "8d26f158f564e3293b42f5e3d34263cb173aa9c9"; @@ -712,7 +735,9 @@ test "blake2b384 single" { try htest.assertEqualHash(Blake2b384, h3, "The quick brown fox jumps over the lazy dog"); const h4 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c"; - try htest.assertEqualHash(Blake2b384, h4, "a" ** 64 ++ "b" ** 64); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + try htest.assertEqualHash(Blake2b384, h4, &repeat_a_64 ++ &repeat_b_64); } test "blake2b384 streaming" { @@ -738,36 +763,39 @@ test "blake2b384 streaming" { h.final(out[0..]); try htest.assertEqual(h2, out[0..]); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c"; h = Blake2b384.init(.{}); - h.update("a" ** 64 ++ "b" ** 64); + h.update(&repeat_a_64 ++ &repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2b384.init(.{}); - h.update("a" ** 64); - h.update("b" ** 64); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2b384.init(.{}); - h.update("a" ** 64); - h.update("b" ** 64); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); const h4 = "934c48fcb197031c71f583d92f98703510805e72142e0b46f5752d1e971bc86c355d556035613ff7a4154b4de09dac5c"; - h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); - h.update("a" ** 64); - h.update("b" ** 64); + h = Blake2b384.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); - h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); - h.update("a" ** 64); - h.update("b" ** 64); + h = Blake2b384.init(.{ .context = @splat(0x69), .salt = @splat(0x42) }); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h4, out[0..]); } @@ -775,7 +803,7 @@ test "blake2b384 streaming" { test "comptime blake2b384" { comptime { @setEvalBranchQuota(20000); - var block = [_]u8{0} ** Blake2b384.block_length; + var block: [Blake2b384.block_length]u8 = @splat(0); var out: [Blake2b384.digest_length]u8 = undefined; const h1 = "e8aa1931ea0422e4446fecdd25c16cf35c240b10cb4659dd5c776eddcaa4d922397a589404b46eb2e53d78132d05fd7d"; @@ -801,7 +829,9 @@ test "blake2b512 single" { try htest.assertEqualHash(Blake2b512, h3, "The quick brown fox jumps over the lazy dog"); const h4 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920"; - try htest.assertEqualHash(Blake2b512, h4, "a" ** 64 ++ "b" ** 64); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + try htest.assertEqualHash(Blake2b512, h4, &repeat_a_64 ++ &repeat_b_64); } test "blake2b512 streaming" { @@ -827,16 +857,19 @@ test "blake2b512 streaming" { h.final(out[0..]); try htest.assertEqual(h2, out[0..]); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920"; h = Blake2b512.init(.{}); - h.update("a" ** 64 ++ "b" ** 64); + h.update(&repeat_a_64 ++ &repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); h = Blake2b512.init(.{}); - h.update("a" ** 64); - h.update("b" ** 64); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h3, out[0..]); } @@ -847,18 +880,21 @@ test "blake2b512 keyed" { const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d"; const key = "secret_key"; - Blake2b512.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); + const repeat_a_64: [64]u8 = @splat('a'); + const repeat_b_64: [64]u8 = @splat('b'); + + Blake2b512.hash(&repeat_a_64 ++ &repeat_b_64, &out, .{ .key = key }); try htest.assertEqual(h1, out[0..]); var h = Blake2b512.init(.{ .key = key }); - h.update("a" ** 64 ++ "b" ** 64); + h.update(&repeat_a_64 ++ &repeat_b_64); h.final(out[0..]); try htest.assertEqual(h1, out[0..]); h = Blake2b512.init(.{ .key = key }); - h.update("a" ** 64); - h.update("b" ** 64); + h.update(&repeat_a_64); + h.update(&repeat_b_64); h.final(out[0..]); try htest.assertEqual(h1, out[0..]); @@ -867,7 +903,7 @@ test "blake2b512 keyed" { test "comptime blake2b512" { comptime { @setEvalBranchQuota(12000); - var block = [_]u8{0} ** Blake2b512.block_length; + var block: [Blake2b512.block_length]u8 = @splat(0); var out: [Blake2b512.digest_length]u8 = undefined; const h1 = "865939e120e6805438478841afb739ae4250cf372653078a065cdcfffca4caf798e6d462b65d658fc165782640eded70963449ae1500fb0f24981d7727e22c41"; diff --git a/lib/std/crypto/cbc_mac.zig b/lib/std/crypto/cbc_mac.zig @@ -21,7 +21,7 @@ pub fn CbcMac(comptime BlockCipher: type) type { pub const mac_length = block_length; cipher_ctx: BlockCipherCtx, - buf: Block = [_]u8{0} ** block_length, + buf: Block = @splat(0), pos: usize = 0, pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void { diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig @@ -648,7 +648,7 @@ fn ChaChaPoly1305(comptime rounds_nb: usize) type { assert(c.len == m.len); assert(m.len <= 64 * (@as(u39, 1 << 32) - 1)); - var polyKey = [_]u8{0} ** 32; + var polyKey: [32]u8 = @splat(0); ChaChaIETF(rounds_nb).xor(polyKey[0..], polyKey[0..], 0, k, npub); ChaChaIETF(rounds_nb).xor(c[0..m.len], m, 1, k, npub); @@ -656,13 +656,13 @@ fn ChaChaPoly1305(comptime rounds_nb: usize) type { var mac = Poly1305.init(polyKey[0..]); mac.update(ad); if (ad.len % 16 != 0) { - const zeros = [_]u8{0} ** 16; + const zeros: [16]u8 = @splat(0); const padding = 16 - (ad.len % 16); mac.update(zeros[0..padding]); } mac.update(c[0..m.len]); if (m.len % 16 != 0) { - const zeros = [_]u8{0} ** 16; + const zeros: [16]u8 = @splat(0); const padding = 16 - (m.len % 16); mac.update(zeros[0..padding]); } @@ -685,20 +685,20 @@ fn ChaChaPoly1305(comptime rounds_nb: usize) type { pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { assert(c.len == m.len); - var polyKey = [_]u8{0} ** 32; + var polyKey: [32]u8 = @splat(0); ChaChaIETF(rounds_nb).xor(polyKey[0..], polyKey[0..], 0, k, npub); var mac = Poly1305.init(polyKey[0..]); mac.update(ad); if (ad.len % 16 != 0) { - const zeros = [_]u8{0} ** 16; + const zeros: [16]u8 = @splat(0); const padding = 16 - (ad.len % 16); mac.update(zeros[0..padding]); } mac.update(c); if (c.len % 16 != 0) { - const zeros = [_]u8{0} ** 16; + const zeros: [16]u8 = @splat(0); const padding = 16 - (c.len % 16); mac.update(zeros[0..padding]); } @@ -759,8 +759,8 @@ test "AEAD API" { const ad = "Additional data"; inline for (aeads) |aead| { - const key = [_]u8{69} ** aead.key_length; - const nonce = [_]u8{42} ** aead.nonce_length; + const key: [aead.key_length]u8 = @splat(69); + const nonce: [aead.nonce_length]u8 = @splat(42); var c: [m.len]u8 = undefined; var tag: [aead.tag_length]u8 = undefined; var out: [m.len]u8 = undefined; @@ -1138,8 +1138,8 @@ test "open" { } test "xchacha20" { - const key = [_]u8{69} ** 32; - const nonce = [_]u8{42} ** 24; + const key: [32]u8 = @splat(69); + const nonce: [24]u8 = @splat(42); const m = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; { var c: [m.len]u8 = undefined; diff --git a/lib/std/crypto/cmac.zig b/lib/std/crypto/cmac.zig @@ -20,7 +20,7 @@ pub fn Cmac(comptime BlockCipher: type) type { cipher_ctx: BlockCipherCtx, k1: Block, k2: Block, - buf: Block = [_]u8{0} ** block_length, + buf: Block = @splat(0), pos: usize = 0, pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void { @@ -31,7 +31,7 @@ pub fn Cmac(comptime BlockCipher: type) type { pub fn init(key: *const [key_length]u8) Self { const cipher_ctx = BlockCipher.initEnc(key.*); - const zeros = [_]u8{0} ** block_length; + const zeros: [block_length]u8 = @splat(0); var k1: Block = undefined; cipher_ctx.encrypt(&k1, &zeros); k1 = double(k1); diff --git a/lib/std/crypto/codecs/asn1.zig b/lib/std/crypto/codecs/asn1.zig @@ -233,7 +233,7 @@ test Element { .slice = Element.Slice{ .start = 2, .end = short_form.len }, }, Element.decode(&short_form, 0)); - const long_form = [_]u8{ 0x30, 129, 129 } ++ [_]u8{0} ** 129; + const long_form = [_]u8{ 0x30, 129, 129 } ++ @as([129]u8, @splat(0)); try std.testing.expectEqual(Element{ .tag = Tag.universal(.sequence, true), .slice = Element.Slice{ .start = 3, .end = long_form.len }, diff --git a/lib/std/crypto/ecdsa.zig b/lib/std/crypto/ecdsa.zig @@ -212,7 +212,7 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { fn finalizePrehashed(self: *Signer, msg_hash: [Hash.digest_length]u8) (IdentityElementError || NonCanonicalError)!Signature { const scalar_encoded_length = Curve.scalar.encoded_length; const h_len = @max(Hash.digest_length, scalar_encoded_length); - var h: [h_len]u8 = [_]u8{0} ** (h_len - Hash.digest_length) ++ msg_hash; + var h: [h_len]u8 = @as([h_len - Hash.digest_length]u8, @splat(0)) ++ msg_hash; std.debug.assert(h.len >= scalar_encoded_length); const z = reduceToScalar(scalar_encoded_length, h[0..scalar_encoded_length].*); @@ -275,7 +275,7 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { fn verifyPrehashed(self: *Verifier, msg_hash: [Hash.digest_length]u8) VerifyError!void { const ht = Curve.scalar.encoded_length; const h_len = @max(Hash.digest_length, ht); - var h: [h_len]u8 = [_]u8{0} ** (h_len - Hash.digest_length) ++ msg_hash; + var h: [h_len]u8 = @as([h_len - Hash.digest_length]u8, @splat(0)) ++ msg_hash; const z = reduceToScalar(ht, h[0..ht].*); if (z.isZero()) { @@ -316,8 +316,8 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { /// /// Except in tests, applications should generally call `generate()` instead of this function. pub fn generateDeterministic(seed: [seed_length]u8) IdentityElementError!KeyPair { - const h = [_]u8{0x00} ** Hash.digest_length; - const k0 = [_]u8{0x01} ** SecretKey.encoded_length; + const h: [Hash.digest_length]u8 = @splat(0x00); + const k0: [SecretKey.encoded_length]u8 = @splat(0x01); const secret_key = deterministicScalar(h, k0, seed).toBytes(.big); return fromSecretKey(SecretKey{ .bytes = secret_key }); } @@ -367,11 +367,11 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { // Reduce the coordinate of a field element to the scalar field. fn reduceToScalar(comptime unreduced_len: usize, s: [unreduced_len]u8) Curve.scalar.Scalar { if (unreduced_len >= 48) { - var xs = [_]u8{0} ** 64; + var xs: [64]u8 = @splat(0); @memcpy(xs[xs.len - s.len ..], s[0..]); return Curve.scalar.Scalar.fromBytes64(xs, .big); } - var xs = [_]u8{0} ** 48; + var xs: [48]u8 = @splat(0); @memcpy(xs[xs.len - s.len ..], s[0..]); return Curve.scalar.Scalar.fromBytes48(xs, .big); } @@ -379,9 +379,9 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type { // Create a deterministic scalar according to a secret key and optional noise. // This uses the overly conservative scheme from the "Deterministic ECDSA and EdDSA Signatures with Additional Randomness" draft. fn deterministicScalar(h: [Hash.digest_length]u8, secret_key: Curve.scalar.CompressedScalar, noise: ?[noise_length]u8) Curve.scalar.Scalar { - var k = [_]u8{0x00} ** h.len; - var m = [_]u8{0x00} ** (h.len + 1 + noise_length + secret_key.len + h.len); - var t = [_]u8{0x00} ** Curve.scalar.encoded_length; + var k: [h.len]u8 = @splat(0); + var m: [h.len + 1 + noise_length + secret_key.len + h.len]u8 = @splat(0); + var t: [Curve.scalar.encoded_length]u8 = @splat(0); const m_v = m[0..h.len]; const m_i = &m[m_v.len]; const m_z = m[m_v.len + 1 ..][0..noise_length]; diff --git a/lib/std/crypto/ff.zig b/lib/std/crypto/ff.zig @@ -96,7 +96,7 @@ pub fn Uint(comptime max_bits: comptime_int) type { /// The zero integer. pub const zero: Self = .{ - .limbs_buffer = [1]Limb{0} ** max_limbs_count, + .limbs_buffer = @splat(0), .limbs_len = max_limbs_count, }; @@ -738,7 +738,7 @@ pub fn Modulus(comptime max_bits: comptime_int) type { } } else { // Use a precomputation table for large exponents - var pc = [1]Fe{x} ++ [_]Fe{self.zero} ** 14; + var pc: [15]Fe = [1]Fe{x} ++ @as([14]Fe, @splat(self.zero)); if (!x.montgomery) { self.toMontgomery(&pc[0]) catch unreachable; } diff --git a/lib/std/crypto/ghash_polyval.zig b/lib/std/crypto/ghash_polyval.zig @@ -417,8 +417,8 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type { const htest = @import("test.zig"); test "ghash" { - const key = [_]u8{0x42} ** 16; - const m = [_]u8{0x69} ** 256; + const key: [16]u8 = @splat(0x42); + const m: [256]u8 = @splat(0x69); var st = Ghash.init(&key); st.update(&m); @@ -467,8 +467,8 @@ test "ghash2" { } test "polyval" { - const key = [_]u8{0x42} ** 16; - const m = [_]u8{0x69} ** 256; + const key: [16]u8 = @splat(0x42); + const m: [256]u8 = @splat(0x69); var st = Polyval.init(&key); st.update(&m); diff --git a/lib/std/crypto/hkdf.zig b/lib/std/crypto/hkdf.zig @@ -72,7 +72,7 @@ pub fn Hkdf(comptime Hmac: type) type { const htest = @import("test.zig"); test "Hkdf" { - const ikm = [_]u8{0x0b} ** 22; + const ikm: [22]u8 = @splat(0x0b); const salt = [_]u8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; const context = [_]u8{ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; const kdf = HkdfSha256; diff --git a/lib/std/crypto/isap.zig b/lib/std/crypto/isap.zig @@ -42,7 +42,7 @@ pub const IsapA128A = struct { break; } } else { - var padded = [_]u8{0} ** 8; + var padded: [8]u8 = @splat(0); @memcpy(padded[0..left], m[i..]); padded[left] = 0x80; isap.st.addBytes(&padded); @@ -169,8 +169,8 @@ pub const IsapA128A = struct { }; test "ISAP" { - const k = [_]u8{1} ** 16; - const n = [_]u8{2} ** 16; + const k: [16]u8 = @splat(1); + const n: [16]u8 = @splat(2); var tag: [16]u8 = undefined; const ad = "ad"; var msg = "test"; diff --git a/lib/std/crypto/kangarootwelve.zig b/lib/std/crypto/kangarootwelve.zig @@ -881,7 +881,7 @@ fn ktMultiThreaded( // Buffer for out-of-order results (select_buf slots get reused) const pending_cv_buf = try allocator.alloc([leaves_per_batch * cv_size]u8, max_concurrent); defer allocator.free(pending_cv_buf); - var pending_cv_lens: [256]usize = .{0} ** 256; + var pending_cv_lens: [256]usize = @splat(0); var select_outstanding: usize = 0; var select: Select = .init(io, select_buf); diff --git a/lib/std/crypto/keccak_p.zig b/lib/std/crypto/keccak_p.zig @@ -40,7 +40,7 @@ pub fn KeccakF(comptime f: u11) type { break :rc rc; }; - st: Block = [_]T{0} ** 25, + st: Block = @splat(0), /// Initialize the state from a slice of bytes. pub fn init(bytes: [block_bytes]u8) Self { @@ -70,7 +70,7 @@ pub fn KeccakF(comptime f: u11) type { self.st[i / @sizeOf(T)] = mem.readInt(T, bytes[i..][0..@sizeOf(T)], .little); } if (i < bytes.len) { - var padded = [_]u8{0} ** @sizeOf(T); + var padded: [@sizeOf(T)]u8 = @splat(0); @memcpy(padded[0 .. bytes.len - i], bytes[i..]); self.st[i / @sizeOf(T)] = mem.readInt(T, padded[0..], .little); } @@ -89,7 +89,7 @@ pub fn KeccakF(comptime f: u11) type { self.st[i / @sizeOf(T)] ^= mem.readInt(T, bytes[i..][0..@sizeOf(T)], .little); } if (i < bytes.len) { - var padded = [_]u8{0} ** @sizeOf(T); + var padded: [@sizeOf(T)]u8 = @splat(0); @memcpy(padded[0 .. bytes.len - i], bytes[i..]); self.st[i / @sizeOf(T)] ^= mem.readInt(T, padded[0..], .little); } @@ -102,7 +102,7 @@ pub fn KeccakF(comptime f: u11) type { mem.writeInt(T, out[i..][0..@sizeOf(T)], self.st[i / @sizeOf(T)], .little); } if (i < out.len) { - var padded = [_]u8{0} ** @sizeOf(T); + var padded: [@sizeOf(T)]u8 = @splat(0); mem.writeInt(T, padded[0..], self.st[i / @sizeOf(T)], .little); @memcpy(out[i..], padded[0 .. out.len - i]); } @@ -118,7 +118,7 @@ pub fn KeccakF(comptime f: u11) type { mem.writeInt(T, out[i..][0..@sizeOf(T)], x, native_endian); } if (i < in.len) { - var padded = [_]u8{0} ** @sizeOf(T); + var padded: [@sizeOf(T)]u8 = @splat(0); @memcpy(padded[0 .. in.len - i], in[i..]); const x = mem.readInt(T, &padded, native_endian) ^ mem.nativeToLittle(T, self.st[i / @sizeOf(T)]); mem.writeInt(T, &padded, x, native_endian); @@ -140,7 +140,7 @@ pub fn KeccakF(comptime f: u11) type { const st = &self.st; // theta - var t = [_]T{0} ** 5; + var t: [5]T = @splat(0); inline for (0..5) |i| { inline for (0..5) |j| { t[i] ^= st[j * 5 + i]; @@ -382,7 +382,7 @@ test "Keccak-f800" { } test "squeeze" { - var st = State(800, 256, 22).init([_]u8{0x80} ** 100, 0x01); + var st: State(800, 256, 22) = .init(@splat(0x80), 0x01); var out0: [15]u8 = undefined; var out1: [out0.len]u8 = undefined; diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig @@ -272,7 +272,7 @@ test "streaming" { } test "aligned final" { - var block = [_]u8{0} ** Md5.block_length; + const block: [Md5.block_length]u8 = @splat(0); var out: [Md5.digest_length]u8 = undefined; var h = Md5.init(.{}); diff --git a/lib/std/crypto/ml_dsa.zig b/lib/std/crypto/ml_dsa.zig @@ -156,7 +156,7 @@ const Params = struct { const Poly = struct { cs: [N]u32, - const zero: Poly = .{ .cs = .{0} ** N }; + const zero: Poly = .{ .cs = @splat(0) }; // Add two polynomials (no normalization) fn add(a: Poly, b: Poly) Poly { @@ -302,7 +302,7 @@ fn PolyVec(comptime len: u8) type { ps: [len]Poly, const Self = @This(); - const zero: Self = .{ .ps = .{Poly.zero} ** len }; + const zero: Self = .{ .ps = @splat(.zero) }; /// Apply a unary operation to each polynomial in the vector fn map(v: Self, comptime op: fn (Poly) Poly) Self { @@ -581,7 +581,7 @@ fn PolyVec(comptime len: u8) type { /// Unpack hints from bytes fn unpackHint(comptime omega: u16, buf: []const u8) ?Self { - var result: Self = .{ .ps = .{Poly.zero} ** len }; + var result: Self = .{ .ps = @splat(.zero) }; var prev_sop: u8 = 0; // previous switch-over-point for (0..len) |i| { @@ -1839,7 +1839,7 @@ fn MLDSAImpl(comptime p: Params) type { return Signer{ .h = h, .secret_key = secret_key, - .rnd = noise orelse .{0} ** 32, + .rnd = noise orelse @splat(0), }; } @@ -2324,7 +2324,7 @@ test "decompose correctness for ML-DSA-87" { test "polyDeriveUniform deterministic" { // Test that polyDeriveUniform produces deterministic results - const seed: [32]u8 = .{0x01} ++ .{0x00} ** 31; + const seed: [32]u8 = .{0x01} ++ @as([31]u8, @splat(0x00)); const nonce: u16 = 0; const p1 = polyDeriveUniform(&seed, nonce); @@ -2343,7 +2343,7 @@ test "polyDeriveUniform deterministic" { test "polyDeriveUniform different nonces" { // Test that different nonces produce different polynomials - const seed: [32]u8 = .{0x01} ++ .{0x00} ** 31; + const seed: [32]u8 = .{0x01} ++ @as([31]u8, @splat(0x00)); const p1 = polyDeriveUniform(&seed, 0); const p2 = polyDeriveUniform(&seed, 1); @@ -2361,7 +2361,7 @@ test "polyDeriveUniform different nonces" { test "expandS with eta=2" { // Test eta=2 sampling - const seed: [64]u8 = .{0x02} ++ .{0x00} ** 63; + const seed: [64]u8 = .{0x02} ++ @as([63]u8, @splat(0x00)); const nonce: u16 = 0; const p = expandS(2, &seed, nonce); @@ -2378,7 +2378,7 @@ test "expandS with eta=2" { test "expandS with eta=4" { // Test eta=4 sampling - const seed: [64]u8 = .{0x03} ++ .{0x00} ** 63; + const seed: [64]u8 = .{0x03} ++ @as([63]u8, @splat(0x00)); const nonce: u16 = 0; const p = expandS(4, &seed, nonce); @@ -2395,7 +2395,7 @@ test "expandS with eta=4" { test "sampleInBall has correct weight" { // Test that ball polynomial has exactly tau non-zero coefficients const tau = 39; // From ML-DSA-44 - const seed: [32]u8 = .{0x04} ++ .{0x00} ** 31; + const seed: [32]u8 = .{0x03} ++ @as([31]u8, @splat(0x00)); const p = sampleInBall(tau, &seed); @@ -2415,7 +2415,7 @@ test "sampleInBall has correct weight" { test "sampleInBall deterministic" { // Test that ball sampling is deterministic const tau = 49; // From ML-DSA-65 - const seed: [32]u8 = .{0x05} ++ .{0x00} ** 31; + const seed: [32]u8 = .{0x05} ++ @as([31]u8, @splat(0x00)); const p1 = sampleInBall(tau, &seed); const p2 = sampleInBall(tau, &seed); @@ -2851,13 +2851,13 @@ test "Key generation basic - all variants" { .{ .variant = MLDSA65, .seed_byte = 0x65 }, .{ .variant = MLDSA87, .seed_byte = 0x87 }, }) |config| { - const seed = [_]u8{config.seed_byte} ** 32; + const seed: [32]u8 = @splat(config.seed_byte); try testKeyGenerationBasic(config.variant, seed); } } test "Key generation determinism" { - const seed = [_]u8{ 0x12, 0x34, 0x56, 0x78 } ++ [_]u8{0xAB} ** 28; + const seed = [_]u8{ 0x12, 0x34, 0x56, 0x78 } ++ @as([28]u8, @splat(0xAB)); // Generate two key pairs from the same seed const result1 = MLDSA44.newKeyFromSeed(&seed); @@ -2874,7 +2874,7 @@ test "Key generation determinism" { } test "Private key can compute public key" { - const seed = [_]u8{0xFF} ** 32; + const seed: [32]u8 = @splat(0xFF); const result = MLDSA44.newKeyFromSeed(&seed); const pk = result.pk; const sk = result.sk; @@ -2907,13 +2907,13 @@ test "Sign and verify - all variants" { .{ .variant = MLDSA65, .seed_byte = 0x65, .message = "Hello, ML-DSA-65!" }, .{ .variant = MLDSA87, .seed_byte = 0x87, .message = "Hello, ML-DSA-87!" }, }) |config| { - const seed = [_]u8{config.seed_byte} ** 32; + const seed: [32]u8 = @splat(config.seed_byte); try testSignAndVerify(config.variant, seed, config.message); } } test "Invalid signature rejection" { - const seed = [_]u8{0x99} ** 32; + const seed: [32]u8 = @splat(0x99); const result = MLDSA44.newKeyFromSeed(&seed); const kp = try MLDSA44.KeyPair.fromSecretKey(result.sk); @@ -2934,7 +2934,7 @@ test "Invalid signature rejection" { } test "Context string support" { - const seed = [_]u8{0xAA} ** 32; + const seed: [32]u8 = @splat(0xAA); const result = MLDSA44.newKeyFromSeed(&seed); const kp = try MLDSA44.KeyPair.fromSecretKey(result.sk); @@ -2964,17 +2964,17 @@ test "Context string support" { try testing.expectError(error.SignatureVerificationFailed, sig2.verifyWithContext(message, kp.public_key, context1)); // Test maximum context length (255 bytes) - const max_context = [_]u8{0xBB} ** 255; + const max_context: [255]u8 = @splat(0xBB); const sig3 = try kp.signWithContext(message, null, &max_context); try sig3.verifyWithContext(message, kp.public_key, &max_context); // Test context too long (256 bytes should fail) - const too_long_context = [_]u8{0xCC} ** 256; + const too_long_context: [256]u8 = @splat(0xCC); try testing.expectError(error.ContextTooLong, kp.signWithContext(message, null, &too_long_context)); } test "Context string with streaming API" { - const seed = [_]u8{0xDD} ** 32; + const seed: [32]u8 = @splat(0xDD); const result = MLDSA44.newKeyFromSeed(&seed); const kp = try MLDSA44.KeyPair.fromSecretKey(result.sk); @@ -3002,12 +3002,12 @@ test "Context string with streaming API" { } test "Signature determinism (same rnd)" { - const seed = [_]u8{0x11} ** 32; + const seed: [32]u8 = @splat(0x11); const result = MLDSA44.newKeyFromSeed(&seed); const sk = result.sk; const message = "Deterministic test"; - const rnd = [_]u8{0x22} ** 32; + const rnd: [32]u8 = @splat(0x22); // Sign twice with same randomness using streaming API var st1 = try sk.signer(rnd); @@ -3023,7 +3023,7 @@ test "Signature determinism (same rnd)" { } test "Signature toBytes/fromBytes roundtrip" { - const seed = [_]u8{0x33} ** 32; + const seed: [32]u8 = @splat(0x33); const result = MLDSA44.newKeyFromSeed(&seed); const kp = try MLDSA44.KeyPair.fromSecretKey(result.sk); @@ -3043,7 +3043,7 @@ test "Signature toBytes/fromBytes roundtrip" { } test "Empty message signing" { - const seed = [_]u8{0x44} ** 32; + const seed: [32]u8 = @splat(0x44); const result = MLDSA44.newKeyFromSeed(&seed); const kp = try MLDSA44.KeyPair.fromSecretKey(result.sk); @@ -3057,12 +3057,12 @@ test "Empty message signing" { } test "Long message signing" { - const seed = [_]u8{0x55} ** 32; + const seed: [32]u8 = @splat(0x55); const result = MLDSA44.newKeyFromSeed(&seed); const kp = try MLDSA44.KeyPair.fromSecretKey(result.sk); // Create a long message (1KB) - const long_message = [_]u8{0xAB} ** 1024; + const long_message: [1024]u8 = @splat(0xAB); // Sign long message const sig = try kp.sign(&long_message, null); @@ -3209,7 +3209,7 @@ test "KeyPair API - generate and sign" { test "KeyPair API - generateDeterministic" { // Test deterministic key generation - const seed = [_]u8{42} ** 32; + const seed: [32]u8 = @splat(42); const kp1 = try MLDSA44.KeyPair.generateDeterministic(seed); const kp2 = try MLDSA44.KeyPair.generateDeterministic(seed); @@ -3240,7 +3240,7 @@ test "Signature verification with noise" { const msg = "Message to be signed with randomness"; // Create some noise - const noise = [_]u8{ 1, 2, 3, 4, 5 } ++ [_]u8{0} ** 27; + const noise = [_]u8{ 1, 2, 3, 4, 5 } ++ @as([27]u8, @splat(0)); // Sign with noise const sig = try kp.sign(msg, noise); @@ -3262,7 +3262,7 @@ test "Signature verification failure" { } test "Streaming API - sign and verify" { - const seed = [_]u8{0x55} ** 32; + const seed: [32]u8 = @splat(0x55); const kp = try MLDSA44.KeyPair.generateDeterministic(seed); const msg = "Test message for streaming API"; @@ -3279,7 +3279,7 @@ test "Streaming API - sign and verify" { } test "Streaming API - chunked message" { - const seed = [_]u8{0x66} ** 32; + const seed: [32]u8 = @splat(0x66); const kp = try MLDSA44.KeyPair.generateDeterministic(seed); // Create a message in chunks @@ -3313,7 +3313,7 @@ test "Streaming API - chunked message" { } test "Streaming API - large message" { - const seed = [_]u8{0x77} ** 32; + const seed: [32]u8 = @splat(0x77); const kp = try MLDSA44.KeyPair.generateDeterministic(seed); // Create a large message (1MB) @@ -3344,7 +3344,7 @@ test "Streaming API - all parameter sets" { // ML-DSA-44 { - const seed = [_]u8{0x44} ** 32; + const seed: [32]u8 = @splat(0x44); const kp = try MLDSA44.KeyPair.generateDeterministic(seed); var signer = try kp.signer(null); signer.update(test_msg); @@ -3356,7 +3356,7 @@ test "Streaming API - all parameter sets" { // ML-DSA-65 { - const seed = [_]u8{0x65} ** 32; + const seed: [32]u8 = @splat(0x65); const kp = try MLDSA65.KeyPair.generateDeterministic(seed); var signer = try kp.signer(null); signer.update(test_msg); @@ -3368,7 +3368,7 @@ test "Streaming API - all parameter sets" { // ML-DSA-87 { - const seed = [_]u8{0x87} ** 32; + const seed: [32]u8 = @splat(0x87); const kp = try MLDSA87.KeyPair.generateDeterministic(seed); var signer = try kp.signer(null); signer.update(test_msg); diff --git a/lib/std/crypto/ml_kem.zig b/lib/std/crypto/ml_kem.zig @@ -615,7 +615,7 @@ const inv_ntt_reductions = [_]i16{ test "invNTTReductions bounds" { // Checks whether the reductions proposed by invNTTReductions // don't overflow during invNTT(). - var xs = [_]i32{1} ** 256; // start at |x| ≤ q + var xs: [256]i32 = @splat(1); // start at |x| ≤ q var r: usize = 0; var layer: math.Log2Int(usize) = 1; @@ -797,7 +797,7 @@ const Poly = struct { cs: [N]i16, const encoded_length = N / 2 * 3; - const zero: Poly = .{ .cs = .{0} ** N }; + const zero: Poly = .{ .cs = @splat(0) }; // Add two polynomials (coefficients not normalized) fn add(a: Poly, b: Poly) Poly { @@ -1011,7 +1011,7 @@ const Poly = struct { const out_length: usize = comptime @divTrunc(N * d, 8); comptime assert(out_length * 8 == d * N); - var out = [_]u8{0} ** out_length; + var out: [out_length]u8 = @splat(0); while (in_off < N) { // First we compress into in. @@ -1754,7 +1754,7 @@ const NistDRBG = struct { } fn init(seed: [48]u8) NistDRBG { - var ret: NistDRBG = .{ .key = .{0} ** 32, .v = .{0} ** 16 }; + var ret: NistDRBG = .{ .key = @splat(0), .v = @splat(0) }; ret.update(seed); return ret; } diff --git a/lib/std/crypto/modes.zig b/lib/std/crypto/modes.zig @@ -183,7 +183,7 @@ test "ctr mode" { // Test 9: Large input (> 2*block_length, 100 bytes) { // Create a 100-byte input by extending with zeros - var in: [100]u8 = [_]u8{0} ** 100; + var in: [100]u8 = @splat(0); @memcpy(in[0..64], &[_]u8{ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, diff --git a/lib/std/crypto/pbkdf2.zig b/lib/std/crypto/pbkdf2.zig @@ -206,7 +206,7 @@ test "RFC 6070 16,777,216 iterations" { const c = 16777216; const dk_len = 20; - var dk = [_]u8{0} ** dk_len; + var dk: [dk_len]u8 = @splat(0); try pbkdf2(&dk, p, s, c, HmacSha1); diff --git a/lib/std/crypto/pcurves/p256/scalar.zig b/lib/std/crypto/pcurves/p256/scalar.zig @@ -196,19 +196,19 @@ const ScalarDouble = struct { } var t = ScalarDouble{ .x1 = undefined, .x2 = Fe.zero, .x3 = Fe.zero }; { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = @min(s.len, 24); b[0..len].* = s[0..len].*; t.x1 = Fe.fromBytes(b, .little) catch unreachable; } if (s_.len >= 24) { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = @min(s.len - 24, 24); b[0..len].* = s[24..][0..len].*; t.x2 = Fe.fromBytes(b, .little) catch unreachable; } if (s_.len >= 48) { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = s.len - 48; b[0..len].* = s[48..][0..len].*; t.x3 = Fe.fromBytes(b, .little) catch unreachable; diff --git a/lib/std/crypto/pcurves/p384/scalar.zig b/lib/std/crypto/pcurves/p384/scalar.zig @@ -184,13 +184,13 @@ const ScalarDouble = struct { } var t = ScalarDouble{ .x1 = undefined, .x2 = Fe.zero }; { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = @min(s.len, 32); b[0..len].* = s[0..len].*; t.x1 = Fe.fromBytes(b, .little) catch unreachable; } if (s_.len >= 32) { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = @min(s.len - 32, 32); b[0..len].* = s[32..][0..len].*; t.x2 = Fe.fromBytes(b, .little) catch unreachable; diff --git a/lib/std/crypto/pcurves/secp256k1/scalar.zig b/lib/std/crypto/pcurves/secp256k1/scalar.zig @@ -196,19 +196,19 @@ const ScalarDouble = struct { } var t = ScalarDouble{ .x1 = undefined, .x2 = Fe.zero, .x3 = Fe.zero }; { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = @min(s.len, 24); b[0..len].* = s[0..len].*; t.x1 = Fe.fromBytes(b, .little) catch unreachable; } if (s_.len >= 24) { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = @min(s.len - 24, 24); b[0..len].* = s[24..][0..len].*; t.x2 = Fe.fromBytes(b, .little) catch unreachable; } if (s_.len >= 48) { - var b = [_]u8{0} ** encoded_length; + var b: [encoded_length]u8 = @splat(0); const len = s.len - 48; b[0..len].* = s[48..][0..len].*; t.x3 = Fe.fromBytes(b, .little) catch unreachable; diff --git a/lib/std/crypto/pcurves/tests/p256.zig b/lib/std/crypto/pcurves/tests/p256.zig @@ -97,7 +97,7 @@ test "p256 public key is the neutral element (public verification)" { } test "p256 field element non-canonical encoding" { - const s = [_]u8{0xff} ** 32; + const s: [32]u8 = @splat(0xff); try testing.expectError(error.NonCanonical, P256.Fe.fromBytes(s, .little)); } @@ -110,8 +110,8 @@ test "p256 neutral element decoding" { test "p256 double base multiplication" { const p1 = P256.basePoint; const p2 = P256.basePoint.dbl(); - const s1 = [_]u8{0x01} ** 32; - const s2 = [_]u8{0x02} ** 32; + const s1: [32]u8 = @splat(0x01); + const s2: [32]u8 = @splat(0x02); const pr1 = try P256.mulDoubleBasePublic(p1, s1, p2, s2, .little); const pr2 = (try p1.mul(s1, .little)).add(try p2.mul(s2, .little)); try testing.expect(pr1.equivalent(pr2)); @@ -120,8 +120,8 @@ test "p256 double base multiplication" { test "p256 double base multiplication with large scalars" { const p1 = P256.basePoint; const p2 = P256.basePoint.dbl(); - const s1 = [_]u8{0xee} ** 32; - const s2 = [_]u8{0xdd} ** 32; + const s1: [32]u8 = @splat(0xee); + const s2: [32]u8 = @splat(0xdd); const pr1 = try P256.mulDoubleBasePublic(p1, s1, p2, s2, .little); const pr2 = (try p1.mul(s1, .little)).add(try p2.mul(s2, .little)); try testing.expect(pr1.equivalent(pr2)); diff --git a/lib/std/crypto/pcurves/tests/p384.zig b/lib/std/crypto/pcurves/tests/p384.zig @@ -100,7 +100,7 @@ test "p384 public key is the neutral element (public verification)" { } test "p384 field element non-canonical encoding" { - const s = [_]u8{0xff} ** 48; + const s: [48]u8 = @splat(0xff); try testing.expectError(error.NonCanonical, P384.Fe.fromBytes(s, .little)); } @@ -113,8 +113,8 @@ test "p384 neutral element decoding" { test "p384 double base multiplication" { const p1 = P384.basePoint; const p2 = P384.basePoint.dbl(); - const s1 = [_]u8{0x01} ** 48; - const s2 = [_]u8{0x02} ** 48; + const s1: [48]u8 = @splat(0x01); + const s2: [48]u8 = @splat(0x02); const pr1 = try P384.mulDoubleBasePublic(p1, s1, p2, s2, .little); const pr2 = (try p1.mul(s1, .little)).add(try p2.mul(s2, .little)); try testing.expect(pr1.equivalent(pr2)); @@ -123,8 +123,8 @@ test "p384 double base multiplication" { test "p384 double base multiplication with large scalars" { const p1 = P384.basePoint; const p2 = P384.basePoint.dbl(); - const s1 = [_]u8{0xee} ** 48; - const s2 = [_]u8{0xdd} ** 48; + const s1: [48]u8 = @splat(0xee); + const s2: [48]u8 = @splat(0xdd); const pr1 = try P384.mulDoubleBasePublic(p1, s1, p2, s2, .little); const pr2 = (try p1.mul(s1, .little)).add(try p2.mul(s2, .little)); try testing.expect(pr1.equivalent(pr2)); diff --git a/lib/std/crypto/pcurves/tests/secp256k1.zig b/lib/std/crypto/pcurves/tests/secp256k1.zig @@ -109,7 +109,7 @@ test "secp256k1 public key is the neutral element (public verification)" { } test "secp256k1 field element non-canonical encoding" { - const s = [_]u8{0xff} ** 32; + const s: [32]u8 = @splat(0xff); try testing.expectError(error.NonCanonical, Secp256k1.Fe.fromBytes(s, .little)); } @@ -122,8 +122,8 @@ test "secp256k1 neutral element decoding" { test "secp256k1 double base multiplication" { const p1 = Secp256k1.basePoint; const p2 = Secp256k1.basePoint.dbl(); - const s1 = [_]u8{0x01} ** 32; - const s2 = [_]u8{0x02} ** 32; + const s1: [32]u8 = @splat(0x01); + const s2: [32]u8 = @splat(0x02); const pr1 = try Secp256k1.mulDoubleBasePublic(p1, s1, p2, s2, .little); const pr2 = (try p1.mul(s1, .little)).add(try p2.mul(s2, .little)); try testing.expect(pr1.equivalent(pr2)); diff --git a/lib/std/crypto/salsa20.zig b/lib/std/crypto/salsa20.zig @@ -384,7 +384,7 @@ pub const XSalsa20Poly1305 = struct { pub fn encrypt(c: []u8, tag: *[tag_length]u8, m: []const u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) void { debug.assert(c.len == m.len); const extended = extend(rounds, k, npub); - var block0 = [_]u8{0} ** 64; + var block0: [64]u8 = @splat(0); const mlen0 = @min(32, m.len); @memcpy(block0[32..][0..mlen0], m[0..mlen0]); Salsa20.xor(block0[0..], block0[0..], 0, extended.key, extended.nonce); @@ -408,7 +408,7 @@ pub const XSalsa20Poly1305 = struct { pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { debug.assert(c.len == m.len); const extended = extend(rounds, k, npub); - var block0 = [_]u8{0} ** 64; + var block0: [64]u8 = @splat(0); const mlen0 = @min(32, c.len); @memcpy(block0[32..][0..mlen0], c[0..mlen0]); Salsa20.xor(block0[0..], block0[0..], 0, extended.key, extended.nonce); @@ -489,7 +489,7 @@ pub const Box = struct { /// Compute a secret suitable for `secretbox` given a recipient's public key and a sender's secret key. pub fn createSharedSecret(public_key: [public_length]u8, secret_key: [secret_length]u8) (IdentityElementError || WeakPublicKeyError)![shared_length]u8 { const p = try X25519.scalarmult(secret_key, public_key); - const zero = [_]u8{0} ** 16; + const zero: [16]u8 = @splat(0); return SalsaImpl(20).hsalsa(zero, p); } @@ -559,15 +559,15 @@ const htest = @import("test.zig"); test "(x)salsa20" { if (builtin.cpu.has(.riscv, .v) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/24299 - const key = [_]u8{0x69} ** 32; - const nonce = [_]u8{0x42} ** 8; - const msg = [_]u8{0} ** 20; + const key: [32]u8 = @splat(0x69); + const nonce: [8]u8 = @splat(0x42); + const msg: [20]u8 = @splat(0); var c: [msg.len]u8 = undefined; Salsa20.xor(&c, msg[0..], 0, key, nonce); try htest.assertEqual("30ff9933aa6534ff5207142593cd1fca4b23bdd8", c[0..]); - const extended_nonce = [_]u8{0x42} ** 24; + const extended_nonce: [24]u8 = @splat(0x42); XSalsa20.xor(&c, msg[0..], 0, key, extended_nonce); try htest.assertEqual("b4ab7d82e750ec07644fa3281bce6cd91d4243f9", c[0..]); } @@ -637,7 +637,7 @@ test "xsalsa20poly1305 sealedbox" { test "secretbox twoblocks" { const key = [_]u8{ 0xc9, 0xc9, 0x4d, 0xcf, 0x68, 0xbe, 0x00, 0xe4, 0x7f, 0xe6, 0x13, 0x26, 0xfc, 0xc4, 0x2f, 0xd0, 0xdb, 0x93, 0x91, 0x1c, 0x09, 0x94, 0x89, 0xe1, 0x1b, 0x88, 0x63, 0x18, 0x86, 0x64, 0x8b, 0x7b }; const nonce = [_]u8{ 0xa4, 0x33, 0xe9, 0x0a, 0x07, 0x68, 0x6e, 0x9a, 0x2b, 0x6d, 0xd4, 0x59, 0x04, 0x72, 0x3e, 0xd3, 0x8a, 0x67, 0x55, 0xc7, 0x9e, 0x3e, 0x77, 0xdc }; - const msg = [_]u8{'a'} ** 97; + const msg: [97]u8 = @splat('a'); var ciphertext: [msg.len + SecretBox.tag_length]u8 = undefined; SecretBox.seal(&ciphertext, &msg, nonce, key); try htest.assertEqual("b05760e217288ba079caa2fd57fd3701784974ffcfda20fe523b89211ad8af065a6eb37cdb29d51aca5bd75dafdd21d18b044c54bb7c526cf576c94ee8900f911ceab0147e82b667a28c52d58ceb29554ff45471224d37b03256b01c119b89ff6d36855de8138d103386dbc9d971f52261", &ciphertext); diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig @@ -461,7 +461,7 @@ test "sha256 streaming" { } test "sha256 aligned final" { - var block = [_]u8{0} ** Sha256.block_length; + var block: [Sha256.block_length]u8 = @splat(0); var out: [Sha256.digest_length]u8 = undefined; var h = Sha256.init(.{}); @@ -833,7 +833,7 @@ test "sha512 streaming" { } test "sha512 aligned final" { - var block = [_]u8{0} ** Sha512.block_length; + var block: [Sha512.block_length]u8 = @splat(0); var out: [Sha512.digest_length]u8 = undefined; var h = Sha512.init(.{}); diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig @@ -543,7 +543,7 @@ test "sha3-256 streaming" { } test "sha3-256 aligned final" { - var block = [_]u8{0} ** Sha3_256.block_length; + var block: [Sha3_256.block_length]u8 = @splat(0); var out: [Sha3_256.digest_length]u8 = undefined; var h = Sha3_256.init(.{}); @@ -616,7 +616,7 @@ test "sha3-512 streaming" { } test "sha3-512 aligned final" { - var block = [_]u8{0} ** Sha3_512.block_length; + var block: [Sha3_512.block_length]u8 = @splat(0); var out: [Sha3_512.digest_length]u8 = undefined; var h = Sha3_512.init(.{}); diff --git a/lib/std/crypto/siphash.zig b/lib/std/crypto/siphash.zig @@ -91,7 +91,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round self.msg_len +%= @as(u8, @truncate(b.len)); - var buf = [_]u8{0} ** 8; + var buf: [8]u8 = @splat(0); @memcpy(buf[0..b.len], b); buf[7] = self.msg_len; self.round(buf); diff --git a/lib/std/crypto/timing_safe.zig b/lib/std/crypto/timing_safe.zig @@ -207,8 +207,8 @@ test "eql (vectors)" { test compare { const expectEqual = std.testing.expectEqual; - var a = [_]u8{10} ** 32; - var b = [_]u8{10} ** 32; + var a: [32]u8 = @splat(10); + var b: [32]u8 = @splat(10); try expectEqual(compare(u8, &a, &b, .big), .eq); try expectEqual(compare(u8, &a, &b, .little), .eq); a[31] = 1; @@ -228,7 +228,7 @@ test "add and sub" { var a: [len]u8 = undefined; var b: [len]u8 = undefined; var c: [len]u8 = undefined; - const zero = [_]u8{0} ** len; + const zero: [len]u8 = @splat(0); var iterations: usize = 100; while (iterations != 0) : (iterations -= 1) { io.random(&a); @@ -262,7 +262,8 @@ test classify { declassify(&out); // Comparing public data in non-constant time is acceptable. - try expect(!std.mem.eql(u8, &out, &[_]u8{0} ** out.len)); + const zeroes: [out.len]u8 = @splat(0); + try expect(!std.mem.eql(u8, &out, &zeroes)); // Comparing secret data must be done in constant time. The result // is going to be considered as secret as well. diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig @@ -375,7 +375,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client const auth_tag = record_decoder.array(P.AEAD.tag_length).*; const nonce = nonce: { const V = @Vector(P.AEAD.nonce_length, u8); - const pad = [1]u8{0} ** (P.AEAD.nonce_length - 8); + const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); const operand: V = pad ++ @as([8]u8, @bitCast(big(read_seq))); break :nonce @as(V, pv.server_handshake_iv) ^ operand; }; @@ -415,7 +415,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client comptime std.math.shl(u64, std.math.maxInt(u64), 8 * P.record_iv_length); const nonce: [P.AEAD.nonce_length]u8 = nonce: { const V = @Vector(P.AEAD.nonce_length, u8); - const pad = [1]u8{0} ** (P.AEAD.nonce_length - 8); + const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); const operand: V = pad ++ @as([8]u8, @bitCast(big(masked_read_seq))); break :nonce @as(V, pv.app_cipher.server_write_IV ++ record_iv) ^ operand; }; @@ -539,7 +539,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client const p = &@field(handshake_cipher, @tagName(tag.with())); const P = @TypeOf(p.*).A; const hello_hash = p.transcript_hash.peek(); - const zeroes = [1]u8{0} ** P.Hash.digest_length; + const zeroes: [P.Hash.digest_length]u8 = @splat(0); const early_secret = P.Hkdf.extract(&[1]u8{0}, &zeroes); const empty_hash = tls.emptyHash(P.Hash); p.version = .{ .tls_1_3 = undefined }; @@ -791,7 +791,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client const pv = &p.version.tls_1_2; const nonce: [P.AEAD.nonce_length]u8 = nonce: { const V = @Vector(P.AEAD.nonce_length, u8); - const pad = [1]u8{0} ** (P.AEAD.nonce_length - 8); + const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); const operand: V = pad ++ @as([8]u8, @bitCast(big(write_seq))); break :nonce @as(V, pv.app_cipher.client_write_IV ++ pv.app_cipher.client_salt) ^ operand; }; @@ -832,8 +832,9 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client } switch (handshake_cipher) { inline else => |*p| { + const pad: [64]u8 = @splat(' '); try main_cert_pub_key.verifySignature(&hsd, &.{ - " " ** 64 ++ "TLS 1.3, server CertificateVerify\x00", + pad ++ "TLS 1.3, server CertificateVerify\x00", &p.transcript_hash.peek(), }); p.transcript_hash.update(wrapped_handshake); @@ -1066,7 +1067,7 @@ fn prepareCiphertextRecord( ciphertext_end += auth_tag.len; const nonce = nonce: { const V = @Vector(P.AEAD.nonce_length, u8); - const pad = [1]u8{0} ** (P.AEAD.nonce_length - 8); + const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); const operand: V = pad ++ mem.toBytes(big(c.write_seq)); break :nonce @as(V, pv.client_iv) ^ operand; }; @@ -1103,7 +1104,7 @@ fn prepareCiphertextRecord( ciphertext_end += P.record_iv_length; const nonce: [P.AEAD.nonce_length]u8 = nonce: { const V = @Vector(P.AEAD.nonce_length, u8); - const pad = [1]u8{0} ** (P.AEAD.nonce_length - 8); + const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); const operand: V = pad ++ @as([8]u8, @bitCast(big(c.write_seq))); break :nonce @as(V, pv.client_write_IV ++ pv.client_salt) ^ operand; }; @@ -1185,7 +1186,7 @@ fn readIndirect(c: *Client) Reader.Error!usize { const auth_tag = (input.takeArray(P.AEAD.tag_length) catch unreachable).*; // already peeked const nonce = nonce: { const V = @Vector(P.AEAD.nonce_length, u8); - const pad = [1]u8{0} ** (P.AEAD.nonce_length - 8); + const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); const operand: V = pad ++ mem.toBytes(big(c.read_seq)); break :nonce @as(V, pv.server_iv) ^ operand; }; @@ -1211,7 +1212,7 @@ fn readIndirect(c: *Client) Reader.Error!usize { comptime std.math.shl(u64, std.math.maxInt(u64), 8 * P.record_iv_length); const nonce: [P.AEAD.nonce_length]u8 = nonce: { const V = @Vector(P.AEAD.nonce_length, u8); - const pad = [1]u8{0} ** (P.AEAD.nonce_length - 8); + const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); const operand: V = pad ++ @as([8]u8, @bitCast(big(masked_read_seq))); break :nonce @as(V, pv.server_write_IV ++ record_iv) ^ operand; }; diff --git a/lib/std/debug.zig b/lib/std/debug.zig @@ -1381,7 +1381,7 @@ test printLineFromFile { try writer.flush(); try printLineFromFile(io, output_stream, .{ .file_name = path, .line = 2, .column = 0 }); - try expectEqualStrings(("a" ** overlap) ++ "\n", aw.written()); + try expectEqualStrings(&@as([overlap]u8, @splat('a')) ++ "\n", aw.written()); aw.clearRetainingCapacity(); } { @@ -1395,7 +1395,7 @@ test printLineFromFile { try writer.splatByteAll('a', std.heap.page_size_max); try printLineFromFile(io, output_stream, .{ .file_name = path, .line = 1, .column = 0 }); - try expectEqualStrings(("a" ** std.heap.page_size_max) ++ "\n", aw.written()); + try expectEqualStrings(&@as([std.heap.page_size_max]u8, @splat('a')) ++ "\n", aw.written()); aw.clearRetainingCapacity(); } { @@ -1410,14 +1410,16 @@ test printLineFromFile { try expectError(error.EndOfStream, printLineFromFile(io, output_stream, .{ .file_name = path, .line = 2, .column = 0 })); + const many_a: [3 * std.heap.page_size_max]u8 = @splat('a'); + try printLineFromFile(io, output_stream, .{ .file_name = path, .line = 1, .column = 0 }); - try expectEqualStrings(("a" ** (3 * std.heap.page_size_max)) ++ "\n", aw.written()); + try expectEqualStrings(&many_a ++ "\n", aw.written()); aw.clearRetainingCapacity(); try writer.writeAll("a\na"); try printLineFromFile(io, output_stream, .{ .file_name = path, .line = 1, .column = 0 }); - try expectEqualStrings(("a" ** (3 * std.heap.page_size_max)) ++ "a\n", aw.written()); + try expectEqualStrings(&many_a ++ "a\n", aw.written()); aw.clearRetainingCapacity(); try printLineFromFile(io, output_stream, .{ .file_name = path, .line = 2, .column = 0 }); diff --git a/lib/std/debug/Dwarf.zig b/lib/std/debug/Dwarf.zig @@ -1346,7 +1346,7 @@ const FileEntry = struct { dir_index: u32 = 0, mtime: u64 = 0, size: u64 = 0, - md5: [16]u8 = [1]u8{0} ** 16, + md5: [16]u8 = @splat(0), }; const LineNumberProgram = struct { diff --git a/lib/std/elf.zig b/lib/std/elf.zig @@ -3054,7 +3054,7 @@ pub const ar_hdr = extern struct { fn genSpecialMemberName(comptime name: []const u8) *const [16]u8 { assert(name.len <= 16); const padding = 16 - name.len; - return name ++ &[_]u8{0x20} ** padding; + return name ++ @as([padding]u8, @splat(0x20)); } // Archive files start with the ARMAG identifying string. Then follows a diff --git a/lib/std/enums.zig b/lib/std/enums.zig @@ -166,7 +166,7 @@ pub fn directEnumArrayDefault( init_values: EnumFieldStruct(E, Data, default), ) [directEnumArrayLen(E, max_unused_slots)]Data { const len = comptime directEnumArrayLen(E, max_unused_slots); - var result: [len]Data = if (default) |d| [_]Data{d} ** len else undefined; + var result: [len]Data = @splat(default orelse undefined); inline for (@typeInfo(@TypeOf(init_values)).@"struct".fields) |f| { const enum_value = @field(E, f.name); const index = @as(usize, @intCast(@intFromEnum(enum_value))); diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig @@ -1194,8 +1194,12 @@ test bytesToHex { } test hexToBytes { + const repeated: []const u8 = repeated: { + const buf: [32][2]u8 = @splat("90".*); + break :repeated @ptrCast(&buf); + }; var buf: [32]u8 = undefined; - try expectFmt("90" ** 32, "{X}", .{try hexToBytes(&buf, "90" ** 32)}); + try expectFmt(repeated, "{X}", .{try hexToBytes(&buf, repeated)}); try expectFmt("ABCD", "{X}", .{try hexToBytes(&buf, "ABCD")}); try expectFmt("", "{X}", .{try hexToBytes(&buf, "")}); try std.testing.expectError(error.InvalidCharacter, hexToBytes(&buf, "012Z")); diff --git a/lib/std/fmt/parse_float/decimal.zig b/lib/std/fmt/parse_float/decimal.zig @@ -80,7 +80,7 @@ pub fn Decimal(comptime T: type) type { .num_digits = 0, .decimal_point = 0, .truncated = false, - .digits = [_]u8{0} ** max_digits, + .digits = @splat(0), }; } diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig @@ -1449,11 +1449,15 @@ test "max file name component lengths" { if (native_os == .windows) { // U+FFFF is the character with the largest code point that is encoded as a single // WTF-16 code unit, so Windows allows for NAME_MAX of them. - const maxed_windows_filename1 = ("\u{FFFF}".*) ** windows.NAME_MAX; + const codepoint1 = "\u{FFFF}".*; + const buf1: [windows.NAME_MAX][codepoint1.len]u8 = @splat(codepoint1); + const maxed_windows_filename1: []const u8 = @ptrCast(&buf1); // This is also a code point that is encoded as one WTF-16 code unit, but // three WTF-8 bytes, so it exercises the limits of both WTF-16 and WTF-8 encodings. - const maxed_windows_filename2 = ("€".*) ** windows.NAME_MAX; - try testFilenameLimits(io, tmp.dir, &maxed_windows_filename1, &maxed_windows_filename2); + const codepoint2 = "€".*; + const buf2: [windows.NAME_MAX][codepoint2.len]u8 = @splat(codepoint2); + const maxed_windows_filename2: []const u8 = @ptrCast(&buf2); + try testFilenameLimits(io, tmp.dir, maxed_windows_filename1, maxed_windows_filename2); } else if (native_os == .wasi) { // On WASI, the maxed filename depends on the host OS, so in order for this test to // work on any host, we need to use a length that will work for all platforms diff --git a/lib/std/hash/Adler32.zig b/lib/std/hash/Adler32.zig @@ -88,15 +88,15 @@ test "sanity" { } test "long" { - const long1 = [_]u8{1} ** 1024; + const long1: [1024]u8 = @splat(1); try testing.expectEqual(@as(u32, 0x06780401), hash(long1[0..])); - const long2 = [_]u8{1} ** 1025; + const long2: [1025]u8 = @splat(1); try testing.expectEqual(@as(u32, 0x0a7a0402), hash(long2[0..])); } test "very long" { - const long = [_]u8{1} ** 5553; + const long: [5553]u8 = @splat(1); try testing.expectEqual(@as(u32, 0x707f15b2), hash(long[0..])); } diff --git a/lib/std/hash/benchmark.zig b/lib/std/hash/benchmark.zig @@ -93,13 +93,13 @@ const hashes = [_]Hash{ .ty = hash.SipHash64(1, 3), .name = "siphash64", .has_crypto_api = true, - .init_u8s = &[_]u8{0} ** 16, + .init_u8s = &@as([16]u8, @splat(0)), }, Hash{ .ty = hash.SipHash128(1, 3), .name = "siphash128", .has_crypto_api = true, - .init_u8s = &[_]u8{0} ** 16, + .init_u8s = &@as([16]u8, @splat(0)), }, }; diff --git a/lib/std/hash/wyhash.zig b/lib/std/hash/wyhash.zig @@ -253,7 +253,7 @@ test "iterative api" { } test "iterative maintains last sixteen" { - const input = "Z" ** 48 ++ "01234567890abcdefg"; + const input = &@as([48]u8, @splat('Z')) ++ "01234567890abcdefg"; const seed = 0; for (0..17) |i| { diff --git a/lib/std/heap/debug_allocator.zig b/lib/std/heap/debug_allocator.zig @@ -164,7 +164,7 @@ pub fn DebugAllocator(comptime config: Config) type { return struct { backing_allocator: Allocator = std.heap.page_allocator, /// Tracks the active bucket, which is the one that has free slots in it. - buckets: [small_bucket_count]?*BucketHeader = [1]?*BucketHeader{null} ** small_bucket_count, + buckets: [small_bucket_count]?*BucketHeader = @splat(null), large_allocations: LargeAllocTable = .empty, total_requested_bytes: @TypeOf(total_requested_bytes_init) = total_requested_bytes_init, requested_memory_limit: @TypeOf(requested_memory_limit_init) = requested_memory_limit_init, diff --git a/lib/std/http.zig b/lib/std/http.zig @@ -749,7 +749,7 @@ pub const BodyWriter = struct { /// How many zeroes to reserve for hex-encoded chunk length. const chunk_len_digits = 8; const max_chunk_len: usize = std.math.pow(u64, 16, chunk_len_digits) - 1; - const chunk_header_template = ("0" ** chunk_len_digits) ++ "\r\n"; + const chunk_header_template = @as([chunk_len_digits]u8, @splat('0')) ++ "\r\n"; comptime { assert(max_chunk_len == std.math.maxInt(u32)); diff --git a/lib/std/json/JSONTestSuite_test.zig b/lib/std/json/JSONTestSuite_test.zig @@ -1,5 +1,5 @@ -// This file was generated by _generate_JSONTestSuite.zig -// These test cases are sourced from: https://github.com/nst/JSONTestSuite +//! This file was generated by _generate_JSONTestSuite.zig +//! These test cases are sourced from: https://github.com/nst/JSONTestSuite const ok = @import("./test.zig").ok; const err = @import("./test.zig").err; const any = @import("./test.zig").any; @@ -104,7 +104,7 @@ test "i_string_utf16LE_no_BOM.json" { try any("[\x00\"\x00\xe9\x00\"\x00]\x00"); } test "i_structure_500_nested_arrays.json" { - try any("[" ** 500 ++ "]" ** 500); + try any(&@as([500]u8, @splat('[')) ++ &@as([500]u8, @splat(']'))); } test "i_structure_UTF-8_BOM_empty_object.json" { try any("\xef\xbb\xbf{}"); @@ -527,7 +527,7 @@ test "n_string_with_trailing_garbage.json" { try err("\"\"x"); } test "n_structure_100000_opening_arrays.json" { - try err("[" ** 100000); + try err(&@as([100000]u8, @splat('['))); } test "n_structure_U+2060_word_joined.json" { try err("[\xe2\x81\xa0]"); @@ -605,7 +605,12 @@ test "n_structure_open_array_comma.json" { try err("[,"); } test "n_structure_open_array_object.json" { - try err("[{\"\":" ** 50000 ++ "\n"); + try err(str: { + const part = "[{\"\":"; + const buf: [50000][part.len]u8 = @splat(part.*); + const s: []const u8 = @ptrCast(&buf); + break :str s ++ "\n"; + }); } test "n_structure_open_array_open_object.json" { try err("[{"); diff --git a/lib/std/json/scanner_test.zig b/lib/std/json/scanner_test.zig @@ -261,19 +261,28 @@ test "strings" { } } -const nesting_test_cases = .{ - .{ null, "[]" }, - .{ null, "{}" }, - .{ error.SyntaxError, "[}" }, - .{ error.SyntaxError, "{]" }, - .{ null, "[" ** 1000 ++ "]" ** 1000 }, - .{ null, "{\"\":" ** 1000 ++ "0" ++ "}" ** 1000 }, - .{ error.SyntaxError, "[" ** 1000 ++ "]" ** 999 ++ "}" }, - .{ error.SyntaxError, "{\"\":" ** 1000 ++ "0" ++ "}" ** 999 ++ "]" }, - .{ error.SyntaxError, "[" ** 1000 ++ "]" ** 1001 }, - .{ error.SyntaxError, "{\"\":" ** 1000 ++ "0" ++ "}" ** 1001 }, - .{ error.UnexpectedEndOfInput, "[" ** 1000 ++ "]" ** 999 }, - .{ error.UnexpectedEndOfInput, "{\"\":" ** 1000 ++ "0" ++ "}" ** 999 }, +const nesting_test_cases = cases: { + const open_arrays: *const [1000]u8 = &@splat('['); + const close_arrays: *const [1000]u8 = &@splat(']'); + + const open_objects_buf: [1000][4]u8 = @splat("{\"\":".*); + const open_objects: []const u8 = @ptrCast(&open_objects_buf); + const close_objects: *const [1000]u8 = &@splat('}'); + + break :cases .{ + .{ null, "[]" }, + .{ null, "{}" }, + .{ error.SyntaxError, "[}" }, + .{ error.SyntaxError, "{]" }, + .{ null, open_arrays ++ close_arrays }, + .{ null, open_objects ++ "0" ++ close_objects }, + .{ error.SyntaxError, open_arrays ++ close_arrays[0..999] ++ "}" }, + .{ error.SyntaxError, open_objects ++ "0" ++ close_objects[0..999] ++ "]" }, + .{ error.SyntaxError, open_arrays ++ close_arrays ++ "]" }, + .{ error.SyntaxError, open_objects ++ "0" ++ close_objects ++ "}" }, + .{ error.UnexpectedEndOfInput, open_arrays ++ close_arrays[0..999] }, + .{ error.UnexpectedEndOfInput, open_objects ++ "0" ++ close_objects[0..999] }, + }; }; test "nesting" { @@ -421,11 +430,12 @@ test "skipValue" { try testSkipValue("{\"foo\": \"bar\\nbaz\"}"); // An absurd number of nestings - const nestings = 1000; - try testSkipValue("[" ** nestings ++ "]" ** nestings); + const open_all: [1000]u8 = @splat('['); + const close_all: [1000]u8 = @splat(']'); + try testSkipValue(&(open_all ++ close_all)); // Would a number token cause problems in a deeply-nested array? - try testSkipValue("[" ** nestings ++ "0.118, 999, 881.99, 911.9, 725, 3" ++ "]" ** nestings); + try testSkipValue(&open_all ++ "0.118, 999, 881.99, 911.9, 725, 3" ++ &close_all); // Mismatched brace/square bracket try std.testing.expectError(error.SyntaxError, testSkipValue("[102, 111, 111}")); @@ -474,7 +484,8 @@ test "enableDiagnostics" { inline for ([_]comptime_int{ 5, 6, 7, 99 }) |reps| { // The error happens 1 byte before the end. - const s = "[" ** reps ++ "}"; + const open_all: [reps]u8 = @splat('['); + const s = &open_all ++ "}"; try testDiagnostics(error.SyntaxError, 1, s.len, s.len - 1, s); } } diff --git a/lib/std/json/static.zig b/lib/std/json/static.zig @@ -334,7 +334,7 @@ pub fn innerParse( if (.object_begin != try source.next()) return error.UnexpectedToken; var r: T = undefined; - var fields_seen = [_]bool{false} ** structInfo.fields.len; + var fields_seen: [structInfo.fields.len]bool = @splat(false); while (true) { var name_token: ?Token = try source.nextAllocMax(allocator, .alloc_if_needed, options.max_value_len.?); @@ -649,7 +649,7 @@ pub fn innerParseFromValue( if (source != .object) return error.UnexpectedToken; var r: T = undefined; - var fields_seen = [_]bool{false} ** structInfo.fields.len; + var fields_seen: [structInfo.fields.len]bool = @splat(false); var it = source.object.iterator(); while (it.next()) |kv| { diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig @@ -29,8 +29,8 @@ const Constants = struct { }; const constants: Constants = blk: { @setEvalBranchQuota(2000); - var digits_per_limb = [_]u8{0} ** 37; - var bases = [_]Limb{0} ** 37; + var digits_per_limb: [37]u8 = @splat(0); + var bases: [37]Limb = @splat(0); for (2..37) |base| { digits_per_limb[base] = @intCast(math.log(Limb, base, math.maxInt(Limb))); bases[base] = std.math.pow(Limb, base, digits_per_limb[base]); @@ -2391,7 +2391,7 @@ pub const Const = struct { var limbs: [calcToStringLimbsBufferLen(available_len, 10)]Limb = undefined; const biggest: Const = .{ - .limbs = &([1]Limb{comptime math.maxInt(Limb)} ** available_len), + .limbs = &@as([available_len]Limb, @splat(comptime math.maxInt(Limb))), .positive = false, }; var buf: [biggest.sizeInBaseUpperBound(2)]u8 = undefined; diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig @@ -3351,7 +3351,7 @@ test "big int popcount" { try popCountTest(&a, limb_bits * 2 + 1, limb_bits * 2 + 1); // Check very large numbers. - try a.setString(16, "ff00000100000100" ++ ("0000000000000000" ** 62)); + try a.setString(16, "ff00000100000100" ++ &@as([16 * 62]u8, @splat('0'))); try popCountTest(&a, 4032, 10); try popCountTest(&a, 6000, 10); a.negate(); @@ -3459,13 +3459,13 @@ test "big int write twos complement +/- zero" { // Test zero m.toConst().writeTwosComplement(buffer1[0..13], .little); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xAA, 0xAA, 0xAA }, buffer1); m.toConst().writeTwosComplement(buffer1[0..13], .big); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xAA, 0xAA, 0xAA }, buffer1); m.toConst().writeTwosComplement(buffer1[0..16], .little); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 16)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, buffer1); m.toConst().writeTwosComplement(buffer1[0..16], .big); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 16)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, buffer1); @memset(buffer1, 0xaa); m.positive = false; @@ -3473,13 +3473,13 @@ test "big int write twos complement +/- zero" { // Test negative zero m.toConst().writeTwosComplement(buffer1[0..13], .little); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xAA, 0xAA, 0xAA }, buffer1); m.toConst().writeTwosComplement(buffer1[0..13], .big); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xAA, 0xAA, 0xAA }, buffer1); m.toConst().writeTwosComplement(buffer1[0..16], .little); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 16)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, buffer1); m.toConst().writeTwosComplement(buffer1[0..16], .big); - try testing.expectEqualSlices(u8, &(([_]u8{0} ** 16)), buffer1); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, buffer1); } test "big int conversion write twos complement with padding" { @@ -3556,7 +3556,7 @@ test "big int conversion write twos complement with padding" { // Test 0 - buffer = &([_]u8{0} ** 16); + buffer = &@as([16]u8, @splat(0)); m.readTwosComplement(buffer[0..13], bit_count, .little, .unsigned); try testing.expectEqual(.eq, m.toConst().orderAgainstScalar(0x0)); m.readTwosComplement(buffer[0..13], bit_count, .big, .unsigned); @@ -3567,7 +3567,7 @@ test "big int conversion write twos complement with padding" { try testing.expectEqual(.eq, m.toConst().orderAgainstScalar(0x0)); bit_count = 0; - buffer = &([_]u8{0xaa} ** 16); + buffer = &@as([16]u8, @splat(0xaa)); m.readTwosComplement(buffer[0..13], bit_count, .little, .unsigned); try testing.expectEqual(.eq, m.toConst().orderAgainstScalar(0x0)); m.readTwosComplement(buffer[0..13], bit_count, .big, .unsigned); @@ -3592,13 +3592,13 @@ test "big int conversion write twos complement zero" { const bit_count: usize = 12 * 8 + 1; var buffer: []const u8 = undefined; - buffer = &([_]u8{0} ** 13); + buffer = &@as([13]u8, @splat(0)); m.readTwosComplement(buffer[0..13], bit_count, .little, .unsigned); try testing.expectEqual(.eq, m.toConst().orderAgainstScalar(0x0)); m.readTwosComplement(buffer[0..13], bit_count, .big, .unsigned); try testing.expectEqual(.eq, m.toConst().orderAgainstScalar(0x0)); - buffer = &([_]u8{0} ** 16); + buffer = &@as([16]u8, @splat(0)); m.readTwosComplement(buffer[0..16], bit_count, .little, .unsigned); try testing.expectEqual(.eq, m.toConst().orderAgainstScalar(0x0)); m.readTwosComplement(buffer[0..16], bit_count, .big, .unsigned); diff --git a/lib/std/mem.zig b/lib/std/mem.zig @@ -359,7 +359,10 @@ test zeroes { var a = zeroes(C_struct); // Extern structs should have padding zeroed out. - try testing.expectEqualSlices(u8, &[_]u8{0} ** @sizeOf(@TypeOf(a)), asBytes(&a)); + { + const num_bytes = @sizeOf(@TypeOf(a)); + try testing.expectEqualSlices(u8, &@as([num_bytes]u8, @splat(0)), @ptrCast(&a)); + } a.y += 10; @@ -1587,7 +1590,7 @@ test find { test "find multibyte" { { // make haystack and needle long enough to trigger Boyer-Moore-Horspool algorithm - const haystack = [1]u16{0} ** 100 ++ [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff }; + const haystack = @as([100]u16, @splat(0)) ++ [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff }; const needle = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee }; try testing.expectEqual(findPos(u16, &haystack, 0, &needle), 100); @@ -1600,7 +1603,7 @@ test "find multibyte" { { // make haystack and needle long enough to trigger Boyer-Moore-Horspool algorithm - const haystack = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff } ++ [1]u16{0} ** 100; + const haystack = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee, 0x00ff } ++ @as([100]u16, @splat(0)); const needle = [_]u16{ 0xbbaa, 0xccbb, 0xddcc, 0xeedd, 0xffee }; try testing.expectEqual(lastIndexOf(u16, &haystack, &needle), 0); @@ -4645,7 +4648,7 @@ test "sliceAsBytes with sentinel slice" { } test "sliceAsBytes with zero-bit element type" { - const lots_of_nothing = [1]void{{}} ** 10_000; + const lots_of_nothing: [10_000]void = @splat({}); const bytes = sliceAsBytes(&lots_of_nothing); try testing.expect(bytes.len == 0); } @@ -4863,8 +4866,8 @@ test doNotOptimizeAway { doNotOptimizeAway(@as(u200, 0)); doNotOptimizeAway(@as(f32, 0.0)); doNotOptimizeAway(@as(f64, 0.0)); - doNotOptimizeAway([_]u8{0} ** 4); - doNotOptimizeAway([_]u8{0} ** 100); + doNotOptimizeAway(@as([4]u8, @splat(0))); + doNotOptimizeAway(@as([100]u8, @splat(0))); doNotOptimizeAway(@as(std.builtin.Endian, .little)); } diff --git a/lib/std/os/emscripten.zig b/lib/std/os/emscripten.zig @@ -373,7 +373,7 @@ pub const rusage = extern struct { nsignals: isize, nvcsw: isize, nivcsw: isize, - __reserved: [16]isize = [1]isize{0} ** 16, + __reserved: [16]isize = @splat(0), pub const SELF = 0; pub const CHILDREN = -1; @@ -481,7 +481,7 @@ pub const Sigaction = extern struct { pub const sigset_t = [1024 / 32]u32; pub fn sigemptyset() sigset_t { - return [_]u32{0} ** @typeInfo(sigset_t).array.len; + return @splat(0); } pub const siginfo_t = extern struct { signo: i32, diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig @@ -2262,12 +2262,12 @@ pub fn sigrtmax() u8 { /// Zig's version of sigemptyset. Returns initialized sigset_t. pub fn sigemptyset() sigset_t { - return [_]SigsetElement{0} ** sigset_len; + return @splat(0); } /// Zig's version of sigfillset. Returns initalized sigset_t. pub fn sigfillset() sigset_t { - return [_]SigsetElement{~@as(SigsetElement, 0)} ** sigset_len; + return @splat(~@as(SigsetElement, 0)); } fn sigset_bit_index(sig: SIG) struct { word: usize, mask: SigsetElement } { @@ -6129,7 +6129,7 @@ pub const sockaddr = extern struct { flags: u8, /// The total size of this structure should be exactly the same as that of struct sockaddr. - zero: [3]u8 = [_]u8{0} ** 3, + zero: [3]u8 = @splat(0), comptime { std.debug.assert(@sizeOf(vm) == @sizeOf(sockaddr)); } @@ -7475,7 +7475,7 @@ pub const rusage = extern struct { nsignals: isize, nvcsw: isize, nivcsw: isize, - __reserved: [16]isize = [1]isize{0} ** 16, + __reserved: [16]isize = @splat(0), pub const SELF = 0; pub const CHILDREN = -1; diff --git a/lib/std/os/linux/IoUring/test.zig b/lib/std/os/linux/IoUring/test.zig @@ -115,12 +115,12 @@ test "readv" { // https://github.com/torvalds/linux/blob/v5.4/fs/io_uring.c#L3119-L3124 vs // https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L6687-L6691 // We therefore avoid stressing sparse fd sets here: - var registered_fds = [_]linux.fd_t{0} ** 1; + var registered_fds: [1]linux.fd_t = .{0}; const fd_index = 0; registered_fds[fd_index] = file.handle; try ring.register_files(registered_fds[0..]); - var buffer = [_]u8{42} ** 128; + var buffer: [128]u8 = @splat(42); var iovecs = [_]iovec{iovec{ .base = &buffer, .len = buffer.len }}; const sqe = try ring.read(0xcccccccc, fd_index, .{ .iovecs = iovecs[0..] }, 0); try testing.expectEqual(linux.IORING_OP.READV, sqe.opcode); @@ -133,7 +133,7 @@ test "readv" { .res = buffer.len, .flags = 0, }, try ring.copy_cqe()); - try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer.len), buffer[0..]); + try testing.expectEqualSlices(u8, &@as([buffer.len]u8, @splat(0)), buffer[0..]); try ring.unregister_files(); } @@ -156,11 +156,11 @@ test "writev/fsync/readv" { defer file.close(io); const fd = file.handle; - const buffer_write = [_]u8{42} ** 128; + const buffer_write: [128]u8 = @splat(42); const iovecs_write = [_]iovec_const{ iovec_const{ .base = &buffer_write, .len = buffer_write.len }, }; - var buffer_read = [_]u8{0} ** 128; + var buffer_read: [128]u8 = @splat(0); var iovecs_read = [_]iovec{ iovec{ .base = &buffer_read, .len = buffer_read.len }, }; @@ -225,8 +225,8 @@ test "write/read" { defer file.close(io); const fd = file.handle; - const buffer_write = [_]u8{97} ** 20; - var buffer_read = [_]u8{98} ** 20; + const buffer_write: [20]u8 = @splat(97); + var buffer_read: [20]u8 = @splat(98); const sqe_write = try ring.write(0x11111111, fd, buffer_write[0..], 10); try testing.expectEqual(linux.IORING_OP.WRITE, sqe_write.opcode); try testing.expectEqual(@as(u64, 10), sqe_write.off); @@ -276,8 +276,8 @@ test "splice/read" { defer file_dst.close(io); const fd_dst = file_dst.handle; - const buffer_write = [_]u8{97} ** 20; - var buffer_read = [_]u8{98} ** 20; + const buffer_write: [20]u8 = @splat(97); + var buffer_read: [20]u8 = @splat(98); try file_src.writeStreamingAll(io, &buffer_write); const fds = try std.Io.Threaded.pipe2(.{}); @@ -542,7 +542,7 @@ test "sendmsg/recvmsg" { const client = try socket(address_server.family, posix.SOCK.DGRAM, 0); defer _ = linux.close(client); - const buffer_send = [_]u8{42} ** 128; + const buffer_send: [128]u8 = @splat(42); const iovecs_send = [_]iovec_const{ iovec_const{ .base = &buffer_send, .len = buffer_send.len }, }; @@ -560,7 +560,7 @@ test "sendmsg/recvmsg" { try testing.expectEqual(linux.IORING_OP.SENDMSG, sqe_sendmsg.opcode); try testing.expectEqual(client, sqe_sendmsg.fd); - var buffer_recv = [_]u8{0} ** 128; + var buffer_recv: [128]u8 = @splat(0); var iovecs_recv = [_]iovec{ iovec{ .base = &buffer_recv, .len = buffer_recv.len }, }; @@ -944,7 +944,7 @@ test "register_files_update" { const file = try Io.Dir.openFileAbsolute(io, "/dev/zero", .{}); defer file.close(io); - var registered_fds = [_]linux.fd_t{0} ** 2; + var registered_fds: [2]linux.fd_t = @splat(0); const fd_index = 0; const fd_index2 = 1; registered_fds[fd_index] = file.handle; @@ -966,7 +966,7 @@ test "register_files_update" { registered_fds[fd_index2] = -1; try ring.register_files_update(0, registered_fds[0..]); - var buffer = [_]u8{42} ** 128; + var buffer: [128]u8 = @splat(42); { const sqe = try ring.read(0xcccccccc, fd_index, .{ .buffer = &buffer }, 0); try testing.expectEqual(linux.IORING_OP.READ, sqe.opcode); @@ -978,7 +978,7 @@ test "register_files_update" { .res = buffer.len, .flags = 0, }, try ring.copy_cqe()); - try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer.len), buffer[0..]); + try testing.expectEqualSlices(u8, &@as([buffer.len]u8, @splat(0)), buffer[0..]); } // Test with a non-zero offset @@ -999,7 +999,7 @@ test "register_files_update" { .res = buffer.len, .flags = 0, }, try ring.copy_cqe()); - try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer.len), buffer[0..]); + try testing.expectEqualSlices(u8, &@as([buffer.len]u8, @splat(0)), buffer[0..]); } try ring.register_files_update(0, registered_fds[0..]); @@ -1404,7 +1404,7 @@ test "provide_buffers: read" { try testing.expectEqual(@as(i32, buffer_len), cqe.res); try testing.expectEqual(@as(u64, 0xdededede), cqe.user_data); - try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer_len), buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]); + try testing.expectEqualSlices(u8, &@as([buffer_len]u8, @splat(0)), buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]); } // This read should fail @@ -1468,7 +1468,7 @@ test "provide_buffers: read" { try testing.expectEqual(used_buffer_id, reprovided_buffer_id); try testing.expectEqual(@as(i32, buffer_len), cqe.res); try testing.expectEqual(@as(u64, 0xdfdfdfdf), cqe.user_data); - try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer_len), buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]); + try testing.expectEqualSlices(u8, &@as([buffer_len]u8, @splat(0)), buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]); } } @@ -1542,7 +1542,7 @@ test "remove_buffers" { try testing.expect(used_buffer_id >= 0 and used_buffer_id < 4); try testing.expectEqual(@as(i32, buffer_len), cqe.res); try testing.expectEqual(@as(u64, 0xdfdfdfdf), cqe.user_data); - try testing.expectEqualSlices(u8, &([_]u8{0} ** buffer_len), buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]); + try testing.expectEqualSlices(u8, &@as([buffer_len]u8, @splat(0)), buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]); } // Final read should _not_ work @@ -1608,7 +1608,7 @@ test "provide_buffers: accept/connect/send/recv" { { var i: usize = 0; while (i < buffers.len) : (i += 1) { - _ = try ring.send(0xdeaddead, socket_test_harness.server, &([_]u8{'z'} ** buffer_len), 0); + _ = try ring.send(0xdeaddead, socket_test_harness.server, &@as([buffer_len]u8, @splat('z')), 0); try testing.expectEqual(@as(u32, 1), try ring.submit()); } @@ -1646,7 +1646,7 @@ test "provide_buffers: accept/connect/send/recv" { try testing.expectEqual(@as(u64, 0xdededede), cqe.user_data); const buffer = buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]; - try testing.expectEqualSlices(u8, &([_]u8{'z'} ** buffer_len), buffer); + try testing.expectEqualSlices(u8, &@as([buffer_len]u8, @splat('z')), buffer); } // This recv should fail @@ -1690,7 +1690,7 @@ test "provide_buffers: accept/connect/send/recv" { // Redo 1 send on the server socket { - _ = try ring.send(0xdeaddead, socket_test_harness.server, &([_]u8{'w'} ** buffer_len), 0); + _ = try ring.send(0xdeaddead, socket_test_harness.server, &@as([buffer_len]u8, @splat('w')), 0); try testing.expectEqual(@as(u32, 1), try ring.submit()); _ = try ring.copy_cqe(); @@ -1724,7 +1724,7 @@ test "provide_buffers: accept/connect/send/recv" { try testing.expectEqual(@as(i32, buffer_len), cqe.res); try testing.expectEqual(@as(u64, 0xdfdfdfdf), cqe.user_data); const buffer = buffers[used_buffer_id][0..@as(usize, @intCast(cqe.res))]; - try testing.expectEqualSlices(u8, &([_]u8{'w'} ** buffer_len), buffer); + try testing.expectEqualSlices(u8, &@as([buffer_len]u8, @splat('w')), buffer); } } @@ -1784,8 +1784,8 @@ test "accept/connect/send_zc/recv" { const socket_test_harness = try createSocketTestHarness(&ring); defer socket_test_harness.close(); - const buffer_send = [_]u8{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe }; - var buffer_recv = [_]u8{0} ** 10; + const buffer_send: [15]u8 = .{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe }; + var buffer_recv: [10]u8 = @splat(0); // zero-copy send const sqe_send = try ring.send_zc(0xeeeeeeee, socket_test_harness.client, buffer_send[0..], 0, 0); @@ -1844,7 +1844,7 @@ test "accept_direct" { }; // register direct file descriptors - var registered_fds = [_]linux.fd_t{-1} ** 2; + var registered_fds: [2]linux.fd_t = @splat(-1); try ring.register_files(registered_fds[0..]); const listener_socket = try createListenerSocket(&address); @@ -1856,7 +1856,7 @@ test "accept_direct" { for (0..2) |_| { for (registered_fds, 0..) |_, i| { - var buffer_recv = [_]u8{0} ** 16; + var buffer_recv: [16]u8 = @splat(0); const buffer_send: []const u8 = data[0 .. data.len - i]; // make it different at each loop // submit accept, will chose registered fd and return index in cqe @@ -1932,7 +1932,7 @@ test "accept_multishot_direct" { .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), }; - var registered_fds = [_]linux.fd_t{-1} ** 2; + var registered_fds: [2]linux.fd_t = @splat(-1); try ring.register_files(registered_fds[0..]); const listener_socket = try createListenerSocket(&address); @@ -2011,7 +2011,7 @@ test "socket_direct/socket_direct_alloc/close_direct" { }; defer ring.deinit(); - var registered_fds = [_]linux.fd_t{-1} ** 3; + var registered_fds: [3]linux.fd_t = @splat(-1); try ring.register_files(registered_fds[0..]); // create socket in registered file descriptor at index 0 (last param) @@ -2092,7 +2092,7 @@ test "openat_direct/close_direct" { }; defer ring.deinit(); - var registered_fds = [_]linux.fd_t{-1} ** 3; + var registered_fds: [3]linux.fd_t = @splat(-1); try ring.register_files(registered_fds[0..]); var tmp = std.testing.tmpDir(.{}); @@ -2562,7 +2562,11 @@ fn expect_buf_grp_cqe( } fn testSendRecv(ring: *IoUring, send_fd: posix.socket_t, recv_fd: posix.socket_t) !void { - const buffer_send = "0123456789abcdf" ** 10; + const buffer_send: []const u8 = comptime buf: { + const part = "0123456789abcdf"; + const repeated: [10][part.len]u8 = @splat(part.*); + break :buf @ptrCast(&repeated); + }; var buffer_recv: [buffer_send.len * 2]u8 = undefined; // 2 sends diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig @@ -70,7 +70,7 @@ test "timer" { try expect(err == .SUCCESS); const events_one: linux.epoll_event = undefined; - var events = [_]linux.epoll_event{events_one} ** 8; + var events: [8]linux.epoll_event = @splat(events_one); err = linux.errno(linux.epoll_wait(@as(i32, @intCast(epoll_fd)), &events, 8, -1)); try expect(err == .SUCCESS); diff --git a/lib/std/os/uefi/hii.zig b/lib/std/os/uefi/hii.zig @@ -66,7 +66,7 @@ pub const WideGlyph = extern struct { attributes: WideGlyphAttributes, glyph_col_1: [19]u8, glyph_col_2: [19]u8, - _pad: [3]u8 = [_]u8{0} ** 3, + _pad: [3]u8 = @splat(0), }; pub const StringPackage = extern struct { diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig @@ -187,11 +187,11 @@ test "mmap" { try expectEqual(@as(usize, 1234), data.len); // By definition the data returned by mmap is zero-filled - try expect(mem.eql(u8, data, &[_]u8{0x00} ** 1234)); + try expect(mem.eql(u8, data, &@as([1234]u8, @splat(0x00)))); // Make sure the memory is writeable as requested @memset(data, 0x55); - try expect(mem.eql(u8, data, &[_]u8{0x55} ** 1234)); + try expect(mem.eql(u8, data, &@as([1234]u8, @splat(0x55)))); } const test_out_file = "os_tmp_test"; diff --git a/lib/std/tar.zig b/lib/std/tar.zig @@ -734,6 +734,10 @@ test PaxIterator { value: []const u8 = undefined, err: ?anyerror = null, }; + const long_path: *const [1000]u8 = comptime path: { + const buf: [100][10]u8 = @splat("0123456789".*); + break :path @ptrCast(&buf); + }; const cases = [_]struct { data: []const u8, attrs: []const Attr, @@ -816,9 +820,9 @@ test PaxIterator { }, }, .{ // 1000 characters path - .data = "1011 path=" ++ "0123456789" ** 100 ++ "\n", + .data = "1011 path=" ++ long_path ++ "\n", .attrs = &[_]Attr{ - .{ .kind = .path, .value = "0123456789" ** 100 }, + .{ .kind = .path, .value = long_path }, }, }, }; @@ -879,7 +883,7 @@ test "header parse size" { }; for (cases) |case| { - var bytes = [_]u8{0} ** Header.SIZE; + var bytes: [Header.SIZE]u8 = @splat(0); @memcpy(bytes[124 .. 124 + case.in.len], case.in); var header = Header{ .bytes = &bytes }; if (case.err) |err| { @@ -904,7 +908,7 @@ test "header parse mode" { .{ .in = "777777777777", .want = 0o77777777 }, }; for (cases) |case| { - var bytes = [_]u8{0} ** Header.SIZE; + var bytes: [Header.SIZE]u8 = @splat(0); @memcpy(bytes[100 .. 100 + case.in.len], case.in); var header = Header{ .bytes = &bytes }; if (case.err) |err| { diff --git a/lib/std/tar/Writer.zig b/lib/std/tar/Writer.zig @@ -193,23 +193,23 @@ pub const Header = extern struct { // numeric field of width w contains w minus 1 digits, and a null. // Reference: https://www.gnu.org/software/tar/manual/html_node/Standard.html // POSIX header: byte offset - name: [100]u8 = [_]u8{0} ** 100, // 0 + name: [100]u8 = @splat(0), // 0 mode: [7:0]u8 = default_mode.file, // 100 - uid: [7:0]u8 = [_:0]u8{0} ** 7, // unused 108 - gid: [7:0]u8 = [_:0]u8{0} ** 7, // unused 116 - size: [11:0]u8 = [_:0]u8{'0'} ** 11, // 124 - mtime: [11:0]u8 = [_:0]u8{'0'} ** 11, // 136 - checksum: [7:0]u8 = [_:0]u8{' '} ** 7, // 148 + uid: [7:0]u8 = @splat(0), // unused 108 + gid: [7:0]u8 = @splat(0), // unused 116 + size: [11:0]u8 = @splat('0'), // 124 + mtime: [11:0]u8 = @splat('0'), // 136 + checksum: [7:0]u8 = @splat(' '), // 148 typeflag: FileType = .regular, // 156 - linkname: [100]u8 = [_]u8{0} ** 100, // 157 - magic: [6]u8 = [_]u8{ 'u', 's', 't', 'a', 'r', 0 }, // 257 - version: [2]u8 = [_]u8{ '0', '0' }, // 263 - uname: [32]u8 = [_]u8{0} ** 32, // unused 265 - gname: [32]u8 = [_]u8{0} ** 32, // unused 297 - devmajor: [7:0]u8 = [_:0]u8{0} ** 7, // unused 329 - devminor: [7:0]u8 = [_:0]u8{0} ** 7, // unused 337 - prefix: [155]u8 = [_]u8{0} ** 155, // 345 - pad: [12]u8 = [_]u8{0} ** 12, // unused 500 + linkname: [100]u8 = @splat(0), // 157 + magic: [6]u8 = .{ 'u', 's', 't', 'a', 'r', 0 }, // 257 + version: [2]u8 = .{ '0', '0' }, // 263 + uname: [32]u8 = @splat(0), // unused 265 + gname: [32]u8 = @splat(0), // unused 297 + devmajor: [7:0]u8 = @splat(0), // unused 329 + devminor: [7:0]u8 = @splat(0), // unused 337 + prefix: [155]u8 = @splat(0), // 345 + pad: [12]u8 = @splat(0), // unused 500 pub const FileType = enum(u8) { regular = '0', @@ -342,26 +342,26 @@ pub const Header = extern struct { }, // no more both fits into name .{ - .in = &.{ "prefix", "0123456789/" ** 8 ++ "basename" }, - .out = &.{ "prefix", "0123456789/" ** 8 ++ "basename" }, + .in = &.{ "prefix", repeatString(8, "0123456789/") ++ "basename" }, + .out = &.{ "prefix", repeatString(8, "0123456789/") ++ "basename" }, }, // put as much as you can into prefix the rest goes into name .{ - .in = &.{ "prefix", "0123456789/" ** 10 ++ "basename" }, - .out = &.{ "prefix/" ++ "0123456789/" ** 9 ++ "0123456789", "basename" }, + .in = &.{ "prefix", repeatString(10, "0123456789/") ++ "basename" }, + .out = &.{ "prefix/" ++ repeatString(9, "0123456789/") ++ "0123456789", "basename" }, }, .{ - .in = &.{ "prefix", "0123456789/" ** 15 ++ "basename" }, - .out = &.{ "prefix/" ++ "0123456789/" ** 12 ++ "0123456789", "0123456789/0123456789/basename" }, + .in = &.{ "prefix", repeatString(15, "0123456789/") ++ "basename" }, + .out = &.{ "prefix/" ++ repeatString(12, "0123456789/") ++ "0123456789", "0123456789/0123456789/basename" }, }, .{ - .in = &.{ "prefix", "0123456789/" ** 21 ++ "basename" }, - .out = &.{ "prefix/" ++ "0123456789/" ** 12 ++ "0123456789", "0123456789/" ** 8 ++ "basename" }, + .in = &.{ "prefix", repeatString(21, "0123456789/") ++ "basename" }, + .out = &.{ "prefix/" ++ repeatString(12, "0123456789/") ++ "0123456789", repeatString(8, "0123456789/") ++ "basename" }, }, .{ - .in = &.{ "", "012345678/" ** 10 ++ "foo" }, - .out = &.{ "012345678/" ** 9 ++ "012345678", "foo" }, + .in = &.{ "", repeatString(10, "012345678/") ++ "foo" }, + .out = &.{ repeatString(9, "012345678/") ++ "012345678", "foo" }, }, }; @@ -378,10 +378,10 @@ pub const Header = extern struct { // basename can't fit into name (106 characters) .{ .in = &.{ "zig", "test/cases/compile_errors/regression_test_2980_base_type_u32_is_not_type_checked_properly_when_assigning_a_value_within_a_struct.zig" } }, // cant fit into 255 + sep - .{ .in = &.{ "prefix", "0123456789/" ** 22 ++ "basename" } }, + .{ .in = &.{ "prefix", repeatString(22, "0123456789/") ++ "basename" } }, // can fit but sub_path can't be split (there is no separator) - .{ .in = &.{ "prefix", "0123456789" ** 10 ++ "a" } }, - .{ .in = &.{ "prefix", "0123456789" ** 14 ++ "basename" } }, + .{ .in = &.{ "prefix", repeatString(10, "0123456789") ++ "a" } }, + .{ .in = &.{ "prefix", repeatString(14, "0123456789") ++ "basename" } }, }; for (error_cases) |case| { @@ -404,11 +404,11 @@ test "write files" { content: []const u8, }{ .{ .path = "foo", .content = "bar" }, - .{ .path = "a12345678/" ** 10 ++ "foo", .content = "a" ** 511 }, - .{ .path = "b12345678/" ** 24 ++ "foo", .content = "b" ** 512 }, - .{ .path = "c12345678/" ** 25 ++ "foo", .content = "c" ** 513 }, - .{ .path = "d12345678/" ** 51 ++ "foo", .content = "d" ** 1025 }, - .{ .path = "e123456789" ** 11, .content = "e" }, + .{ .path = repeatString(10, "a12345678/") ++ "foo", .content = repeatString(511, "a") }, + .{ .path = repeatString(24, "b12345678/") ++ "foo", .content = repeatString(512, "b") }, + .{ .path = repeatString(25, "c12345678/") ++ "foo", .content = repeatString(513, "c") }, + .{ .path = repeatString(51, "d12345678/") ++ "foo", .content = repeatString(1025, "d") }, + .{ .path = repeatString(11, "e123456789"), .content = "e" }, }; var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; @@ -482,3 +482,9 @@ test "write files" { try w.finishPedantically(); } } + +/// Marked `inline` to avoid unnecessary binary float, since arguments are always comptime-known. +inline fn repeatString(comptime n: usize, comptime str: []const u8) []const u8 { + const buf: [n][str.len]u8 = @splat(str[0..str.len].*); + return @ptrCast(&buf); +} diff --git a/lib/std/tar/test.zig b/lib/std/tar/test.zig @@ -53,7 +53,7 @@ const trailing_slash_case: Case = .{ .data = @embedFile("testdata/trailing-slash.tar"), .files = &[_]Case.File{ .{ - .name = "123456789/" ** 30, + .name = @ptrCast(&@as([30][10]u8, @splat("123456789/".*))), .kind = .directory, }, }, @@ -64,7 +64,11 @@ const writer_big_long_case: Case = .{ .data = @embedFile("testdata/writer-big-long.tar"), .files = &[_]Case.File{ .{ - .name = "longname/" ** 15 ++ "16gig.txt", + .name = name: { + const buf: [15][9]u8 = @splat("longname/".*); + const dir: []const u8 = @ptrCast(&buf); + break :name dir ++ "16gig.txt"; + }, .size = 16 * 1024 * 1024 * 1024, .mode = 0o644, .truncated = true, diff --git a/lib/std/unicode.zig b/lib/std/unicode.zig @@ -275,11 +275,16 @@ fn utf8ValidateSliceImpl(input: []const u8, comptime surrogates: Surrogates) boo const s7 = 0x44; // accept 4, size 4 // Information about the first byte in a UTF-8 sequence. - const first = comptime ([_]u8{as} ** 128) ++ ([_]u8{xx} ** 64) ++ [_]u8{ - xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, - s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, - s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, - s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + const first = comptime first: { + const a: [128]u8 = @splat(as); + const b: [64]u8 = @splat(xx); + const c: [64]u8 = .{ + xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, + s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, + s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, + s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, + }; + break :first a ++ b ++ c; }; const n = remaining.len; @@ -647,7 +652,7 @@ test "validate slice" { // We skip a variable (based on recommended vector size) chunks of // ASCII characters. Let's make sure we're chunking correctly. - const str = [_]u8{'a'} ** 550 ++ "\xc0"; + const str = @as([550]u8, @splat('a')) ++ "\xc0"; for (0..str.len - 3) |i| { try testing.expect(!utf8ValidateSlice(str[i..])); } @@ -1394,7 +1399,7 @@ test "ArrayList functions on a re-used list" { fn utf8ToUtf16LeStringLiteralImpl(comptime utf8: []const u8, comptime surrogates: Surrogates) *const [calcUtf16LeLenImpl(utf8, surrogates) catch |err| @compileError(err):0]u16 { return comptime blk: { const len: usize = calcUtf16LeLenImpl(utf8, surrogates) catch unreachable; - var utf16le: [len:0]u16 = [_:0]u16{0} ** len; + var utf16le: [len:0]u16 = @splat(0); const utf16le_len = utf8ToUtf16LeImpl(&utf16le, utf8[0..], surrogates) catch |err| @compileError(err); assert(len == utf16le_len); const final = utf16le; @@ -1640,7 +1645,7 @@ test "validate WTF-8 slice" { // We skip a variable (based on recommended vector size) chunks of // ASCII characters. Let's make sure we're chunking correctly. - const str = [_]u8{'a'} ** 550 ++ "\xc0"; + const str = @as([550]u8, @splat('a')) ++ "\xc0"; for (0..str.len - 3) |i| { try testing.expect(!wtf8ValidateSlice(str[i..])); } diff --git a/lib/std/unicode/throughput_test.zig b/lib/std/unicode/throughput_test.zig @@ -63,21 +63,27 @@ pub fn main(init: std.process.Init) !void { try stdout.print("pure ASCII strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("hello" ** 16, io); + const part = "hello"; + const buf: [16][part.len]u8 = @splat(part.*); + const result = try benchmarkCodepointCount(@ptrCast(&buf), io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.print("pure Unicode strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("こんにちは" ** 16, io); + const part = "こんにちは"; + const buf: [16][part.len]u8 = @splat(part.*); + const result = try benchmarkCodepointCount(@ptrCast(&buf), io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.print("mixed ASCII/Unicode strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("Hyvää huomenta" ** 16, io); + const part = "Hyvää huomenta"; + const buf: [16][part.len]u8 = @splat(part.*); + const result = try benchmarkCodepointCount(@ptrCast(&buf), io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.flush(); diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig @@ -4795,7 +4795,7 @@ fn testDecl( .noalias_bits = 0, // Tests don't have a prototype that needs hashing - .proto_hash = .{0} ** 16, + .proto_hash = @splat(0), }); _ = try decl_block.addBreak(.break_inline, decl_inst, func_inst); diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig @@ -46,7 +46,7 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const found: bool, allocated: ?[:0]u8, }; - var found_keys = [1]FoundKey{FoundKey{ .found = false, .allocated = null }} ** fields.len; + var found_keys: [fields.len]FoundKey = @splat(.{ .found = false, .allocated = null }); errdefer { self = .{}; for (found_keys) |found_key| { diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig @@ -120,7 +120,7 @@ fn iterateAndFilterByVersion( if (!std.mem.startsWith(u8, entry.name, prefix)) continue; var version: Version = .{ - .nums = .{0} ** 4, + .nums = @splat(0), .build = "", }; const suffix = entry.name[prefix.len..]; diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig @@ -7628,9 +7628,7 @@ pub const Constant = enum(u32) { const expected_limbs = @divExact(512, @bitSizeOf(std.math.big.Limb)); string: [ (std.math.big.int.Const{ - .limbs = &([1]std.math.big.Limb{ - maxInt(std.math.big.Limb), - } ** expected_limbs), + .limbs = &@splat(maxInt(std.math.big.Limb)), .positive = false, }).sizeInBaseUpperBound(10) ]u8, @@ -9347,7 +9345,7 @@ pub fn nanConst(self: *Builder, ty: Type) Allocator.Error!Constant { .double => try self.doubleConst(std.math.nan(f64)), .fp128 => try self.fp128Const(std.math.nan(f128)), .x86_fp80 => try self.x86_fp80Const(std.math.nan(f80)), - .ppc_fp128 => try self.ppc_fp128Const(.{std.math.nan(f64)} ** 2), + .ppc_fp128 => try self.ppc_fp128Const(@splat(.{std.math.nan(f64)})), else => unreachable, }; } @@ -10597,9 +10595,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void const expected_limbs = @divExact(512, @bitSizeOf(std.math.big.Limb)); string: [ (std.math.big.int.Const{ - .limbs = &([1]std.math.big.Limb{ - maxInt(std.math.big.Limb), - } ** expected_limbs), + .limbs = &@splat(maxInt(std.math.big.Limb)), .positive = false, }).sizeInBaseUpperBound(10) ]u8, diff --git a/src/Air/Liveness.zig b/src/Air/Liveness.zig @@ -611,7 +611,7 @@ fn analyzeInst( const call = a.air.unwrapCall(inst); const args = call.args; if (args.len + 1 <= bpi - 1) { - var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1); + var buf: [bpi - 1]Air.Inst.Ref = @splat(.none); buf[0] = call.callee; @memcpy(buf[1..][0..args.len], args); return analyzeOperands(a, pass, data, inst, buf); @@ -655,7 +655,7 @@ fn analyzeInst( const elements = @as([]const Air.Inst.Ref, @ptrCast(a.air.extra.items[ty_pl.payload..][0..len])); if (elements.len <= bpi - 1) { - var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1); + var buf: [bpi - 1]Air.Inst.Ref = @splat(.none); @memcpy(buf[0..elements.len], elements); return analyzeOperands(a, pass, data, inst, buf); } @@ -711,7 +711,7 @@ fn analyzeInst( const inputs = unwrapped_asm.inputs; const num_operands = simple: { - var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1); + var buf: [bpi - 1]Air.Inst.Ref = @splat(.none); var buf_index: usize = 0; for (unwrapped_asm.outputs) |output| { if (output != .none) { @@ -1421,7 +1421,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type { inst: Air.Inst.Index, operands_remaining: u32, - small: [bpi - 1]Air.Inst.Ref = .{.none} ** (bpi - 1), + small: [bpi - 1]Air.Inst.Ref = @splat(.none), extra_tombs: []u32, // Only used in `LivenessPass.main_analysis` diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig @@ -4345,7 +4345,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, try isel.emit(.ldr(neg_zero_ra.q(), .{ .literal = @intCast((isel.instructions.items.len + 1 + isel.literals.items.len) << 2), })); - try isel.emitLiteral(&(.{0} ** 15 ++ .{0x80})); + try isel.emitLiteral(&(@as([15]u8, @splat(0)) ++ .{0x80})); try src_mat.finish(isel); }, } @@ -4425,7 +4425,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, try isel.emit(.ldr(neg_zero_ra.q(), .{ .literal = @intCast((isel.instructions.items.len + 1 + isel.literals.items.len) << 2), })); - try isel.emitLiteral(&(.{0} ** 15 ++ .{0x80})); + try isel.emitLiteral(&(@as([15]u8, @splat(0)) ++ .{0x80})); try src_mat.finish(isel); }, } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig @@ -647,7 +647,11 @@ pub const Object = struct { debug_enums_fwd_ref.toOptional(), debug_globals_fwd_ref.toOptional(), }; - } else .{Builder.Metadata.Optional.none} ** 3; + } else .{ + Builder.Metadata.Optional.none, + Builder.Metadata.Optional.none, + Builder.Metadata.Optional.none, + }; const obj = try arena.create(Object); obj.* = .{ @@ -1439,7 +1443,7 @@ pub const Object = struct { ); llvm_function.setSubprogram(subprogram, &o.builder); break :debug_info .{ file, subprogram }; - } else .{undefined} ** 2; + } else .{ undefined, undefined }; const fuzz: ?FuncGen.Fuzz = f: { if (!owner_mod.fuzz) break :f null; diff --git a/src/codegen/llvm/FuncGen.zig b/src/codegen/llvm/FuncGen.zig @@ -3981,7 +3981,7 @@ fn buildFloatOp( const scalar_llvm_ty = try o.lowerType(scalar_ty); const libc_fn = try o.getLibcFunction( fn_name, - ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len], + @as([3]Builder.Type, @splat(scalar_llvm_ty))[0..params.len], scalar_llvm_ty, ); if (ty.zigTypeTag(zcu) == .vector) { diff --git a/src/codegen/riscv64/CodeGen.zig b/src/codegen/riscv64/CodeGen.zig @@ -6230,7 +6230,7 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { sym: SymbolOffset, }; - var ops: [4]Operand = .{.none} ** 4; + var ops: [4]Operand = @splat(.none); var last_op = false; var op_it = mem.splitAny(u8, mnem_it.rest(), ",("); next_op: for (&ops) |*op| { @@ -6466,7 +6466,7 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void { } simple: { - var buf = [1]Air.Inst.Ref{.none} ** (Air.Liveness.bpi - 1); + var buf: [Air.Liveness.bpi - 1]Air.Inst.Ref = @splat(.none); var buf_index: usize = 0; for (outputs) |output| { if (output == .none) continue; @@ -6581,7 +6581,7 @@ fn genInlineMemcpy( src_ptr: MCValue, len: MCValue, ) !void { - const regs = try func.register_manager.allocRegs(4, .{null} ** 4, abi.Registers.Integer.temporary); + const regs = try func.register_manager.allocRegs(4, @splat(null), abi.Registers.Integer.temporary); const locks = func.register_manager.lockRegsAssumeUnused(4, regs); defer for (locks) |lock| func.register_manager.unlockReg(lock); @@ -6691,7 +6691,7 @@ fn genInlineMemset( src_value: MCValue, len: MCValue, ) !void { - const regs = try func.register_manager.allocRegs(3, .{null} ** 3, abi.Registers.Integer.temporary); + const regs = try func.register_manager.allocRegs(3, @splat(null), abi.Registers.Integer.temporary); const locks = func.register_manager.lockRegsAssumeUnused(3, regs); defer for (locks) |lock| func.register_manager.unlockReg(lock); @@ -8076,7 +8076,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { }; if (elements.len <= Air.Liveness.bpi - 1) { - var buf = [1]Air.Inst.Ref{.none} ** (Air.Liveness.bpi - 1); + var buf: [Air.Liveness.bpi - 1]Air.Inst.Ref = @splat(.none); @memcpy(buf[0..elements.len], elements); return func.finishAir(inst, result, buf); } diff --git a/src/codegen/riscv64/abi.zig b/src/codegen/riscv64/abi.zig @@ -98,7 +98,7 @@ pub const SystemClass = enum { integer, float, memory, none }; /// There are a maximum of 8 possible return slots. Returned values are in /// the beginning of the array; unused slots are filled with .none. pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass { - var result = [1]SystemClass{.none} ** 8; + var result: [8]SystemClass = @splat(.none); const memory_class = [_]SystemClass{ .memory, .none, .none, .none, .none, .none, .none, .none, diff --git a/src/codegen/sparc64/CodeGen.zig b/src/codegen/sparc64/CodeGen.zig @@ -833,7 +833,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { }; if (elements.len <= Air.Liveness.bpi - 1) { - var buf = [1]Air.Inst.Ref{.none} ** (Air.Liveness.bpi - 1); + var buf: [Air.Liveness.bpi - 1]Air.Inst.Ref = @splat(.none); @memcpy(buf[0..elements.len], elements); return self.finishAir(inst, result, buf); } @@ -944,7 +944,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { }; simple: { - var buf = [1]Air.Inst.Ref{.none} ** (Air.Liveness.bpi - 1); + var buf: [Air.Liveness.bpi - 1]Air.Inst.Ref = @splat(.none); var buf_index: usize = 0; for (outputs) |output| { if (output == .none) continue; @@ -1344,7 +1344,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const result = info.return_value; if (args.len + 1 <= Air.Liveness.bpi - 1) { - var buf = [1]Air.Inst.Ref{.none} ** (Air.Liveness.bpi - 1); + var buf: [Air.Liveness.bpi - 1]Air.Inst.Ref = @splat(.none); buf[0] = call.callee; @memcpy(buf[1..][0..args.len], args); return self.finishAir(inst, result, buf); diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig @@ -181601,9 +181601,9 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty const ip = &zcu.intern_pool; var parts: [parts_len]Type = undefined; switch (ip.indexToKey(ty.toIntern())) { - .vector_type => |vector_type| if (std.math.divExact(u32, vector_type.len, parts_len)) |vec_len| return .{ - try pt.vectorType(.{ .len = vec_len, .child = vector_type.child }), - } ** parts_len else |err| switch (err) { + .vector_type => |vector_type| if (std.math.divExact(u32, vector_type.len, parts_len)) |vec_len| { + return @splat(try pt.vectorType(.{ .len = vec_len, .child = vector_type.child })); + } else |err| switch (err) { error.DivisionByZero => unreachable, error.UnexpectedRemainder => {}, }, @@ -188774,7 +188774,9 @@ const Select = struct { try pt.aggregateValue(try pt.vectorType(.{ .len = 4, .child = .u32_type }), &(.{ (try pt.intValue(.u32, @as(u64, @bitCast(@as(f64, 0x1p52))) >> 32)).toIntern(), (try pt.intValue(.u32, @as(u64, @bitCast(@as(f64, 0x1p84))) >> 32)).toIntern(), - } ++ .{(try pt.intValue(.u32, 0)).toIntern()} ** 2)), + (try pt.intValue(.u32, 0)).toIntern(), + (try pt.intValue(.u32, 0)).toIntern(), + })), ), true }, .f32_0_0x1p64_mem => .{ try cg.tempMemFromValue( try pt.aggregateValue(try pt.vectorType(.{ .len = 2, .child = .f32_type }), &.{ diff --git a/src/codegen/x86_64/Encoding.zig b/src/codegen/x86_64/Encoding.zig @@ -1044,9 +1044,17 @@ const mnemonic_to_encodings_map = init: { const index = &mnemonic_index[@intFromEnum(entry[0])]; mnemonic_map[@intFromEnum(entry[0])][index.*] = .{ .op_en = entry[1], - .ops = (entry[2] ++ .{.none} ** (ops_len - entry[2].len)).*, + .ops = ops: { + var ops: [ops_len]Op = @splat(.none); + @memcpy(ops[0..entry[2].len], entry[2]); + break :ops ops; + }, .opc_len = entry[3].len, - .opc = (entry[3] ++ .{undefined} ** (opc_len - entry[3].len)).*, + .opc = opc: { + var opc: [opc_len]u8 = @splat(undefined); + @memcpy(opc[0..entry[3].len], entry[3]); + break :opc opc; + }, .modrm_ext = entry[4], .mode = entry[5], .feature = entry[6], diff --git a/src/codegen/x86_64/encoder.zig b/src/codegen/x86_64/encoder.zig @@ -14,7 +14,7 @@ const Symbol = bits.Symbol; pub const Instruction = struct { prefix: Prefix = .none, encoding: Encoding, - ops: [4]Operand = .{.none} ** 4, + ops: [4]Operand = @splat(.none), pub const Mnemonic = Encoding.Mnemonic; @@ -335,7 +335,7 @@ pub const Instruction = struct { var inst: Instruction = .{ .prefix = prefix, .encoding = encoding, - .ops = [1]Operand{.none} ** 4, + .ops = @splat(.none), }; @memcpy(inst.ops[0..ops.len], ops); return inst; diff --git a/src/libs/mingw/implib.zig b/src/libs/mingw/implib.zig @@ -387,7 +387,7 @@ const first_string_table_entry = getNameBytesForStringTableOffset(first_string_t const byte_size_of_relocation = 10; fn getNameBytesForStringTableOffset(offset: u32) [8]u8 { - var bytes = [_]u8{0} ** 8; + var bytes: [8]u8 = @splat(0); std.mem.writeInt(u32, bytes[4..8], offset, .little); return bytes; } diff --git a/src/link/Coff.zig b/src/link/Coff.zig @@ -81,15 +81,31 @@ pub const msdos_stub: [120]u8 = .{ 0x00, 0x00, // Overlay number. Zero means this is the main executable. } // Reserved words. - ++ .{ 0x00, 0x00 } ** 4 - // OEM-related fields. + ++ .{ + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + } + // OEM-related fields. ++ .{ 0x00, 0x00, // OEM identifier. 0x00, 0x00, // OEM information. } // Reserved words. - ++ .{ 0x00, 0x00 } ** 10 - // Address of the PE header (a long). This matches the size of this entire MS-DOS stub, so that's the address of what's after this MS-DOS stub. + ++ .{ + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + } + // Address of the PE header (a long). This matches the size of this entire MS-DOS stub, so that's the address of what's after this MS-DOS stub. ++ .{ 0x78, 0x00, 0x00, 0x00 } // What follows is a 16-bit x86 MS-DOS program of 7 instructions that prints the bytes after these instructions and then exits. ++ .{ diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig @@ -2975,7 +2975,7 @@ fn finishWipNavFuncWriterError( wip_nav.unit, wip_nav.entry, dwarf, - ([1]u8{DW.RLE.start_end} ++ [1]u8{0} ** (8 + 8))[0 .. 1 + @intFromEnum(dwarf.address_size) + @intFromEnum(dwarf.address_size)], + ([1]u8{DW.RLE.start_end} ++ @as([8 + 8]u8, @splat(0)))[0 .. 1 + @intFromEnum(dwarf.address_size) + @intFromEnum(dwarf.address_size)], ); } diff --git a/src/link/Elf.zig b/src/link/Elf.zig @@ -3943,7 +3943,7 @@ fn formatPhdr(ctx: FormatPhdr, writer: *std.Io.Writer) std.Io.Writer.Error!void const write = phdr.p_flags & elf.PF_W != 0; const read = phdr.p_flags & elf.PF_R != 0; const exec = phdr.p_flags & elf.PF_X != 0; - var flags: [3]u8 = [_]u8{'_'} ** 3; + var flags: [3]u8 = @splat('_'); if (exec) flags[0] = 'X'; if (write) flags[1] = 'W'; if (read) flags[2] = 'R'; diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig @@ -363,7 +363,7 @@ const Format = struct { if (symbol.atom(elf_file)) |atom_ptr| { try writer.print(" : atom({d})", .{atom_ptr.atom_index}); } - var buf: [2]u8 = .{'_'} ** 2; + var buf: [2]u8 = @splat('_'); if (symbol.flags.@"export") buf[0] = 'E'; if (symbol.flags.import) buf[1] = 'I'; try writer.print(" : {s}", .{&buf}); diff --git a/src/link/MachO.zig b/src/link/MachO.zig @@ -38,7 +38,7 @@ symtab_cmd: macho.symtab_command = .{}, dysymtab_cmd: macho.dysymtab_command = .{}, function_starts_cmd: macho.linkedit_data_command = .{ .cmd = .FUNCTION_STARTS }, data_in_code_cmd: macho.linkedit_data_command = .{ .cmd = .DATA_IN_CODE }, -uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 }, +uuid_cmd: macho.uuid_command = .{ .uuid = @splat(0) }, codesig_cmd: macho.linkedit_data_command = .{ .cmd = .CODE_SIGNATURE }, pagezero_seg_index: ?u8 = null, @@ -3763,7 +3763,7 @@ pub fn addSection( } pub fn makeStaticString(bytes: []const u8) [16]u8 { - var buf = [_]u8{0} ** 16; + var buf: [16]u8 = @splat(0); @memcpy(buf[0..bytes.len], bytes); return buf; } diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig @@ -95,7 +95,7 @@ const CodeDirectory = struct { }; comptime var i = 0; inline while (i < n_special_slots) : (i += 1) { - cdir.special_slots[i] = [_]u8{0} ** hash_size; + cdir.special_slots[i] = @splat(0); } return cdir; } diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig @@ -25,7 +25,7 @@ allocator: Allocator, file: ?Io.File, symtab_cmd: macho.symtab_command = .{}, -uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 }, +uuid_cmd: macho.uuid_command = .{ .uuid = @splat(0) }, segments: std.ArrayList(macho.segment_command_64) = .empty, sections: std.ArrayList(macho.section_64) = .empty, diff --git a/src/link/MachO/InternalObject.zig b/src/link/MachO/InternalObject.zig @@ -11,7 +11,7 @@ symbols_extra: std.ArrayList(u32) = .empty, globals: std.ArrayList(MachO.SymbolResolver.Index) = .empty, objc_methnames: std.ArrayList(u8) = .empty, -objc_selrefs: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64), +objc_selrefs: [@sizeOf(u64)]u8 = @splat(0), force_undefined: std.ArrayList(Symbol.Index) = .empty, entry_index: ?Symbol.Index = null, diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig @@ -325,7 +325,7 @@ const Format = struct { if (symbol.getAtom(f.macho_file)) |atom| { try w.print(" : atom({d})", .{atom.atom_index}); } - var buf: [3]u8 = .{'_'} ** 3; + var buf: [3]u8 = @splat('_'); if (symbol.flags.@"export") buf[0] = 'E'; if (symbol.flags.import) buf[1] = 'I'; switch (symbol.visibility) { diff --git a/test/behavior/array.zig b/test/behavior/array.zig @@ -104,18 +104,6 @@ test "array init with concat" { try expect(std.mem.eql(u8, &i, "abcd")); } -test "array init with mult" { - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - - const a = 'a'; - var i: [8]u8 = [2]u8{ a, 'b' } ** 4; - try expect(std.mem.eql(u8, &i, "abababab")); - - var j: [4]u8 = [1]u8{'a'} ** 4; - try expect(std.mem.eql(u8, &j, "aaaa")); -} - test "array literal with explicit type" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -320,7 +308,7 @@ test "set global var array via slice embedded in struct" { try expect(s_array[2].b == 3); } -test "read/write through global variable array of struct fields initialized via array mult" { +test "read/write through global variable array of struct fields initialized via splat" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -335,7 +323,7 @@ test "read/write through global variable array of struct fields initialized via term: usize, }; - var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1; + var storage: [1]MyStruct = @splat(.{ .term = 1 }); }; try S.doTheTest(); } @@ -641,8 +629,8 @@ test "array of array agregate init" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - var a = [1]u32{11} ** 10; - var b = [1][10]u32{a} ** 2; + var a: [10]u32 = @splat(11); + var b: [2][10]u32 = @splat(a); _ = .{ &a, &b }; try std.testing.expect(b[1][1] == 11); } diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig @@ -294,13 +294,6 @@ test "string concatenation simple" { try expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); } -test "array mult operator" { - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - - try expect(mem.eql(u8, "ab" ** 5, "ababababab")); -} - const global_a: i32 = 1234; const global_b: *const i32 = &global_a; const global_c: *const f32 = @as(*const f32, @ptrCast(global_b)); @@ -1041,7 +1034,7 @@ test "const alloc with comptime-known initializer is made comptime-known" { positive: bool, }; const biggest: Const = .{ - .limbs = &([1]usize{comptime std.math.maxInt(usize)} ** 128), + .limbs = &@as([128]usize, @splat(comptime std.math.maxInt(usize))), .positive = false, }; if (biggest.positive) @compileError("bad"); diff --git a/test/behavior/bit_shifting.zig b/test/behavior/bit_shifting.zig @@ -15,7 +15,7 @@ fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, compt shards: [1 << shard_key_bits]?*Node, pub fn create() Self { - return Self{ .shards = [_]?*Node{null} ** (1 << shard_key_bits) }; + return .{ .shards = @splat(null) }; } fn getShardKey(key: Key) ShardKey { diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig @@ -3036,7 +3036,7 @@ test "bitcast vector" { const u8x32 = @Vector(32, u8); const u32x8 = @Vector(8, u32); - const zerox32: u8x32 = [_]u8{0} ** 32; + const zerox32: u8x32 = @splat(0); const bigsum: u32x8 = @bitCast(zerox32); try std.testing.expectEqual(0, @reduce(.Add, bigsum)); } diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig @@ -727,15 +727,6 @@ test "array concatenation of function calls" { try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 })); } -test "array multiplication of function calls" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - - var a = oneItem(3) ** scalar(2); - try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 })); -} - fn oneItem(x: i32) [1]i32 { return [_]i32{x}; } @@ -814,41 +805,6 @@ test "array concatenation sets the sentinel - pointer" { try expect(ptr[5] == 69); } -test "array multiplication sets the sentinel - value" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - - var a = [2:7]u3{ 1, 6 }; - _ = &a; - const b = a ** 2; - comptime assert(@TypeOf(b) == [4:7]u3); - try expect(b[0] == 1); - try expect(b[1] == 6); - try expect(b[2] == 1); - try expect(b[3] == 6); - const ptr: [*]const u3 = &b; - try expect(ptr[4] == 7); -} - -test "array multiplication sets the sentinel - pointer" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - - var a = [2:7]u3{ 1, 6 }; - const b = &a ** 2; - comptime assert(@TypeOf(b) == *const [4:7]u3); - try expect(b[0] == 1); - try expect(b[1] == 6); - try expect(b[2] == 1); - try expect(b[3] == 6); - const ptr: [*]const u3 = b; - try expect(ptr[4] == 7); -} - test "comptime assign int to optional int" { comptime { var x: ?i32 = null; @@ -1094,7 +1050,7 @@ test "storing an array of type in a field" { fn foo() @This() { comptime var foobar: Foobar = undefined; - foobar.str = [_]u8{'a'} ** 1024; + foobar.str = @splat('a'); return foobar; } }; diff --git a/test/behavior/extern_struct_zero_size_fields.zig b/test/behavior/extern_struct_zero_size_fields.zig @@ -10,9 +10,9 @@ const T = extern struct { baz: struct {} = .{}, ayy: E = .the_only_possible_value, arr: [0]u0 = .{}, - matey: [128]void = [_]void{{}} ** 128, + matey: [128]void = @splat({}), running_out_of_ideas: packed struct {} = .{}, - one_more: [256]S = [_]S{.{}} ** 256, + one_more: [256]S = @splat(.{}), }; test { diff --git a/test/behavior/for.zig b/test/behavior/for.zig @@ -69,7 +69,11 @@ test "basic for loop" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - const expected_result = [_]u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3; + const expected_result: [24]u8 = .{ + 9, 8, 7, 6, 0, 1, 2, 3, + 9, 8, 7, 6, 0, 1, 2, 3, + 9, 8, 7, 6, 0, 1, 2, 3, + }; var buffer: [expected_result.len]u8 = undefined; var buf_index: usize = 0; diff --git a/test/behavior/memset.zig b/test/behavior/memset.zig @@ -109,7 +109,7 @@ test "memset with large array element, runtime known" { const A = [128]u64; var buf: [5]A = undefined; - var runtime_known_element = [_]u64{0} ** 128; + var runtime_known_element: A = @splat(0); _ = &runtime_known_element; @memset(&buf, runtime_known_element); for (buf[0]) |elem| try expect(elem == 0); @@ -127,7 +127,7 @@ test "memset with large array element, comptime known" { const A = [128]u64; var buf: [5]A = undefined; - const comptime_known_element = [_]u64{0} ** 128; + const comptime_known_element: A = @splat(0); @memset(&buf, comptime_known_element); for (buf[0]) |elem| try expect(elem == 0); for (buf[1]) |elem| try expect(elem == 0); diff --git a/test/behavior/optional.zig b/test/behavior/optional.zig @@ -621,7 +621,7 @@ test "copied optional doesn't alias source" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - var opt_x: ?[3]f32 = [_]f32{0.0} ** 3; + var opt_x: ?[3]f32 = @splat(0.0); const x = opt_x.?; opt_x.?[0] = 15.0; diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig @@ -883,7 +883,7 @@ test "pointer to container level packed struct field" { enable_5: bool, enable_6: bool, }, - var arr = [_]u32{0} ** 2; + var arr: [2]u32 = @splat(0); }; @as(*S, @ptrCast(&S.arr[0])).other_bits.enable_3 = true; try expect(S.arr[0] == 0x10000000); diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig @@ -627,7 +627,7 @@ test "pointer to array has explicit alignment" { return @alignCast(@as(*[4]Base2, @ptrCast(ptr))); } }; - var bases = [_]S.Base{.{ .a = 2 }} ** 4; + var bases: [4]S.Base = @splat(.{ .a = 2 }); const casted = S.func(&bases); try expect(casted[0].a == 2); } diff --git a/test/behavior/popcount.zig b/test/behavior/popcount.zig @@ -88,16 +88,16 @@ test "@popCount vectors" { fn testPopCountVectors() !void { { - var x: @Vector(8, u32) = [1]u32{0xffffffff} ** 8; + var x: @Vector(8, u32) = @splat(0xffffffff); _ = &x; - const expected = [1]u6{32} ** 8; + const expected: [8]u6 = @splat(32); const result: [8]u6 = @popCount(x); try expect(std.mem.eql(u6, &expected, &result)); } { - var x: @Vector(8, i16) = [1]i16{-1} ** 8; + var x: @Vector(8, i16) = @splat(-1); _ = &x; - const expected = [1]u5{16} ** 8; + const expected: [8]u5 = @splat(16); const result: [8]u5 = @popCount(x); try expect(std.mem.eql(u5, &expected, &result)); } diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig @@ -314,7 +314,7 @@ test "C pointer slice access" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - var buf: [10]u32 = [1]u32{42} ** 10; + var buf: [10]u32 = @splat(42); const c_ptr = @as([*c]const u32, @ptrCast(&buf)); var runtime_zero: usize = 0; @@ -768,16 +768,6 @@ test "array concat of slices gives ptr to array" { } } -test "array mult of slice gives ptr to array" { - comptime { - var a: []const u8 = "aoeu"; - _ = &a; - const c = a ** 2; - try expect(std.mem.eql(u8, c, "aoeuaoeu")); - try expect(@TypeOf(c) == *const [8]u8); - } -} - test "slice bounds in comptime concatenation" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; diff --git a/test/behavior/slice_sentinel_comptime.zig b/test/behavior/slice_sentinel_comptime.zig @@ -1,16 +1,19 @@ const builtin = @import("builtin"); +const undef_10_u8: [10]u8 = @splat(undefined); +const ff_10_u8: [10]u8 = @splat(0xFF); + test "comptime slice-sentinel in bounds (unterminated)" { // array comptime { - var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..3 :'d']; _ = slice; } // ptr_array comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -18,7 +21,7 @@ test "comptime slice-sentinel in bounds (unterminated)" { // vector_ConstPtrSpecialBaseArray comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -26,7 +29,7 @@ test "comptime slice-sentinel in bounds (unterminated)" { // vector_ConstPtrSpecialRef comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @as([*]u8, @ptrCast(&buf)); const slice = target[0..3 :'d']; _ = slice; @@ -34,7 +37,7 @@ test "comptime slice-sentinel in bounds (unterminated)" { // cvector_ConstPtrSpecialBaseArray comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -42,7 +45,7 @@ test "comptime slice-sentinel in bounds (unterminated)" { // cvector_ConstPtrSpecialRef comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @as([*c]u8, @ptrCast(&buf)); const slice = target[0..3 :'d']; _ = slice; @@ -50,7 +53,7 @@ test "comptime slice-sentinel in bounds (unterminated)" { // slice comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -60,14 +63,14 @@ test "comptime slice-sentinel in bounds (unterminated)" { test "comptime slice-sentinel in bounds (end,unterminated)" { // array comptime { - var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; + var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ ff_10_u8; const slice = target[0..13 :0xff]; _ = slice; } // ptr_array comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ ff_10_u8; var target = &buf; const slice = target[0..13 :0xff]; _ = slice; @@ -75,7 +78,7 @@ test "comptime slice-sentinel in bounds (end,unterminated)" { // vector_ConstPtrSpecialBaseArray comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ ff_10_u8; var target: [*]u8 = &buf; const slice = target[0..13 :0xff]; _ = slice; @@ -83,7 +86,7 @@ test "comptime slice-sentinel in bounds (end,unterminated)" { // vector_ConstPtrSpecialRef comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ ff_10_u8; var target: [*]u8 = @as([*]u8, @ptrCast(&buf)); const slice = target[0..13 :0xff]; _ = slice; @@ -91,7 +94,7 @@ test "comptime slice-sentinel in bounds (end,unterminated)" { // cvector_ConstPtrSpecialBaseArray comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ ff_10_u8; var target: [*c]u8 = &buf; const slice = target[0..13 :0xff]; _ = slice; @@ -99,7 +102,7 @@ test "comptime slice-sentinel in bounds (end,unterminated)" { // cvector_ConstPtrSpecialRef comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ ff_10_u8; var target: [*c]u8 = @as([*c]u8, @ptrCast(&buf)); const slice = target[0..13 :0xff]; _ = slice; @@ -107,7 +110,7 @@ test "comptime slice-sentinel in bounds (end,unterminated)" { // slice comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ ff_10_u8; var target: []u8 = &buf; const slice = target[0..13 :0xff]; _ = slice; @@ -117,14 +120,14 @@ test "comptime slice-sentinel in bounds (end,unterminated)" { test "comptime slice-sentinel in bounds (terminated)" { // array comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..3 :'d']; _ = slice; } // ptr_array comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -132,7 +135,7 @@ test "comptime slice-sentinel in bounds (terminated)" { // vector_ConstPtrSpecialBaseArray comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -140,7 +143,7 @@ test "comptime slice-sentinel in bounds (terminated)" { // vector_ConstPtrSpecialRef comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @as([*]u8, @ptrCast(&buf)); const slice = target[0..3 :'d']; _ = slice; @@ -148,7 +151,7 @@ test "comptime slice-sentinel in bounds (terminated)" { // cvector_ConstPtrSpecialBaseArray comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -156,7 +159,7 @@ test "comptime slice-sentinel in bounds (terminated)" { // cvector_ConstPtrSpecialRef comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @as([*c]u8, @ptrCast(&buf)); const slice = target[0..3 :'d']; _ = slice; @@ -164,7 +167,7 @@ test "comptime slice-sentinel in bounds (terminated)" { // slice comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..3 :'d']; _ = slice; @@ -174,14 +177,14 @@ test "comptime slice-sentinel in bounds (terminated)" { test "comptime slice-sentinel in bounds (on target sentinel)" { // array comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..14 :0]; _ = slice; } // ptr_array comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..14 :0]; _ = slice; @@ -189,7 +192,7 @@ test "comptime slice-sentinel in bounds (on target sentinel)" { // vector_ConstPtrSpecialBaseArray comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..14 :0]; _ = slice; @@ -197,7 +200,7 @@ test "comptime slice-sentinel in bounds (on target sentinel)" { // vector_ConstPtrSpecialRef comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @as([*]u8, @ptrCast(&buf)); const slice = target[0..14 :0]; _ = slice; @@ -205,7 +208,7 @@ test "comptime slice-sentinel in bounds (on target sentinel)" { // cvector_ConstPtrSpecialBaseArray comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..14 :0]; _ = slice; @@ -213,7 +216,7 @@ test "comptime slice-sentinel in bounds (on target sentinel)" { // cvector_ConstPtrSpecialRef comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @as([*c]u8, @ptrCast(&buf)); const slice = target[0..14 :0]; _ = slice; @@ -221,7 +224,7 @@ test "comptime slice-sentinel in bounds (on target sentinel)" { // slice comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..14 :0]; _ = slice; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig @@ -634,7 +634,7 @@ test "packed array 24bits" { try expect(@sizeOf(FooArray24Bits) == @sizeOf(u96)); } - var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1); + var bytes: [@sizeOf(FooArray24Bits) + 1]u8 = @splat(0); bytes[bytes.len - 1] = 0xbb; const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0]; try expect(ptr.a == 0); diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig @@ -26,29 +26,6 @@ test "tuple concatenation" { try comptime S.doTheTest(); } -test "tuple multiplication" { - const S = struct { - fn doTheTest() !void { - { - const t = .{} ** 4; - try expect(@typeInfo(@TypeOf(t)).@"struct".fields.len == 0); - } - { - const t = .{'a'} ** 4; - try expect(@typeInfo(@TypeOf(t)).@"struct".fields.len == 4); - inline for (t) |x| try expect(x == 'a'); - } - { - const t = .{ 1, 2, 3 } ** 4; - try expect(@typeInfo(@TypeOf(t)).@"struct".fields.len == 12); - inline for (t, 0..) |x, i| try expect(x == 1 + i % 3); - } - } - }; - try S.doTheTest(); - try comptime S.doTheTest(); -} - test "more tuple concatenation" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -357,7 +334,7 @@ test "tuple of struct concatenation and coercion to array" { const StructWithDefault = struct { value: f32 = 42 }; const SomeStruct = struct { array: [4]StructWithDefault }; - const value1 = SomeStruct{ .array = .{StructWithDefault{}} ++ [_]StructWithDefault{.{}} ** 3 }; + const value1 = SomeStruct{ .array = .{StructWithDefault{}} ++ @as([3]StructWithDefault, @splat(.{})) }; const value2 = SomeStruct{ .array = .{ .{}, .{}, .{}, .{} } }; try expectEqual(value1, value2); diff --git a/test/behavior/tuple_declarations.zig b/test/behavior/tuple_declarations.zig @@ -42,12 +42,6 @@ test "tuple declaration usage" { try expect(t[0] == 1); try expectEqualStrings(t[1], "foo"); - const mul = t ** 3; - try expect(@TypeOf(mul) != T); - try expect(mul.len == 6); - try expect(mul[2] == 1); - try expectEqualStrings(mul[3], "foo"); - var t2: T = .{ 2, "bar" }; _ = &t2; const cat = t ++ t2; diff --git a/test/behavior/undefined.zig b/test/behavior/undefined.zig @@ -90,7 +90,7 @@ test "reslice of undefined global var slice" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - var stack_buf: [100]u8 = [_]u8{0} ** 100; + var stack_buf: [100]u8 = @splat(0); buf = &stack_buf; const x = buf[0..1]; try @import("std").testing.expect(x.len == 1 and x[0] == 0); diff --git a/test/behavior/union.zig b/test/behavior/union.zig @@ -138,7 +138,7 @@ const Agg = struct { }; const v1 = Value{ .Int = 1234 }; -const v2 = Value{ .Array = [_]u8{3} ** 9 }; +const v2 = Value{ .Array = @splat(3) }; const err = @as(anyerror!Agg, Agg{ .val1 = v1, @@ -1156,7 +1156,7 @@ test "extern union most-aligned field is smaller" { }, un: [110]u8, }; - var a: ?U = .{ .un = [_]u8{0} ** 110 }; + var a: ?U = .{ .un = @splat(0) }; _ = &a; try expect(a != null); } diff --git a/test/behavior/void.zig b/test/behavior/void.zig @@ -44,7 +44,7 @@ test "void optional" { } test "void array as a local variable initializer" { - var x = [_]void{{}} ** 1004; + var x: [1004]void = @splat({}); _ = &x[0]; _ = x[0]; } diff --git a/test/c/unistd.zig b/test/c/unistd.zig @@ -22,14 +22,14 @@ test "swab" { // n < 1 @memset(a[0..], '\x00'); c.swab("abcd", &a, 0); - try testing.expectEqualSlices(u8, "\x00" ** 4, &a); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0 }, &a); c.swab("abcd", &a, -1); - try testing.expectEqualSlices(u8, "\x00" ** 4, &a); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0 }, &a); // Odd n @memset(a[0..], '\x00'); c.swab("abcd", &a, 1); - try testing.expectEqualSlices(u8, "\x00" ** 4, &a); + try testing.expectEqualSlices(u8, &.{ 0, 0, 0, 0 }, &a); c.swab("abcd", &a, 3); try testing.expectEqualSlices(u8, "ba\x00\x00", &a); } diff --git a/test/cases/compile_errors/Issue_6823_dont_allow_._to_be_followed_by_.zig b/test/cases/compile_errors/Issue_6823_dont_allow_._to_be_followed_by_.zig @@ -1,8 +0,0 @@ -fn foo() void { - var sequence = "repeat".*** 10; - _ = sequence; -} - -// error -// -// :2:28: error: '.*' cannot be followed by '*'; are you missing a space? diff --git a/test/cases/compile_errors/array_mult_with_number_type.zig b/test/cases/compile_errors/array_mult_with_number_type.zig @@ -1,9 +0,0 @@ -const exponent: f32 = 1.0; -export fn entry(base: f32) f32 { - return base ** exponent; -} - -// error -// -// :3:12: error: expected indexable; found 'f32' -// :3:17: note: this operator multiplies arrays; use std.math.pow for exponentiation diff --git a/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig @@ -1,13 +1,13 @@ export fn foo_array() void { comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..3 :0]; _ = slice; } } export fn foo_ptr_array() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..3 :0]; _ = slice; @@ -15,7 +15,7 @@ export fn foo_ptr_array() void { } export fn foo_vector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..3 :0]; _ = slice; @@ -23,7 +23,7 @@ export fn foo_vector_ConstPtrSpecialBaseArray() void { } export fn foo_vector_ConstPtrSpecialRef() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @ptrCast(&buf); const slice = target[0..3 :0]; _ = slice; @@ -31,7 +31,7 @@ export fn foo_vector_ConstPtrSpecialRef() void { } export fn foo_cvector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..3 :0]; _ = slice; @@ -39,7 +39,7 @@ export fn foo_cvector_ConstPtrSpecialBaseArray() void { } export fn foo_cvector_ConstPtrSpecialRef() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @ptrCast(&buf); const slice = target[0..3 :0]; _ = slice; @@ -47,12 +47,13 @@ export fn foo_cvector_ConstPtrSpecialRef() void { } export fn foo_slice() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..3 :0]; _ = slice; } } +const undef_10_u8: [10]u8 = @splat(undefined); // error // diff --git a/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig @@ -1,13 +1,13 @@ export fn foo_array() void { comptime { - var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..3 :0]; _ = slice; } } export fn foo_ptr_array() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..3 :0]; _ = slice; @@ -15,7 +15,7 @@ export fn foo_ptr_array() void { } export fn foo_vector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..3 :0]; _ = slice; @@ -23,7 +23,7 @@ export fn foo_vector_ConstPtrSpecialBaseArray() void { } export fn foo_vector_ConstPtrSpecialRef() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @ptrCast(&buf); const slice = target[0..3 :0]; _ = slice; @@ -31,7 +31,7 @@ export fn foo_vector_ConstPtrSpecialRef() void { } export fn foo_cvector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..3 :0]; _ = slice; @@ -39,7 +39,7 @@ export fn foo_cvector_ConstPtrSpecialBaseArray() void { } export fn foo_cvector_ConstPtrSpecialRef() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @ptrCast(&buf); const slice = target[0..3 :0]; _ = slice; @@ -47,12 +47,13 @@ export fn foo_cvector_ConstPtrSpecialRef() void { } export fn foo_slice() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..3 :0]; _ = slice; } } +const undef_10_u8: [10]u8 = @splat(undefined); // error // diff --git a/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig b/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig @@ -1,13 +1,13 @@ export fn foo_array() void { comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..14 :255]; _ = slice; } } export fn foo_ptr_array() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..14 :255]; _ = slice; @@ -15,7 +15,7 @@ export fn foo_ptr_array() void { } export fn foo_vector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..14 :255]; _ = slice; @@ -23,7 +23,7 @@ export fn foo_vector_ConstPtrSpecialBaseArray() void { } export fn foo_vector_ConstPtrSpecialRef() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @ptrCast(&buf); const slice = target[0..14 :255]; _ = slice; @@ -31,7 +31,7 @@ export fn foo_vector_ConstPtrSpecialRef() void { } export fn foo_cvector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..14 :255]; _ = slice; @@ -39,7 +39,7 @@ export fn foo_cvector_ConstPtrSpecialBaseArray() void { } export fn foo_cvector_ConstPtrSpecialRef() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @ptrCast(&buf); const slice = target[0..14 :255]; _ = slice; @@ -47,12 +47,13 @@ export fn foo_cvector_ConstPtrSpecialRef() void { } export fn foo_slice() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..14 :255]; _ = slice; } } +const undef_10_u8: [10]u8 = @splat(undefined); export fn undefined_slice() void { const arr: [100]u16 = undefined; const slice = arr[0..12 :0]; @@ -85,9 +86,9 @@ export fn typeName_slice() void { // :44:29: note: expected '255', found '0' // :52:29: error: value in memory does not match slice sentinel // :52:29: note: expected '255', found '0' -// :58:22: error: value in memory does not match slice sentinel -// :58:22: note: expected '0', found 'undefined' -// :63:22: error: value in memory does not match slice sentinel -// :63:22: note: expected '12', found '98' -// :68:22: error: value in memory does not match slice sentinel -// :68:22: note: expected '0', found '105' +// :59:22: error: value in memory does not match slice sentinel +// :59:22: note: expected '0', found 'undefined' +// :64:22: error: value in memory does not match slice sentinel +// :64:22: note: expected '12', found '98' +// :69:22: error: value in memory does not match slice sentinel +// :69:22: note: expected '0', found '105' diff --git a/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_terminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_terminated.zig @@ -1,13 +1,13 @@ export fn foo_array() void { comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..15 :1]; _ = slice; } } export fn foo_ptr_array() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..15 :0]; _ = slice; @@ -15,7 +15,7 @@ export fn foo_ptr_array() void { } export fn foo_vector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..15 :0]; _ = slice; @@ -23,7 +23,7 @@ export fn foo_vector_ConstPtrSpecialBaseArray() void { } export fn foo_vector_ConstPtrSpecialRef() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @ptrCast(&buf); const slice = target[0..15 :0]; _ = slice; @@ -31,7 +31,7 @@ export fn foo_vector_ConstPtrSpecialRef() void { } export fn foo_cvector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..15 :0]; _ = slice; @@ -39,7 +39,7 @@ export fn foo_cvector_ConstPtrSpecialBaseArray() void { } export fn foo_cvector_ConstPtrSpecialRef() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @ptrCast(&buf); const slice = target[0..15 :0]; _ = slice; @@ -47,12 +47,13 @@ export fn foo_cvector_ConstPtrSpecialRef() void { } export fn foo_slice() void { comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..15 :0]; _ = slice; } } +const undef_10_u8: [10]u8 = @splat(undefined); // error // diff --git a/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig @@ -1,13 +1,13 @@ export fn foo_array() void { comptime { - var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; const slice = target[0..14 :0]; _ = slice; } } export fn foo_ptr_array() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target = &buf; const slice = target[0..14 :0]; _ = slice; @@ -15,7 +15,7 @@ export fn foo_ptr_array() void { } export fn foo_vector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = &buf; const slice = target[0..14 :0]; _ = slice; @@ -23,7 +23,7 @@ export fn foo_vector_ConstPtrSpecialBaseArray() void { } export fn foo_vector_ConstPtrSpecialRef() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*]u8 = @ptrCast(&buf); const slice = target[0..14 :0]; _ = slice; @@ -31,7 +31,7 @@ export fn foo_vector_ConstPtrSpecialRef() void { } export fn foo_cvector_ConstPtrSpecialBaseArray() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = &buf; const slice = target[0..14 :0]; _ = slice; @@ -39,7 +39,7 @@ export fn foo_cvector_ConstPtrSpecialBaseArray() void { } export fn foo_cvector_ConstPtrSpecialRef() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: [*c]u8 = @ptrCast(&buf); const slice = target[0..14 :0]; _ = slice; @@ -47,12 +47,13 @@ export fn foo_cvector_ConstPtrSpecialRef() void { } export fn foo_slice() void { comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ undef_10_u8; var target: []u8 = &buf; const slice = target[0..14 :0]; _ = slice; } } +const undef_10_u8: [10]u8 = @splat(undefined); // error // diff --git a/test/cases/compile_errors/dereference_bad_pointer_via_array_mul.zig b/test/cases/compile_errors/dereference_bad_pointer_via_array_mul.zig @@ -1,11 +0,0 @@ -const A = struct {}; -const B = struct {}; -comptime { - const val: [1]A = .{.{}}; - const ptr: *const [1]B = @ptrCast(&val); - _ = ptr ** 2; -} - -// error -// -// :6:9: error: comptime dereference requires '[1]tmp.B' to have a well-defined layout diff --git a/test/cases/compile_errors/function_call_assigned_to_incorrect_type.zig b/test/cases/compile_errors/function_call_assigned_to_incorrect_type.zig @@ -3,7 +3,7 @@ export fn entry() void { arr = concat(); } fn concat() [16]f32 { - return [1]f32{0} ** 16; + return @splat(0.0); } // error diff --git a/test/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig b/test/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig @@ -1,5 +1,5 @@ export fn foo() void { - const bytes align(@alignOf([]const u8)) = [1]u8{0xfa} ** 16; + const bytes: [16]u8 align(@alignOf([]const u8)) = @splat(0xFA); _ = @as(*const []const u8, @ptrCast(&bytes)).*; } diff --git a/test/cases/safety/memcpy_alias.zig b/test/cases/safety/memcpy_alias.zig @@ -8,7 +8,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi std.process.exit(1); } pub fn main() !void { - var buffer = [2]u8{ 1, 2 } ** 5; + var buffer: [10]u8 = .{ 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 }; var len: usize = 5; _ = &len; @memcpy(buffer[0..len], buffer[4 .. 4 + len]); diff --git a/test/cases/safety/memcpy_len_mismatch.zig b/test/cases/safety/memcpy_len_mismatch.zig @@ -8,7 +8,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi std.process.exit(1); } pub fn main() !void { - var buffer = [2]u8{ 1, 2 } ** 5; + var buffer: [10]u8 = .{ 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 }; var len: usize = 5; _ = &len; @memcpy(buffer[0..len], buffer[len .. len + 4]); diff --git a/test/cases/safety/memmove_len_mismatch.zig b/test/cases/safety/memmove_len_mismatch.zig @@ -8,7 +8,7 @@ pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usi std.process.exit(1); } pub fn main() !void { - var buffer = [2]u8{ 1, 2 } ** 5; + var buffer: [10]u8 = .{ 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 }; var len: usize = 5; _ = &len; @memmove(buffer[0..len], buffer[len .. len + 4]); diff --git a/tools/fetch_them_macos_headers.zig b/tools/fetch_them_macos_headers.zig @@ -237,7 +237,7 @@ const Version = struct { patch: u8, fn parse(raw: []const u8) ?Version { - var parsed: [3]u16 = [_]u16{0} ** 3; + var parsed: [3]u16 = @splat(0); var count: usize = 0; var it = std.mem.splitAny(u8, raw, "."); while (it.next()) |comp| { diff --git a/tools/gen_spirv_spec.zig b/tools/gen_spirv_spec.zig @@ -732,7 +732,7 @@ fn renderBitEnum( ) !void { try writer.print("pub const {f} = packed struct {{\n", .{std.zig.fmtId(enumeration.kind)}); - var flags_by_bitpos = [_]?usize{null} ** 32; + var flags_by_bitpos: [32]?usize = @splat(null); const enumerants = enumeration.enumerants orelse return error.InvalidRegistry; var aliases = std.array_list.Managed(struct { flag: usize, alias: u5 }).init(arena); diff --git a/tools/gen_stubs.zig b/tools/gen_stubs.zig @@ -702,12 +702,12 @@ fn parseElf(parse: Parse, comptime is_64: bool, comptime endian: std.builtin.End } } else { gop.value_ptr.* = .{ - .present = [1]bool{false} ** arches.len, + .present = @splat(false), .section = section_index_map[this_section], .ty = ty, - .binding = [1]u4{0} ** arches.len, + .binding = @splat(0), .visib = visib, - .size = [1]u64{0} ** arches.len, + .size = @splat(0), }; } gop.value_ptr.present[archIndex(parse.arch)] = true; diff --git a/tools/generate_JSONTestSuite.zig b/tools/generate_JSONTestSuite.zig @@ -4,15 +4,15 @@ const std = @import("std"); const Io = std.Io; pub fn main(init: std.process.Init) !void { - const allocator = init.gpa; + const allocator = init.arena.allocator(); const io = init.io; var stdout_buffer: [2000]u8 = undefined; var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); const output = &stdout_writer.interface; try output.writeAll( - \\// This file was generated by _generate_JSONTestSuite.zig - \\// These test cases are sourced from: https://github.com/nst/JSONTestSuite + \\//! This file was generated by _generate_JSONTestSuite.zig + \\//! These test cases are sourced from: https://github.com/nst/JSONTestSuite \\const ok = @import("./test.zig").ok; \\const err = @import("./test.zig").err; \\const any = @import("./test.zig").any; @@ -33,7 +33,7 @@ pub fn main(init: std.process.Init) !void { }).lessThan); for (names.items) |name| { - const contents = try Io.Dir.cwd().readFileAlloc(io, name, allocator, .limited(250001)); + const contents = try Io.Dir.cwd().readFileAlloc(io, name, allocator, .limited(300000)); try output.writeAll("test "); try writeString(output, name); try output.writeAll(" {\n try "); @@ -51,21 +51,34 @@ pub fn main(init: std.process.Init) !void { try output.flush(); } -const i_structure_500_nested_arrays = "[" ** 500 ++ "]" ** 500; -const n_structure_100000_opening_arrays = "[" ** 100000; -const n_structure_open_array_object = "[{\"\":" ** 50000 ++ "\n"; +const i_structure_500_nested_arrays = &(@as([500]u8, @splat('[')) ++ @as([500]u8, @splat(']'))); +const n_structure_100000_opening_arrays: *const [100000]u8 = &@splat('['); +const n_structure_open_array_object = str: { + const part = "[{\"\":"; + const buf: [50000][part.len]u8 = @splat(part.*); + const s: []const u8 = @ptrCast(&buf); + break :str s ++ "\n"; +}; fn writeString(writer: anytype, s: []const u8) !void { if (s.len > 200) { // There are a few of these we can compress with Zig expressions. if (std.mem.eql(u8, s, i_structure_500_nested_arrays)) { - return writer.writeAll("\"[\" ** 500 ++ \"]\" ** 500"); + return writer.writeAll("&@as([500]u8, @splat('[')) ++ &@as([500]u8, @splat(']'))"); } else if (std.mem.eql(u8, s, n_structure_100000_opening_arrays)) { - return writer.writeAll("\"[\" ** 100000"); + return writer.writeAll("&@as([100000]u8, @splat('['))"); } else if (std.mem.eql(u8, s, n_structure_open_array_object)) { - return writer.writeAll("\"[{\\\"\\\":\" ** 50000 ++ \"\\n\""); + return writer.writeAll( + \\str: { + \\ const part = "[{\"\":"; + \\ const buf: [50000][part.len]u8 = @splat(part.*); + \\ const s: []const u8 = @ptrCast(&buf); + \\ break :str s ++ "\n"; + \\ } + ); + } else { + @panic("unhandled long string literal"); } - unreachable; } try writer.writeByte('"'); for (s) |b| {