From 0e405c5fc52945a03711454e86c1caa7c72c4d02 Mon Sep 17 00:00:00 2001 From: Vexu <15308111+Vexu@users.noreply.github.com> Date: Tue, 19 Nov 2019 22:54:32 +0200 Subject: [PATCH 01/19] add missing cast to call result type --- src/ir.cpp | 5 +++++ test/compile_errors.zig | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/ir.cpp b/src/ir.cpp index db135092e0fcec68ab045a0f74bad0ae9f2f11ac..92ef48f50f70955146bc5ef897bfd57314ebf0bc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17682,6 +17682,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { ir_reset_result(call_instruction->result_loc); result_loc = nullptr; + } else { + call_instruction->base.value.type = return_type; + IrInstruction *casted_value = ir_implicit_cast(ira, &call_instruction->base, result_loc->value.type->data.pointer.child_type); + if (type_is_invalid(casted_value->value.type)) + return casted_value; } } } else if (call_instruction->is_async_call_builtin) { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index c1e2d579a40781818d85e63e3b9e1e38029a679b..35d462289f09534f33290e50264ef188d958f8e1 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -96,6 +96,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:11:25: error: expected type 'u32', found '@typeOf(get_uval).ReturnType.ErrorSet!u32'", ); + cases.add( + "function call assigned to incorrect type", + \\export fn entry() void { + \\ var arr: [4]f32 = undefined; + \\ arr = concat(); + \\} + \\fn concat() [16]f32 { + \\ return [1]f32{0}**16; + \\} + , + "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'" + ); + cases.add( "asigning to struct or union fields that are not optionals with a function that returns an optional", \\fn maybe(is: bool) ?u8 { -- 2.54.0 From 379d547603badb2667089c85454a2e3f5ede3342 Mon Sep 17 00:00:00 2001 From: Vexu <15308111+Vexu@users.noreply.github.com> Date: Wed, 20 Nov 2019 07:54:47 +0200 Subject: [PATCH 02/19] add missing cast to generic function call result --- src/ir.cpp | 5 +++++ test/compile_errors.zig | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/ir.cpp b/src/ir.cpp index 92ef48f50f70955146bc5ef897bfd57314ebf0bc..2772108a21d39e5f426a7f72e2fdf2da41b659c5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17520,6 +17520,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { ir_reset_result(call_instruction->result_loc); result_loc = nullptr; + } else { + call_instruction->base.value.type = impl_fn_type_id->return_type; + IrInstruction *casted_value = ir_implicit_cast(ira, &call_instruction->base, result_loc->value.type->data.pointer.child_type); + if (type_is_invalid(casted_value->value.type)) + return casted_value; } } } else if (call_instruction->is_async_call_builtin) { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 35d462289f09534f33290e50264ef188d958f8e1..4008ff19e116217f399b5f6d47c813259e146f41 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -109,6 +109,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'" ); + cases.add( + "generic function call assigned to incorrect type", + \\pub export fn entry() void { + \\ var res: []i32 = undefined; + \\ res = myAlloc(i32); + \\} + \\fn myAlloc(comptime arg: type) anyerror!arg{ + \\ unreachable; + \\} + , + "tmp.zig:3:18: error: expected type '[]i32', found 'anyerror!i32" + ); + cases.add( "asigning to struct or union fields that are not optionals with a function that returns an optional", \\fn maybe(is: bool) ?u8 { -- 2.54.0 From bf3ac6615051143a9ef41180cd74e88de5dd573d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 27 Nov 2019 03:30:39 -0500 Subject: [PATCH 03/19] remove type coercion from array values to references * Implements #3768. This is a sweeping breaking change that requires many (trivial) edits to Zig source code. Array values no longer coerced to slices; however one may use `&` to obtain a reference to an array value, which may then be coerced to a slice. * Adds `IrInstruction::dump`, for debugging purposes. It's useful to call to inspect the instruction when debugging Zig IR. * Fixes bugs with result location semantics. See the new behavior test cases, and compile error test cases. * Fixes bugs with `@typeInfo` not properly resolving const values. * Behavior tests are passing but std lib tests are not yet. There is more work to do before merging this branch. --- build.zig | 30 +- lib/std/array_list.zig | 15 +- lib/std/bloom_filter.zig | 6 +- lib/std/build.zig | 57 +-- lib/std/crypto/aes.zig | 4 +- lib/std/crypto/blake2.zig | 4 +- lib/std/crypto/chacha20.zig | 14 +- lib/std/crypto/gimli.zig | 8 +- lib/std/crypto/md5.zig | 2 +- lib/std/crypto/poly1305.zig | 2 +- lib/std/crypto/sha1.zig | 2 +- lib/std/crypto/sha2.zig | 4 +- lib/std/crypto/sha3.zig | 4 +- lib/std/crypto/test.zig | 4 +- lib/std/crypto/x25519.zig | 36 +- lib/std/debug.zig | 2 +- lib/std/elf.zig | 2 +- lib/std/event/loop.zig | 4 +- lib/std/fifo.zig | 10 +- lib/std/fmt.zig | 25 +- lib/std/fs.zig | 6 +- lib/std/fs/get_app_data_dir.zig | 6 +- lib/std/fs/path.zig | 120 ++--- lib/std/hash/cityhash.zig | 2 +- lib/std/hash/murmur.zig | 2 +- lib/std/hash_map.zig | 2 +- lib/std/http/headers.zig | 4 +- lib/std/io.zig | 2 +- lib/std/io/out_stream.zig | 10 +- lib/std/io/test.zig | 8 +- lib/std/mem.zig | 128 +++-- lib/std/meta/trait.zig | 2 +- lib/std/net.zig | 8 +- lib/std/os/test.zig | 2 +- lib/std/packed_int_array.zig | 24 +- lib/std/priority_queue.zig | 2 +- lib/std/process.zig | 14 +- lib/std/rand.zig | 2 +- lib/std/segmented_list.zig | 12 +- lib/std/sort.zig | 86 ++-- lib/std/unicode.zig | 12 +- lib/std/zig/tokenizer.zig | 122 ++--- src-self-hosted/dep_tokenizer.zig | 4 +- src-self-hosted/main.zig | 2 +- src-self-hosted/stage1.zig | 4 +- src/all_types.hpp | 3 + src/ir.cpp | 436 +++++++----------- test/compare_output.zig | 4 +- test/stage1/behavior/array.zig | 44 +- test/stage1/behavior/async_fn.zig | 12 +- test/stage1/behavior/await_struct.zig | 2 +- test/stage1/behavior/bugs/1607.zig | 4 +- test/stage1/behavior/bugs/1914.zig | 4 +- test/stage1/behavior/cast.zig | 49 +- test/stage1/behavior/eval.zig | 6 +- test/stage1/behavior/for.zig | 10 +- test/stage1/behavior/generics.zig | 4 +- test/stage1/behavior/misc.zig | 6 +- test/stage1/behavior/ptrcast.zig | 2 +- test/stage1/behavior/shuffle.zig | 14 +- test/stage1/behavior/slice.zig | 6 +- test/stage1/behavior/struct.zig | 9 +- .../struct_contains_slice_of_itself.zig | 16 +- test/stage1/behavior/type.zig | 24 +- test/stage1/behavior/union.zig | 2 +- test/stage1/behavior/vector.zig | 54 +-- test/tests.zig | 32 +- 67 files changed, 727 insertions(+), 837 deletions(-) diff --git a/build.zig b/build.zig index fc03296158e0c0b62c81962481fce2fbca1a3966..707094d36b0592551942c895ef486098e6d5a015 100644 --- a/build.zig +++ b/build.zig @@ -20,10 +20,10 @@ pub fn build(b: *Builder) !void { const rel_zig_exe = try fs.path.relative(b.allocator, b.build_root, b.zig_exe); const langref_out_path = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, "langref.html" }, + &[_][]const u8{ b.cache_root, "langref.html" }, ) catch unreachable; var docgen_cmd = docgen_exe.run(); - docgen_cmd.addArgs([_][]const u8{ + docgen_cmd.addArgs(&[_][]const u8{ rel_zig_exe, "doc" ++ fs.path.sep_str ++ "langref.html.in", langref_out_path, @@ -36,7 +36,7 @@ pub fn build(b: *Builder) !void { const test_step = b.step("test", "Run all the tests"); // find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library - const build_info = try b.exec([_][]const u8{ + const build_info = try b.exec(&[_][]const u8{ b.zig_exe, "BUILD_INFO", }); @@ -56,7 +56,7 @@ pub fn build(b: *Builder) !void { test_stage2.setBuildMode(builtin.Mode.Debug); test_stage2.addPackagePath("stage2_tests", "test/stage2/test.zig"); - const fmt_build_zig = b.addFmt([_][]const u8{"build.zig"}); + const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"}); var exe = b.addExecutable("zig", "src-self-hosted/main.zig"); exe.setBuildMode(mode); @@ -88,7 +88,7 @@ pub fn build(b: *Builder) !void { .source_dir = "lib", .install_dir = .Lib, .install_subdir = "zig", - .exclude_extensions = [_][]const u8{ "test.zig", "README.md" }, + .exclude_extensions = &[_][]const u8{ "test.zig", "README.md" }, }); const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); @@ -148,7 +148,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void { } const lib_dir = fs.path.join( b.allocator, - [_][]const u8{ dep.prefix, "lib" }, + &[_][]const u8{ dep.prefix, "lib" }, ) catch unreachable; for (dep.system_libs.toSliceConst()) |lib| { const static_bare_name = if (mem.eql(u8, lib, "curses")) @@ -157,7 +157,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void { b.fmt("lib{}.a", lib); const static_lib_name = fs.path.join( b.allocator, - [_][]const u8{ lib_dir, static_bare_name }, + &[_][]const u8{ lib_dir, static_bare_name }, ) catch unreachable; const have_static = fileExists(static_lib_name) catch unreachable; if (have_static) { @@ -183,7 +183,7 @@ fn fileExists(filename: []const u8) !bool { } fn addCppLib(b: *Builder, lib_exe_obj: var, cmake_binary_dir: []const u8, lib_name: []const u8) void { - lib_exe_obj.addObjectFile(fs.path.join(b.allocator, [_][]const u8{ + lib_exe_obj.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{ cmake_binary_dir, "zig_cpp", b.fmt("{}{}{}", lib_exe_obj.target.libPrefix(), lib_name, lib_exe_obj.target.staticLibSuffix()), @@ -199,22 +199,22 @@ const LibraryDep = struct { }; fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep { - const shared_mode = try b.exec([_][]const u8{ llvm_config_exe, "--shared-mode" }); + const shared_mode = try b.exec(&[_][]const u8{ llvm_config_exe, "--shared-mode" }); const is_static = mem.startsWith(u8, shared_mode, "static"); const libs_output = if (is_static) - try b.exec([_][]const u8{ + try b.exec(&[_][]const u8{ llvm_config_exe, "--libfiles", "--system-libs", }) else - try b.exec([_][]const u8{ + try b.exec(&[_][]const u8{ llvm_config_exe, "--libs", }); - const includes_output = try b.exec([_][]const u8{ llvm_config_exe, "--includedir" }); - const libdir_output = try b.exec([_][]const u8{ llvm_config_exe, "--libdir" }); - const prefix_output = try b.exec([_][]const u8{ llvm_config_exe, "--prefix" }); + const includes_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--includedir" }); + const libdir_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--libdir" }); + const prefix_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--prefix" }); var result = LibraryDep{ .prefix = mem.tokenize(prefix_output, " \r\n").next().?, @@ -341,7 +341,7 @@ fn addCxxKnownPath( objname: []const u8, errtxt: ?[]const u8, ) !void { - const path_padded = try b.exec([_][]const u8{ + const path_padded = try b.exec(&[_][]const u8{ ctx.cxx_compiler, b.fmt("-print-file-name={}", objname), }); diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index 26342d7833f0791fa8d2cdf0f1461f1a1f892ba6..6edc472c202cd08bb240387ea956c923dd43242f 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -35,7 +35,7 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type { /// Deinitialize with `deinit` or use `toOwnedSlice`. pub fn init(allocator: *Allocator) Self { return Self{ - .items = [_]T{}, + .items = &[_]T{}, .len = 0, .allocator = allocator, }; @@ -306,18 +306,14 @@ test "std.ArrayList.basic" { testing.expect(list.pop() == 10); testing.expect(list.len == 9); - list.appendSlice([_]i32{ - 1, - 2, - 3, - }) catch unreachable; + list.appendSlice(&[_]i32{ 1, 2, 3 }) catch unreachable; testing.expect(list.len == 12); testing.expect(list.pop() == 3); testing.expect(list.pop() == 2); testing.expect(list.pop() == 1); testing.expect(list.len == 9); - list.appendSlice([_]i32{}) catch unreachable; + list.appendSlice(&[_]i32{}) catch unreachable; testing.expect(list.len == 9); // can only set on indices < self.len @@ -464,10 +460,7 @@ test "std.ArrayList.insertSlice" { try list.append(2); try list.append(3); try list.append(4); - try list.insertSlice(1, [_]i32{ - 9, - 8, - }); + try list.insertSlice(1, &[_]i32{ 9, 8 }); testing.expect(list.items[0] == 1); testing.expect(list.items[1] == 9); testing.expect(list.items[2] == 8); diff --git a/lib/std/bloom_filter.zig b/lib/std/bloom_filter.zig index 6c4d713076d76648f56037aebec105befe9ba5fd..f12f0d86afe8aa6cefdef7fc8f58c152a5cdc7d3 100644 --- a/lib/std/bloom_filter.zig +++ b/lib/std/bloom_filter.zig @@ -62,7 +62,7 @@ pub fn BloomFilter( } pub fn getCell(self: Self, cell: Index) Cell { - return Io.get(self.data, cell, 0); + return Io.get(&self.data, cell, 0); } pub fn incrementCell(self: *Self, cell: Index) void { @@ -70,7 +70,7 @@ pub fn BloomFilter( // skip the 'get' operation Io.set(&self.data, cell, 0, cellMax); } else { - const old = Io.get(self.data, cell, 0); + const old = Io.get(&self.data, cell, 0); if (old != cellMax) { Io.set(&self.data, cell, 0, old + 1); } @@ -120,7 +120,7 @@ pub fn BloomFilter( } else if (newsize > n_items) { var copied: usize = 0; while (copied < r.data.len) : (copied += self.data.len) { - std.mem.copy(u8, r.data[copied .. copied + self.data.len], self.data); + std.mem.copy(u8, r.data[copied .. copied + self.data.len], &self.data); } } return r; diff --git a/lib/std/build.zig b/lib/std/build.zig index 9bac20df4bbd8b2fc2bf0b68d4375a576c71ddcd..fe980aaf89d666c255cd356255d62e74776d7f95 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -186,7 +186,7 @@ pub const Builder = struct { pub fn resolveInstallPrefix(self: *Builder) void { if (self.dest_dir) |dest_dir| { const install_prefix = self.install_prefix orelse "/usr"; - self.install_path = fs.path.join(self.allocator, [_][]const u8{ dest_dir, install_prefix }) catch unreachable; + self.install_path = fs.path.join(self.allocator, &[_][]const u8{ dest_dir, install_prefix }) catch unreachable; } else { const install_prefix = self.install_prefix orelse blk: { const p = self.cache_root; @@ -195,8 +195,8 @@ pub const Builder = struct { }; self.install_path = install_prefix; } - self.lib_dir = fs.path.join(self.allocator, [_][]const u8{ self.install_path, "lib" }) catch unreachable; - self.exe_dir = fs.path.join(self.allocator, [_][]const u8{ self.install_path, "bin" }) catch unreachable; + self.lib_dir = fs.path.join(self.allocator, &[_][]const u8{ self.install_path, "lib" }) catch unreachable; + self.exe_dir = fs.path.join(self.allocator, &[_][]const u8{ self.install_path, "bin" }) catch unreachable; } pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { @@ -803,7 +803,7 @@ pub const Builder = struct { } fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 { - return fs.path.resolve(self.allocator, [_][]const u8{ self.build_root, rel_path }) catch unreachable; + return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable; } pub fn fmt(self: *Builder, comptime format: []const u8, args: ...) []u8 { @@ -818,7 +818,7 @@ pub const Builder = struct { if (fs.path.isAbsolute(name)) { return name; } - const full_path = try fs.path.join(self.allocator, [_][]const u8{ search_prefix, "bin", self.fmt("{}{}", name, exe_extension) }); + const full_path = try fs.path.join(self.allocator, &[_][]const u8{ search_prefix, "bin", self.fmt("{}{}", name, exe_extension) }); return fs.realpathAlloc(self.allocator, full_path) catch continue; } } @@ -827,9 +827,9 @@ pub const Builder = struct { if (fs.path.isAbsolute(name)) { return name; } - var it = mem.tokenize(PATH, [_]u8{fs.path.delimiter}); + var it = mem.tokenize(PATH, &[_]u8{fs.path.delimiter}); while (it.next()) |path| { - const full_path = try fs.path.join(self.allocator, [_][]const u8{ path, self.fmt("{}{}", name, exe_extension) }); + const full_path = try fs.path.join(self.allocator, &[_][]const u8{ path, self.fmt("{}{}", name, exe_extension) }); return fs.realpathAlloc(self.allocator, full_path) catch continue; } } @@ -839,7 +839,7 @@ pub const Builder = struct { return name; } for (paths) |path| { - const full_path = try fs.path.join(self.allocator, [_][]const u8{ path, self.fmt("{}{}", name, exe_extension) }); + const full_path = try fs.path.join(self.allocator, &[_][]const u8{ path, self.fmt("{}{}", name, exe_extension) }); return fs.realpathAlloc(self.allocator, full_path) catch continue; } } @@ -926,12 +926,12 @@ pub const Builder = struct { }; return fs.path.resolve( self.allocator, - [_][]const u8{ base_dir, dest_rel_path }, + &[_][]const u8{ base_dir, dest_rel_path }, ) catch unreachable; } fn execPkgConfigList(self: *Builder, out_code: *u8) ![]const PkgConfigPkg { - const stdout = try self.execAllowFail([_][]const u8{ "pkg-config", "--list-all" }, out_code, .Ignore); + const stdout = try self.execAllowFail(&[_][]const u8{ "pkg-config", "--list-all" }, out_code, .Ignore); var list = ArrayList(PkgConfigPkg).init(self.allocator); var line_it = mem.tokenize(stdout, "\r\n"); while (line_it.next()) |line| { @@ -970,7 +970,7 @@ pub const Builder = struct { test "builder.findProgram compiles" { const builder = try Builder.create(std.heap.page_allocator, "zig", "zig-cache", "zig-cache"); - _ = builder.findProgram([_][]const u8{}, [_][]const u8{}) catch null; + _ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null; } /// Deprecated. Use `builtin.Version`. @@ -1384,7 +1384,7 @@ pub const LibExeObjStep = struct { }; var code: u8 = undefined; - const stdout = if (self.builder.execAllowFail([_][]const u8{ + const stdout = if (self.builder.execAllowFail(&[_][]const u8{ "pkg-config", pkg_name, "--cflags", @@ -1504,7 +1504,7 @@ pub const LibExeObjStep = struct { pub fn getOutputPath(self: *LibExeObjStep) []const u8 { return fs.path.join( self.builder.allocator, - [_][]const u8{ self.output_dir.?, self.out_filename }, + &[_][]const u8{ self.output_dir.?, self.out_filename }, ) catch unreachable; } @@ -1514,7 +1514,7 @@ pub const LibExeObjStep = struct { assert(self.kind == Kind.Lib); return fs.path.join( self.builder.allocator, - [_][]const u8{ self.output_dir.?, self.out_lib_filename }, + &[_][]const u8{ self.output_dir.?, self.out_lib_filename }, ) catch unreachable; } @@ -1525,7 +1525,7 @@ pub const LibExeObjStep = struct { assert(!self.disable_gen_h); return fs.path.join( self.builder.allocator, - [_][]const u8{ self.output_dir.?, self.out_h_filename }, + &[_][]const u8{ self.output_dir.?, self.out_h_filename }, ) catch unreachable; } @@ -1535,7 +1535,7 @@ pub const LibExeObjStep = struct { assert(self.target.isWindows() or self.target.isUefi()); return fs.path.join( self.builder.allocator, - [_][]const u8{ self.output_dir.?, self.out_pdb_filename }, + &[_][]const u8{ self.output_dir.?, self.out_pdb_filename }, ) catch unreachable; } @@ -1605,14 +1605,14 @@ pub const LibExeObjStep = struct { const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage); defer self.builder.allocator.free(triplet); - const include_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "include" }); + const include_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "include" }); errdefer allocator.free(include_path); try self.include_dirs.append(IncludeDir{ .RawPath = include_path }); - const lib_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "lib" }); + const lib_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "lib" }); try self.lib_paths.append(lib_path); - self.vcpkg_bin_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "bin" }); + self.vcpkg_bin_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "bin" }); }, } } @@ -1725,7 +1725,7 @@ pub const LibExeObjStep = struct { if (self.build_options_contents.len() > 0) { const build_options_file = try fs.path.join( builder.allocator, - [_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", self.name) }, + &[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", self.name) }, ); try std.io.writeFile(build_options_file, self.build_options_contents.toSliceConst()); try zig_args.append("--pkg-begin"); @@ -1849,7 +1849,7 @@ pub const LibExeObjStep = struct { try zig_args.append("--test-cmd"); try zig_args.append(bin_name); if (glibc_dir_arg) |dir| { - const full_dir = try fs.path.join(builder.allocator, [_][]const u8{ + const full_dir = try fs.path.join(builder.allocator, &[_][]const u8{ dir, try self.target.linuxTriple(builder.allocator), }); @@ -1994,7 +1994,7 @@ pub const LibExeObjStep = struct { const output_path = mem.trimRight(u8, output_path_nl, "\r\n"); if (self.output_dir) |output_dir| { - const full_dest = try fs.path.join(builder.allocator, [_][]const u8{ + const full_dest = try fs.path.join(builder.allocator, &[_][]const u8{ output_dir, fs.path.basename(output_path), }); @@ -2068,7 +2068,7 @@ pub const RunStep = struct { env_map.set(PATH, search_path) catch unreachable; return; }; - const new_path = self.builder.fmt("{}" ++ [1]u8{fs.path.delimiter} ++ "{}", prev_path, search_path); + const new_path = self.builder.fmt("{}" ++ &[1]u8{fs.path.delimiter} ++ "{}", prev_path, search_path); env_map.set(PATH, new_path) catch unreachable; } @@ -2162,6 +2162,9 @@ const InstallArtifactStep = struct { if (self.artifact.isDynamicLibrary()) { builder.pushInstalledFile(.Lib, artifact.major_only_filename); builder.pushInstalledFile(.Lib, artifact.name_only_filename); + if (self.artifact.target.isWindows()) { + builder.pushInstalledFile(.Lib, artifact.out_lib_filename); + } } if (self.pdb_dir) |pdb_dir| { builder.pushInstalledFile(pdb_dir, artifact.out_pdb_filename); @@ -2254,7 +2257,7 @@ pub const InstallDirStep = struct { }; const rel_path = entry.path[full_src_dir.len + 1 ..]; - const dest_path = try fs.path.join(self.builder.allocator, [_][]const u8{ dest_prefix, rel_path }); + const dest_path = try fs.path.join(self.builder.allocator, &[_][]const u8{ dest_prefix, rel_path }); switch (entry.kind) { .Directory => try fs.makePath(self.builder.allocator, dest_path), .File => try self.builder.updateFile(entry.path, dest_path), @@ -2377,7 +2380,7 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj // sym link for libfoo.so.1 to libfoo.so.1.2.3 const major_only_path = fs.path.join( allocator, - [_][]const u8{ out_dir, filename_major_only }, + &[_][]const u8{ out_dir, filename_major_only }, ) catch unreachable; fs.atomicSymLink(allocator, out_basename, major_only_path) catch |err| { warn("Unable to symlink {} -> {}\n", major_only_path, out_basename); @@ -2386,7 +2389,7 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj // sym link for libfoo.so to libfoo.so.1 const name_only_path = fs.path.join( allocator, - [_][]const u8{ out_dir, filename_name_only }, + &[_][]const u8{ out_dir, filename_name_only }, ) catch unreachable; fs.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| { warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only); @@ -2399,7 +2402,7 @@ fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 { const appdata_path = try fs.getAppDataDir(allocator, "vcpkg"); defer allocator.free(appdata_path); - const path_file = try fs.path.join(allocator, [_][]const u8{ appdata_path, "vcpkg.path.txt" }); + const path_file = try fs.path.join(allocator, &[_][]const u8{ appdata_path, "vcpkg.path.txt" }); defer allocator.free(path_file); const file = fs.File.openRead(path_file) catch return null; diff --git a/lib/std/crypto/aes.zig b/lib/std/crypto/aes.zig index ddccd0b1b326349f94bfdb7409232807a050ff63..1cc166f94301ec6f4f841c2258ed6f51f41c231a 100644 --- a/lib/std/crypto/aes.zig +++ b/lib/std/crypto/aes.zig @@ -136,7 +136,7 @@ fn AES(comptime keysize: usize) type { pub fn init(key: [keysize / 8]u8) Self { var ctx: Self = undefined; - expandKey(key, ctx.enc[0..], ctx.dec[0..]); + expandKey(&key, ctx.enc[0..], ctx.dec[0..]); return ctx; } @@ -157,7 +157,7 @@ fn AES(comptime keysize: usize) type { var ctr_i = std.mem.readIntSliceBig(u128, ctrbuf[0..]); std.mem.writeIntSliceBig(u128, ctrbuf[0..], ctr_i +% 1); - n += xorBytes(dst[n..], src[n..], keystream); + n += xorBytes(dst[n..], src[n..], &keystream); } } }; diff --git a/lib/std/crypto/blake2.zig b/lib/std/crypto/blake2.zig index d6b1e497245f3bd57ef6f14b85cf03a25acd4e1a..aa866acbe4b7d37486de1f5be78dab0f1072d9e9 100644 --- a/lib/std/crypto/blake2.zig +++ b/lib/std/crypto/blake2.zig @@ -256,7 +256,7 @@ test "blake2s256 aligned final" { var out: [Blake2s256.digest_length]u8 = undefined; var h = Blake2s256.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } @@ -490,6 +490,6 @@ test "blake2b512 aligned final" { var out: [Blake2b512.digest_length]u8 = undefined; var h = Blake2b512.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/chacha20.zig b/lib/std/crypto/chacha20.zig index d5d03f2bfa214e9d39414ac34a49978452dd19c5..10d21306594d259d2937d360f2e6066bb3523c4d 100644 --- a/lib/std/crypto/chacha20.zig +++ b/lib/std/crypto/chacha20.zig @@ -218,12 +218,12 @@ test "crypto.chacha20 test vector sunscreen" { }; chaCha20IETF(result[0..], input[0..], 1, key, nonce); - testing.expectEqualSlices(u8, expected_result, result); + testing.expectEqualSlices(u8, &expected_result, &result); // Chacha20 is self-reversing. var plaintext: [114]u8 = undefined; chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce); - testing.expect(mem.compare(u8, input, plaintext) == mem.Compare.Equal); + testing.expect(mem.compare(u8, input, &plaintext) == mem.Compare.Equal); } // https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7 @@ -258,7 +258,7 @@ test "crypto.chacha20 test vector 1" { const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }; chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); - testing.expectEqualSlices(u8, expected_result, result); + testing.expectEqualSlices(u8, &expected_result, &result); } test "crypto.chacha20 test vector 2" { @@ -292,7 +292,7 @@ test "crypto.chacha20 test vector 2" { const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }; chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); - testing.expectEqualSlices(u8, expected_result, result); + testing.expectEqualSlices(u8, &expected_result, &result); } test "crypto.chacha20 test vector 3" { @@ -326,7 +326,7 @@ test "crypto.chacha20 test vector 3" { const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 1 }; chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); - testing.expectEqualSlices(u8, expected_result, result); + testing.expectEqualSlices(u8, &expected_result, &result); } test "crypto.chacha20 test vector 4" { @@ -360,7 +360,7 @@ test "crypto.chacha20 test vector 4" { const nonce = [_]u8{ 1, 0, 0, 0, 0, 0, 0, 0 }; chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); - testing.expectEqualSlices(u8, expected_result, result); + testing.expectEqualSlices(u8, &expected_result, &result); } test "crypto.chacha20 test vector 5" { @@ -432,5 +432,5 @@ test "crypto.chacha20 test vector 5" { }; chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); - testing.expectEqualSlices(u8, expected_result, result); + testing.expectEqualSlices(u8, &expected_result, &result); } diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig index 0d18afd705ca9f2f2aafb1f791f35ae2d1615043..1d835b231b31d28eb4cb1cb4b555bc7ad77fb294 100644 --- a/lib/std/crypto/gimli.zig +++ b/lib/std/crypto/gimli.zig @@ -83,7 +83,7 @@ test "permute" { while (i < 12) : (i += 1) { input[i] = i * i * i + i *% 0x9e3779b9; } - testing.expectEqualSlices(u32, input, [_]u32{ + testing.expectEqualSlices(u32, &input, &[_]u32{ 0x00000000, 0x9e3779ba, 0x3c6ef37a, 0xdaa66d46, 0x78dde724, 0x1715611a, 0xb54cdb2e, 0x53845566, 0xf1bbcfc8, 0x8ff34a5a, 0x2e2ac522, 0xcc624026, @@ -92,7 +92,7 @@ test "permute" { }, }; state.permute(); - testing.expectEqualSlices(u32, state.data, [_]u32{ + testing.expectEqualSlices(u32, &state.data, &[_]u32{ 0xba11c85a, 0x91bad119, 0x380ce880, 0xd24c2c68, 0x3eceffea, 0x277a921c, 0x4f73a0bd, 0xda5a9cd8, 0x84b673f0, 0x34e52ff7, 0x9e2bef49, 0xf41bb8d6, @@ -163,6 +163,6 @@ test "hash" { var msg: [58 / 2]u8 = undefined; try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C"); var md: [32]u8 = undefined; - hash(&md, msg); - htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", md); + hash(&md, &msg); + htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md); } diff --git a/lib/std/crypto/md5.zig b/lib/std/crypto/md5.zig index db6150699d7e61759397c3e53dba02661589c41f..41ce802dd7b116f71b87732cb4a9976990257ea2 100644 --- a/lib/std/crypto/md5.zig +++ b/lib/std/crypto/md5.zig @@ -276,6 +276,6 @@ test "md5 aligned final" { var out: [Md5.digest_length]u8 = undefined; var h = Md5.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig index 78881ba049b53170b3c01841fe76176d658b613e..2395b1c7aac9d8c68109552804eabb2fc2d7819c 100644 --- a/lib/std/crypto/poly1305.zig +++ b/lib/std/crypto/poly1305.zig @@ -230,5 +230,5 @@ test "poly1305 rfc7439 vector1" { var mac: [16]u8 = undefined; Poly1305.create(mac[0..], msg, key); - std.testing.expectEqualSlices(u8, expected_mac, mac); + std.testing.expectEqualSlices(u8, expected_mac, &mac); } diff --git a/lib/std/crypto/sha1.zig b/lib/std/crypto/sha1.zig index c17ef2daf775e5085ac503927a9961e798e6be09..b4d6e5c0cc70563f2dd8f2802e698b1d3123c32d 100644 --- a/lib/std/crypto/sha1.zig +++ b/lib/std/crypto/sha1.zig @@ -297,6 +297,6 @@ test "sha1 aligned final" { var out: [Sha1.digest_length]u8 = undefined; var h = Sha1.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/sha2.zig b/lib/std/crypto/sha2.zig index 77698176bd117b1af7cf5b73ee1e0fdf1258e409..478cadd03c0e8765d3b5b641d441e59667a4e664 100644 --- a/lib/std/crypto/sha2.zig +++ b/lib/std/crypto/sha2.zig @@ -343,7 +343,7 @@ test "sha256 aligned final" { var out: [Sha256.digest_length]u8 = undefined; var h = Sha256.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } @@ -723,6 +723,6 @@ test "sha512 aligned final" { var out: [Sha512.digest_length]u8 = undefined; var h = Sha512.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index d417ef07e25131ffa5868b762b7497cd04a11c04..d7b2fbe2566dd3c3fa42b4aa8c872c41a3bf9465 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -229,7 +229,7 @@ test "sha3-256 aligned final" { var out: [Sha3_256.digest_length]u8 = undefined; var h = Sha3_256.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } @@ -300,6 +300,6 @@ test "sha3-512 aligned final" { var out: [Sha3_512.digest_length]u8 = undefined; var h = Sha3_512.init(); - h.update(block); + h.update(&block); h.final(out[0..]); } diff --git a/lib/std/crypto/test.zig b/lib/std/crypto/test.zig index a0ddad6c83136bb9890b0f6d6df09ef95d134a1c..1ff326cf39784e06023594244754a3e3f99cb236 100644 --- a/lib/std/crypto/test.zig +++ b/lib/std/crypto/test.zig @@ -8,7 +8,7 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu var h: [expected.len / 2]u8 = undefined; Hasher.hash(input, h[0..]); - assertEqual(expected, h); + assertEqual(expected, &h); } // Assert `expected` == `input` where `input` is a bytestring. @@ -18,5 +18,5 @@ pub fn assertEqual(comptime expected: []const u8, input: []const u8) void { r.* = fmt.parseInt(u8, expected[2 * i .. 2 * i + 2], 16) catch unreachable; } - testing.expectEqualSlices(u8, expected_bytes, input); + testing.expectEqualSlices(u8, &expected_bytes, input); } diff --git a/lib/std/crypto/x25519.zig b/lib/std/crypto/x25519.zig index 73e0f033f2e04a39706b7c26aceea14471bd885e..16e3f073f846415aabbf2640f5203bfc0f674e4c 100644 --- a/lib/std/crypto/x25519.zig +++ b/lib/std/crypto/x25519.zig @@ -63,7 +63,7 @@ pub const X25519 = struct { var pos: isize = 254; while (pos >= 0) : (pos -= 1) { // constant time conditional swap before ladder step - const b = scalarBit(e, @intCast(usize, pos)); + const b = scalarBit(&e, @intCast(usize, pos)); swap ^= b; // xor trick avoids swapping at the end of the loop Fe.cswap(x2, x3, swap); Fe.cswap(z2, z3, swap); @@ -117,7 +117,7 @@ pub const X25519 = struct { pub fn createPublicKey(public_key: []u8, private_key: []const u8) bool { var base_point = [_]u8{9} ++ [_]u8{0} ** 31; - return create(public_key, private_key, base_point); + return create(public_key, private_key, &base_point); } }; @@ -581,8 +581,8 @@ test "x25519 public key calculation from secret key" { var pk_calculated: [32]u8 = undefined; try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166"); try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50"); - std.testing.expect(X25519.createPublicKey(pk_calculated[0..], sk)); - std.testing.expect(std.mem.eql(u8, pk_calculated, pk_expected)); + std.testing.expect(X25519.createPublicKey(pk_calculated[0..], &sk)); + std.testing.expect(std.mem.eql(u8, &pk_calculated, &pk_expected)); } test "x25519 rfc7748 vector1" { @@ -594,7 +594,7 @@ test "x25519 rfc7748 vector1" { var output: [32]u8 = undefined; std.testing.expect(X25519.create(output[0..], secret_key, public_key)); - std.testing.expect(std.mem.eql(u8, output, expected_output)); + std.testing.expect(std.mem.eql(u8, &output, expected_output)); } test "x25519 rfc7748 vector2" { @@ -606,12 +606,12 @@ test "x25519 rfc7748 vector2" { var output: [32]u8 = undefined; std.testing.expect(X25519.create(output[0..], secret_key, public_key)); - std.testing.expect(std.mem.eql(u8, output, expected_output)); + std.testing.expect(std.mem.eql(u8, &output, expected_output)); } test "x25519 rfc7748 one iteration" { const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; - const expected_output = "\x42\x2c\x8e\x7a\x62\x27\xd7\xbc\xa1\x35\x0b\x3e\x2b\xb7\x27\x9f\x78\x97\xb8\x7b\xb6\x85\x4b\x78\x3c\x60\xe8\x03\x11\xae\x30\x79".*; + const expected_output = "\x42\x2c\x8e\x7a\x62\x27\xd7\xbc\xa1\x35\x0b\x3e\x2b\xb7\x27\x9f\x78\x97\xb8\x7b\xb6\x85\x4b\x78\x3c\x60\xe8\x03\x11\xae\x30\x79"; var k: [32]u8 = initial_value; var u: [32]u8 = initial_value; @@ -619,7 +619,7 @@ test "x25519 rfc7748 one iteration" { var i: usize = 0; while (i < 1) : (i += 1) { var output: [32]u8 = undefined; - std.testing.expect(X25519.create(output[0..], k, u)); + std.testing.expect(X25519.create(output[0..], &k, &u)); std.mem.copy(u8, u[0..], k[0..]); std.mem.copy(u8, k[0..], output[0..]); @@ -634,16 +634,16 @@ test "x25519 rfc7748 1,000 iterations" { return error.SkipZigTest; } - const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; - const expected_output = "\x68\x4c\xf5\x9b\xa8\x33\x09\x55\x28\x00\xef\x56\x6f\x2f\x4d\x3c\x1c\x38\x87\xc4\x93\x60\xe3\x87\x5f\x2e\xb9\x4d\x99\x53\x2c\x51".*; + const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + const expected_output = "\x68\x4c\xf5\x9b\xa8\x33\x09\x55\x28\x00\xef\x56\x6f\x2f\x4d\x3c\x1c\x38\x87\xc4\x93\x60\xe3\x87\x5f\x2e\xb9\x4d\x99\x53\x2c\x51"; - var k: [32]u8 = initial_value; - var u: [32]u8 = initial_value; + var k: [32]u8 = initial_value.*; + var u: [32]u8 = initial_value.*; var i: usize = 0; while (i < 1000) : (i += 1) { var output: [32]u8 = undefined; - std.testing.expect(X25519.create(output[0..], k, u)); + std.testing.expect(X25519.create(output[0..], &k, &u)); std.mem.copy(u8, u[0..], k[0..]); std.mem.copy(u8, k[0..], output[0..]); @@ -657,16 +657,16 @@ test "x25519 rfc7748 1,000,000 iterations" { return error.SkipZigTest; } - const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; - const expected_output = "\x7c\x39\x11\xe0\xab\x25\x86\xfd\x86\x44\x97\x29\x7e\x57\x5e\x6f\x3b\xc6\x01\xc0\x88\x3c\x30\xdf\x5f\x4d\xd2\xd2\x4f\x66\x54\x24".*; + const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + const expected_output = "\x7c\x39\x11\xe0\xab\x25\x86\xfd\x86\x44\x97\x29\x7e\x57\x5e\x6f\x3b\xc6\x01\xc0\x88\x3c\x30\xdf\x5f\x4d\xd2\xd2\x4f\x66\x54\x24"; - var k: [32]u8 = initial_value; - var u: [32]u8 = initial_value; + var k: [32]u8 = initial_value.*; + var u: [32]u8 = initial_value.*; var i: usize = 0; while (i < 1000000) : (i += 1) { var output: [32]u8 = undefined; - std.testing.expect(X25519.create(output[0..], k, u)); + std.testing.expect(X25519.create(output[0..], &k, &u)); std.mem.copy(u8, u[0..], k[0..]); std.mem.copy(u8, k[0..], output[0..]); diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 6324c88d86411707e98d16bfd1151dd23209c31d..a6a3e148d4f88c9f97b0d5f1c78adfc5e394d40c 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1916,7 +1916,7 @@ const LineNumberProgram = struct { return error.InvalidDebugInfo; } else self.include_dirs[file_entry.dir_index]; - const file_name = try fs.path.join(self.file_entries.allocator, [_][]const u8{ dir_name, file_entry.file_name }); + const file_name = try fs.path.join(self.file_entries.allocator, &[_][]const u8{ dir_name, file_entry.file_name }); errdefer self.file_entries.allocator.free(file_name); return LineInfo{ .line = if (self.prev_line >= 0) @intCast(u64, self.prev_line) else 0, diff --git a/lib/std/elf.zig b/lib/std/elf.zig index c6a4c0cc0b93bc22928e66c50fd3a862b99b40c0..dc1638c5cb304bdc796e7742a924c6c0b3312224 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -381,7 +381,7 @@ pub const Elf = struct { var magic: [4]u8 = undefined; try in.readNoEof(magic[0..]); - if (!mem.eql(u8, magic, "\x7fELF")) return error.InvalidFormat; + if (!mem.eql(u8, &magic, "\x7fELF")) return error.InvalidFormat; elf.is_64 = switch (try in.readByte()) { 1 => false, diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index f47663a51122a4af9a711bf2e415026c0ad726ce..03478f65d57c376ee04405d6d42858baab7047d8 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -237,7 +237,7 @@ pub const Loop = struct { var extra_thread_index: usize = 0; errdefer { // writing 8 bytes to an eventfd cannot fail - os.write(self.os_data.final_eventfd, wakeup_bytes) catch unreachable; + os.write(self.os_data.final_eventfd, &wakeup_bytes) catch unreachable; while (extra_thread_index != 0) { extra_thread_index -= 1; self.extra_threads[extra_thread_index].wait(); @@ -684,7 +684,7 @@ pub const Loop = struct { .linux => { self.posixFsRequest(&self.os_data.fs_end_request); // writing 8 bytes to an eventfd cannot fail - noasync os.write(self.os_data.final_eventfd, wakeup_bytes) catch unreachable; + noasync os.write(self.os_data.final_eventfd, &wakeup_bytes) catch unreachable; return; }, .macosx, .freebsd, .netbsd, .dragonfly => { diff --git a/lib/std/fifo.zig b/lib/std/fifo.zig index e078abcb2b86bd65bf992b70e6ba818d24cd4567..fdd746dfccc1dfe7d6a409a796d69c3346998b0f 100644 --- a/lib/std/fifo.zig +++ b/lib/std/fifo.zig @@ -70,7 +70,7 @@ pub fn LinearFifo( pub fn init(allocator: *Allocator) Self { return .{ .allocator = allocator, - .buf = [_]T{}, + .buf = &[_]T{}, .head = 0, .count = 0, }; @@ -143,7 +143,7 @@ pub fn LinearFifo( /// Returns a writable slice from the 'read' end of the fifo fn readableSliceMut(self: SliceSelfArg, offset: usize) []T { - if (offset > self.count) return [_]T{}; + if (offset > self.count) return &[_]T{}; var start = self.head + offset; if (start >= self.buf.len) { @@ -223,7 +223,7 @@ pub fn LinearFifo( /// Returns the first section of writable buffer /// Note that this may be of length 0 pub fn writableSlice(self: SliceSelfArg, offset: usize) []T { - if (offset > self.buf.len) return [_]T{}; + if (offset > self.buf.len) return &[_]T{}; const tail = self.head + offset + self.count; if (tail < self.buf.len) { @@ -357,7 +357,7 @@ test "LinearFifo(u8, .Dynamic)" { { var i: usize = 0; while (i < 5) : (i += 1) { - try fifo.write([_]u8{try fifo.peekItem(i)}); + try fifo.write(&[_]u8{try fifo.peekItem(i)}); } testing.expectEqual(@as(usize, 10), fifo.readableLength()); testing.expectEqualSlices(u8, "HELLOHELLO", fifo.readableSlice(0)); @@ -426,7 +426,7 @@ test "LinearFifo" { }; defer fifo.deinit(); - try fifo.write([_]T{ 0, 1, 1, 0, 1 }); + try fifo.write(&[_]T{ 0, 1, 1, 0, 1 }); testing.expectEqual(@as(usize, 5), fifo.readableLength()); { diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index cbb11cba36617e89f6d8a3679612825c9f3a6fb5..4a28daf4b7b46df41ecfec2a7ae996f43e9176cd 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -451,13 +451,18 @@ pub fn formatType( }, }, .Array => |info| { - if (info.child == u8) { - return formatText(value, fmt, options, context, Errors, output); - } - if (value.len == 0) { - return format(context, Errors, output, "[0]{}", @typeName(T.Child)); - } - return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value)); + const Slice = @Type(builtin.TypeInfo{ + .Pointer = .{ + .size = .Slice, + .is_const = true, + .is_volatile = false, + .is_allowzero = false, + .alignment = @alignOf(info.child), + .child = info.child, + .sentinel = null, + }, + }); + return formatType(@as(Slice, &value), fmt, options, context, Errors, output, max_depth); }, .Fn => { return format(context, Errors, output, "{}@{x}", @typeName(T), @ptrToInt(value)); @@ -872,8 +877,8 @@ pub fn formatBytes( } const buf = switch (radix) { - 1000 => [_]u8{ suffix, 'B' }, - 1024 => [_]u8{ suffix, 'i', 'B' }, + 1000 => &[_]u8{ suffix, 'B' }, + 1024 => &[_]u8{ suffix, 'i', 'B' }, else => unreachable, }; return output(context, buf); @@ -969,7 +974,7 @@ fn formatIntUnsigned( if (leftover_padding == 0) break; } mem.set(u8, buf[0..index], options.fill); - return output(context, buf); + return output(context, &buf); } else { const padded_buf = buf[index - padding ..]; mem.set(u8, padded_buf[0..padding], options.fill); diff --git a/lib/std/fs.zig b/lib/std/fs.zig index f580cf20458582ab0d735a0ec37eaf088bf7cba3..7116d2fd9e31c00520cf33a2fb2a6b16695576a0 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -60,7 +60,7 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: tmp_path[dirname.len] = path.sep; while (true) { try crypto.randomBytes(rand_buf[0..]); - b64_fs_encoder.encode(tmp_path[dirname.len + 1 ..], rand_buf); + b64_fs_encoder.encode(tmp_path[dirname.len + 1 ..], &rand_buf); if (symLink(existing_path, tmp_path)) { return rename(tmp_path, new_path); @@ -226,7 +226,7 @@ pub const AtomicFile = struct { while (true) { try crypto.randomBytes(rand_buf[0..]); - b64_fs_encoder.encode(tmp_path_buf[dirname_component_len..tmp_path_len], rand_buf); + b64_fs_encoder.encode(tmp_path_buf[dirname_component_len..tmp_path_len], &rand_buf); const file = File.openWriteNoClobberC(@ptrCast([*:0]u8, &tmp_path_buf), mode) catch |err| switch (err) { error.PathAlreadyExists => continue, @@ -290,7 +290,7 @@ pub fn makeDirW(dir_path: [*:0]const u16) !void { /// have been modified regardless. /// TODO determine if we can remove the allocator requirement from this function pub fn makePath(allocator: *Allocator, full_path: []const u8) !void { - const resolved_path = try path.resolve(allocator, [_][]const u8{full_path}); + const resolved_path = try path.resolve(allocator, &[_][]const u8{full_path}); defer allocator.free(resolved_path); var end_index: usize = resolved_path.len; diff --git a/lib/std/fs/get_app_data_dir.zig b/lib/std/fs/get_app_data_dir.zig index 657971dd9014860f5b3165309d4cb9153e876827..bbc9c4b7bb1c9a053345dfdbcc4a6c03b367daab 100644 --- a/lib/std/fs/get_app_data_dir.zig +++ b/lib/std/fs/get_app_data_dir.zig @@ -31,7 +31,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD error.OutOfMemory => return error.OutOfMemory, }; defer allocator.free(global_dir); - return fs.path.join(allocator, [_][]const u8{ global_dir, appname }); + return fs.path.join(allocator, &[_][]const u8{ global_dir, appname }); }, os.windows.E_OUTOFMEMORY => return error.OutOfMemory, else => return error.AppDataDirUnavailable, @@ -42,14 +42,14 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD // TODO look in /etc/passwd return error.AppDataDirUnavailable; }; - return fs.path.join(allocator, [_][]const u8{ home_dir, "Library", "Application Support", appname }); + return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname }); }, .linux, .freebsd, .netbsd, .dragonfly => { const home_dir = os.getenv("HOME") orelse { // TODO look in /etc/passwd return error.AppDataDirUnavailable; }; - return fs.path.join(allocator, [_][]const u8{ home_dir, ".local", "share", appname }); + return fs.path.join(allocator, &[_][]const u8{ home_dir, ".local", "share", appname }); }, else => @compileError("Unsupported OS"), } diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index e2f1b5ac6531e3b8bee01c20b9817514c24aec31..c7ebb470c5fc005b35d87c6c212abb38808ac5ac 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -15,7 +15,9 @@ pub const sep_windows = '\\'; pub const sep_posix = '/'; pub const sep = if (builtin.os == .windows) sep_windows else sep_posix; -pub const sep_str = [1]u8{sep}; +pub const sep_str_windows = "\\"; +pub const sep_str_posix = "/"; +pub const sep_str = if (builtin.os == .windows) sep_str_windows else sep_str_posix; pub const delimiter_windows = ';'; pub const delimiter_posix = ':'; @@ -101,31 +103,31 @@ fn testJoinPosix(paths: []const []const u8, expected: []const u8) void { } test "join" { - testJoinWindows([_][]const u8{ "c:\\a\\b", "c" }, "c:\\a\\b\\c"); - testJoinWindows([_][]const u8{ "c:\\a\\b", "c" }, "c:\\a\\b\\c"); - testJoinWindows([_][]const u8{ "c:\\a\\b\\", "c" }, "c:\\a\\b\\c"); + testJoinWindows(&[_][]const u8{ "c:\\a\\b", "c" }, "c:\\a\\b\\c"); + testJoinWindows(&[_][]const u8{ "c:\\a\\b", "c" }, "c:\\a\\b\\c"); + testJoinWindows(&[_][]const u8{ "c:\\a\\b\\", "c" }, "c:\\a\\b\\c"); - testJoinWindows([_][]const u8{ "c:\\", "a", "b\\", "c" }, "c:\\a\\b\\c"); - testJoinWindows([_][]const u8{ "c:\\a\\", "b\\", "c" }, "c:\\a\\b\\c"); + testJoinWindows(&[_][]const u8{ "c:\\", "a", "b\\", "c" }, "c:\\a\\b\\c"); + testJoinWindows(&[_][]const u8{ "c:\\a\\", "b\\", "c" }, "c:\\a\\b\\c"); testJoinWindows( - [_][]const u8{ "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std", "io.zig" }, + &[_][]const u8{ "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std", "io.zig" }, "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std\\io.zig", ); - testJoinPosix([_][]const u8{ "/a/b", "c" }, "/a/b/c"); - testJoinPosix([_][]const u8{ "/a/b/", "c" }, "/a/b/c"); + testJoinPosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c"); + testJoinPosix(&[_][]const u8{ "/a/b/", "c" }, "/a/b/c"); - testJoinPosix([_][]const u8{ "/", "a", "b/", "c" }, "/a/b/c"); - testJoinPosix([_][]const u8{ "/a/", "b/", "c" }, "/a/b/c"); + testJoinPosix(&[_][]const u8{ "/", "a", "b/", "c" }, "/a/b/c"); + testJoinPosix(&[_][]const u8{ "/a/", "b/", "c" }, "/a/b/c"); testJoinPosix( - [_][]const u8{ "/home/andy/dev/zig/build/lib/zig/std", "io.zig" }, + &[_][]const u8{ "/home/andy/dev/zig/build/lib/zig/std", "io.zig" }, "/home/andy/dev/zig/build/lib/zig/std/io.zig", ); - testJoinPosix([_][]const u8{ "a", "/c" }, "a/c"); - testJoinPosix([_][]const u8{ "a/", "/c" }, "a/c"); + testJoinPosix(&[_][]const u8{ "a", "/c" }, "a/c"); + testJoinPosix(&[_][]const u8{ "a/", "/c" }, "a/c"); } pub fn isAbsolute(path: []const u8) bool { @@ -246,7 +248,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath { } const relative_path = WindowsPath{ .kind = WindowsPath.Kind.None, - .disk_designator = [_]u8{}, + .disk_designator = &[_]u8{}, .is_abs = false, }; if (path.len < "//a/b".len) { @@ -255,12 +257,12 @@ pub fn windowsParsePath(path: []const u8) WindowsPath { inline for ("/\\") |this_sep| { const two_sep = [_]u8{ this_sep, this_sep }; - if (mem.startsWith(u8, path, two_sep)) { + if (mem.startsWith(u8, path, &two_sep)) { if (path[2] == this_sep) { return relative_path; } - var it = mem.tokenize(path, [_]u8{this_sep}); + var it = mem.tokenize(path, &[_]u8{this_sep}); _ = (it.next() orelse return relative_path); _ = (it.next() orelse return relative_path); return WindowsPath{ @@ -322,8 +324,8 @@ fn networkShareServersEql(ns1: []const u8, ns2: []const u8) bool { const sep1 = ns1[0]; const sep2 = ns2[0]; - var it1 = mem.tokenize(ns1, [_]u8{sep1}); - var it2 = mem.tokenize(ns2, [_]u8{sep2}); + var it1 = mem.tokenize(ns1, &[_]u8{sep1}); + var it2 = mem.tokenize(ns2, &[_]u8{sep2}); // TODO ASCII is wrong, we actually need full unicode support to compare paths. return asciiEqlIgnoreCase(it1.next().?, it2.next().?); @@ -343,8 +345,8 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8 const sep1 = p1[0]; const sep2 = p2[0]; - var it1 = mem.tokenize(p1, [_]u8{sep1}); - var it2 = mem.tokenize(p2, [_]u8{sep2}); + var it1 = mem.tokenize(p1, &[_]u8{sep1}); + var it2 = mem.tokenize(p2, &[_]u8{sep2}); // TODO ASCII is wrong, we actually need full unicode support to compare paths. return asciiEqlIgnoreCase(it1.next().?, it2.next().?) and asciiEqlIgnoreCase(it1.next().?, it2.next().?); @@ -637,10 +639,10 @@ test "resolve" { if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) { cwd[0] = asciiUpper(cwd[0]); } - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{"."}), cwd)); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{"."}), cwd)); } else { - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "a/b/c/", "../../.." }), cwd)); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{"."}), cwd)); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "a/b/c/", "../../.." }), cwd)); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{"."}), cwd)); } } @@ -653,8 +655,8 @@ test "resolveWindows" { const cwd = try process.getCwdAlloc(debug.global_allocator); const parsed_cwd = windowsParsePath(cwd); { - const result = testResolveWindows([_][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" }); - const expected = try join(debug.global_allocator, [_][]const u8{ + const result = testResolveWindows(&[_][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" }); + const expected = try join(debug.global_allocator, &[_][]const u8{ parsed_cwd.disk_designator, "usr\\local\\lib\\zig\\std\\array_list.zig", }); @@ -664,8 +666,8 @@ test "resolveWindows" { testing.expect(mem.eql(u8, result, expected)); } { - const result = testResolveWindows([_][]const u8{ "usr/local", "lib\\zig" }); - const expected = try join(debug.global_allocator, [_][]const u8{ + const result = testResolveWindows(&[_][]const u8{ "usr/local", "lib\\zig" }); + const expected = try join(debug.global_allocator, &[_][]const u8{ cwd, "usr\\local\\lib\\zig", }); @@ -676,32 +678,32 @@ test "resolveWindows" { } } - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }), "C:\\hi\\ok")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }), "C:\\blah\\a")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }), "C:\\blah\\a")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }), "D:\\e.exe")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/ignore", "c:/some/file" }), "C:\\some\\file")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "d:/ignore", "d:some/dir//" }), "D:\\ignore\\some\\dir")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "//server/share", "..", "relative\\" }), "\\\\server\\share\\relative")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/", "//" }), "C:\\")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/", "//dir" }), "C:\\dir")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/", "//server/share" }), "\\\\server\\share\\")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/", "//server//share" }), "\\\\server\\share\\")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "c:/", "///some//dir" }), "C:\\some\\dir")); - testing.expect(mem.eql(u8, testResolveWindows([_][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }), "C:\\foo\\tmp.3\\cycles\\root.js")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }), "C:\\hi\\ok")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }), "C:\\blah\\a")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }), "C:\\blah\\a")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }), "D:\\e.exe")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/ignore", "c:/some/file" }), "C:\\some\\file")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "d:/ignore", "d:some/dir//" }), "D:\\ignore\\some\\dir")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "//server/share", "..", "relative\\" }), "\\\\server\\share\\relative")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//" }), "C:\\")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//dir" }), "C:\\dir")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//server/share" }), "\\\\server\\share\\")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "//server//share" }), "\\\\server\\share\\")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "c:/", "///some//dir" }), "C:\\some\\dir")); + testing.expect(mem.eql(u8, testResolveWindows(&[_][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }), "C:\\foo\\tmp.3\\cycles\\root.js")); } test "resolvePosix" { - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/a/b", "c" }), "/a/b/c")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/a/b", "c", "//d", "e///" }), "/d/e")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/a/b/c", "..", "../" }), "/a")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/", "..", ".." }), "/")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{"/a/b/c/"}), "/a/b/c")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b", "c" }), "/a/b/c")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b", "c", "//d", "e///" }), "/d/e")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/a/b/c", "..", "../" }), "/a")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/", "..", ".." }), "/")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{"/a/b/c/"}), "/a/b/c")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/var/lib", "../", "file/" }), "/var/file")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/var/lib", "/../", "file/" }), "/file")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/some/dir", ".", "/absolute/" }), "/absolute")); - testing.expect(mem.eql(u8, testResolvePosix([_][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }), "/foo/tmp.3/cycles/root.js")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/var/lib", "../", "file/" }), "/var/file")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/var/lib", "/../", "file/" }), "/file")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/some/dir", ".", "/absolute/" }), "/absolute")); + testing.expect(mem.eql(u8, testResolvePosix(&[_][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }), "/foo/tmp.3/cycles/root.js")); } fn testResolveWindows(paths: []const []const u8) []u8 { @@ -856,12 +858,12 @@ pub fn basename(path: []const u8) []const u8 { pub fn basenamePosix(path: []const u8) []const u8 { if (path.len == 0) - return [_]u8{}; + return &[_]u8{}; var end_index: usize = path.len - 1; while (path[end_index] == '/') { if (end_index == 0) - return [_]u8{}; + return &[_]u8{}; end_index -= 1; } var start_index: usize = end_index; @@ -877,19 +879,19 @@ pub fn basenamePosix(path: []const u8) []const u8 { pub fn basenameWindows(path: []const u8) []const u8 { if (path.len == 0) - return [_]u8{}; + return &[_]u8{}; var end_index: usize = path.len - 1; while (true) { const byte = path[end_index]; if (byte == '/' or byte == '\\') { if (end_index == 0) - return [_]u8{}; + return &[_]u8{}; end_index -= 1; continue; } if (byte == ':' and end_index == 1) { - return [_]u8{}; + return &[_]u8{}; } break; } @@ -971,11 +973,11 @@ pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 { } pub fn relativeWindows(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 { - const resolved_from = try resolveWindows(allocator, [_][]const u8{from}); + const resolved_from = try resolveWindows(allocator, &[_][]const u8{from}); defer allocator.free(resolved_from); var clean_up_resolved_to = true; - const resolved_to = try resolveWindows(allocator, [_][]const u8{to}); + const resolved_to = try resolveWindows(allocator, &[_][]const u8{to}); defer if (clean_up_resolved_to) allocator.free(resolved_to); const parsed_from = windowsParsePath(resolved_from); @@ -1044,10 +1046,10 @@ pub fn relativeWindows(allocator: *Allocator, from: []const u8, to: []const u8) } pub fn relativePosix(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 { - const resolved_from = try resolvePosix(allocator, [_][]const u8{from}); + const resolved_from = try resolvePosix(allocator, &[_][]const u8{from}); defer allocator.free(resolved_from); - const resolved_to = try resolvePosix(allocator, [_][]const u8{to}); + const resolved_to = try resolvePosix(allocator, &[_][]const u8{to}); defer allocator.free(resolved_to); var from_it = mem.tokenize(resolved_from, "/"); diff --git a/lib/std/hash/cityhash.zig b/lib/std/hash/cityhash.zig index d31ee17105ed26acfb2c91e8c74c7874528e7a2f..5038c3758eab4e90c06c26a65e606dbf14e3b477 100644 --- a/lib/std/hash/cityhash.zig +++ b/lib/std/hash/cityhash.zig @@ -367,7 +367,7 @@ fn SMHasherTest(comptime hash_fn: var, comptime hashbits: u32) u32 { @memcpy(@ptrCast([*]u8, &hashes[i * hashbytes]), @ptrCast([*]u8, &h), hashbytes); } - return @truncate(u32, hash_fn(hashes, 0)); + return @truncate(u32, hash_fn(&hashes, 0)); } fn CityHash32hashIgnoreSeed(str: []const u8, seed: u32) u32 { diff --git a/lib/std/hash/murmur.zig b/lib/std/hash/murmur.zig index f70190d31197bcb54b2cdf5da815299a2382005d..d3379a81f70a1c6dc22e505725251635453a90a9 100644 --- a/lib/std/hash/murmur.zig +++ b/lib/std/hash/murmur.zig @@ -299,7 +299,7 @@ fn SMHasherTest(comptime hash_fn: var, comptime hashbits: u32) u32 { @memcpy(@ptrCast([*]u8, &hashes[i * hashbytes]), @ptrCast([*]u8, &h), hashbytes); } - return @truncate(u32, hash_fn(hashes, 0)); + return @truncate(u32, hash_fn(&hashes, 0)); } test "murmur2_32" { diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index 8b61531cf232cebaab08a6a72f9b410a4b6f768b..f08ec4b59ee2465c2d8645e788575fc010297751 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -94,7 +94,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 pub fn init(allocator: *Allocator) Self { return Self{ - .entries = [_]Entry{}, + .entries = &[_]Entry{}, .allocator = allocator, .size = 0, .max_distance_from_start_index = 0, diff --git a/lib/std/http/headers.zig b/lib/std/http/headers.zig index a860186e474161a15df42cc8642b4d13f87c6dbb..1d573aebc03dceae2e62a80f3f4a043b914408f5 100644 --- a/lib/std/http/headers.zig +++ b/lib/std/http/headers.zig @@ -514,8 +514,8 @@ test "Headers.getIndices" { try h.append("set-cookie", "y=2", null); testing.expect(null == h.getIndices("not-present")); - testing.expectEqualSlices(usize, [_]usize{0}, h.getIndices("foo").?.toSliceConst()); - testing.expectEqualSlices(usize, [_]usize{ 1, 2 }, h.getIndices("set-cookie").?.toSliceConst()); + testing.expectEqualSlices(usize, &[_]usize{0}, h.getIndices("foo").?.toSliceConst()); + testing.expectEqualSlices(usize, &[_]usize{ 1, 2 }, h.getIndices("set-cookie").?.toSliceConst()); } test "Headers.get" { diff --git a/lib/std/io.zig b/lib/std/io.zig index 124d3cf2530c5524db35cc847ea48d4cc812a702..09e428984c35650da551aa33319add57ef62c4d8 100644 --- a/lib/std/io.zig +++ b/lib/std/io.zig @@ -1107,7 +1107,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co byte.* = if (t_bit_count < u8_bit_count) v else @truncate(u8, v); } - try self.out_stream.write(buffer); + try self.out_stream.write(&buffer); } /// Serializes the passed value into the stream diff --git a/lib/std/io/out_stream.zig b/lib/std/io/out_stream.zig index c0cd6e48a15954f9d0dfec1329fe94f861321108..77698b333c5b92cebd78cba5a8050ea73291135b 100644 --- a/lib/std/io/out_stream.zig +++ b/lib/std/io/out_stream.zig @@ -56,32 +56,32 @@ pub fn OutStream(comptime WriteError: type) type { pub fn writeIntNative(self: *Self, comptime T: type, value: T) Error!void { var bytes: [(T.bit_count + 7) / 8]u8 = undefined; mem.writeIntNative(T, &bytes, value); - return self.writeFn(self, bytes); + return self.writeFn(self, &bytes); } /// Write a foreign-endian integer. pub fn writeIntForeign(self: *Self, comptime T: type, value: T) Error!void { var bytes: [(T.bit_count + 7) / 8]u8 = undefined; mem.writeIntForeign(T, &bytes, value); - return self.writeFn(self, bytes); + return self.writeFn(self, &bytes); } pub fn writeIntLittle(self: *Self, comptime T: type, value: T) Error!void { var bytes: [(T.bit_count + 7) / 8]u8 = undefined; mem.writeIntLittle(T, &bytes, value); - return self.writeFn(self, bytes); + return self.writeFn(self, &bytes); } pub fn writeIntBig(self: *Self, comptime T: type, value: T) Error!void { var bytes: [(T.bit_count + 7) / 8]u8 = undefined; mem.writeIntBig(T, &bytes, value); - return self.writeFn(self, bytes); + return self.writeFn(self, &bytes); } pub fn writeInt(self: *Self, comptime T: type, value: T, endian: builtin.Endian) Error!void { var bytes: [(T.bit_count + 7) / 8]u8 = undefined; mem.writeInt(T, &bytes, value, endian); - return self.writeFn(self, bytes); + return self.writeFn(self, &bytes); } }; } diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index d2374f0a3fa00264ddf2cb7f8acd7e7a606810ca..c7471fd3152df7da0efbf903124dee0f23604b34 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -55,7 +55,7 @@ test "write a file, read it, then delete it" { defer allocator.free(contents); expect(mem.eql(u8, contents[0.."begin".len], "begin")); - expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data)); + expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], &data)); expect(mem.eql(u8, contents[contents.len - "end".len ..], "end")); } try fs.deleteFile(tmp_file_name); @@ -77,7 +77,7 @@ test "BufferOutStream" { test "SliceInStream" { const bytes = [_]u8{ 1, 2, 3, 4, 5, 6, 7 }; - var ss = io.SliceInStream.init(bytes); + var ss = io.SliceInStream.init(&bytes); var dest: [4]u8 = undefined; @@ -95,7 +95,7 @@ test "SliceInStream" { test "PeekStream" { const bytes = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; - var ss = io.SliceInStream.init(bytes); + var ss = io.SliceInStream.init(&bytes); var ps = io.PeekStream(2, io.SliceInStream.Error).init(&ss.stream); var dest: [4]u8 = undefined; @@ -614,7 +614,7 @@ test "File seek ops" { fs.deleteFile(tmp_file_name) catch {}; } - try file.write([_]u8{0x55} ** 8192); + try file.write(&([_]u8{0x55} ** 8192)); // Seek to the end try file.seekFromEnd(0); diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 412bf9b649f479198e14258982b9e557d378836c..cba1f9f177a1b8cf9820c5785f60a4596ef88adf 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -624,23 +624,23 @@ test "comptime read/write int" { } test "readIntBig and readIntLittle" { - testing.expect(readIntSliceBig(u0, [_]u8{}) == 0x0); - testing.expect(readIntSliceLittle(u0, [_]u8{}) == 0x0); + testing.expect(readIntSliceBig(u0, &[_]u8{}) == 0x0); + testing.expect(readIntSliceLittle(u0, &[_]u8{}) == 0x0); - testing.expect(readIntSliceBig(u8, [_]u8{0x32}) == 0x32); - testing.expect(readIntSliceLittle(u8, [_]u8{0x12}) == 0x12); + testing.expect(readIntSliceBig(u8, &[_]u8{0x32}) == 0x32); + testing.expect(readIntSliceLittle(u8, &[_]u8{0x12}) == 0x12); - testing.expect(readIntSliceBig(u16, [_]u8{ 0x12, 0x34 }) == 0x1234); - testing.expect(readIntSliceLittle(u16, [_]u8{ 0x12, 0x34 }) == 0x3412); + testing.expect(readIntSliceBig(u16, &[_]u8{ 0x12, 0x34 }) == 0x1234); + testing.expect(readIntSliceLittle(u16, &[_]u8{ 0x12, 0x34 }) == 0x3412); - testing.expect(readIntSliceBig(u72, [_]u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024); - testing.expect(readIntSliceLittle(u72, [_]u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec); + testing.expect(readIntSliceBig(u72, &[_]u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024); + testing.expect(readIntSliceLittle(u72, &[_]u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec); - testing.expect(readIntSliceBig(i8, [_]u8{0xff}) == -1); - testing.expect(readIntSliceLittle(i8, [_]u8{0xfe}) == -2); + testing.expect(readIntSliceBig(i8, &[_]u8{0xff}) == -1); + testing.expect(readIntSliceLittle(i8, &[_]u8{0xfe}) == -2); - testing.expect(readIntSliceBig(i16, [_]u8{ 0xff, 0xfd }) == -3); - testing.expect(readIntSliceLittle(i16, [_]u8{ 0xfc, 0xff }) == -4); + testing.expect(readIntSliceBig(i16, &[_]u8{ 0xff, 0xfd }) == -3); + testing.expect(readIntSliceLittle(i16, &[_]u8{ 0xfc, 0xff }) == -4); } /// Writes an integer to memory, storing it in twos-complement. @@ -749,34 +749,34 @@ test "writeIntBig and writeIntLittle" { var buf9: [9]u8 = undefined; writeIntBig(u0, &buf0, 0x0); - testing.expect(eql(u8, buf0[0..], [_]u8{})); + testing.expect(eql(u8, buf0[0..], &[_]u8{})); writeIntLittle(u0, &buf0, 0x0); - testing.expect(eql(u8, buf0[0..], [_]u8{})); + testing.expect(eql(u8, buf0[0..], &[_]u8{})); writeIntBig(u8, &buf1, 0x12); - testing.expect(eql(u8, buf1[0..], [_]u8{0x12})); + testing.expect(eql(u8, buf1[0..], &[_]u8{0x12})); writeIntLittle(u8, &buf1, 0x34); - testing.expect(eql(u8, buf1[0..], [_]u8{0x34})); + testing.expect(eql(u8, buf1[0..], &[_]u8{0x34})); writeIntBig(u16, &buf2, 0x1234); - testing.expect(eql(u8, buf2[0..], [_]u8{ 0x12, 0x34 })); + testing.expect(eql(u8, buf2[0..], &[_]u8{ 0x12, 0x34 })); writeIntLittle(u16, &buf2, 0x5678); - testing.expect(eql(u8, buf2[0..], [_]u8{ 0x78, 0x56 })); + testing.expect(eql(u8, buf2[0..], &[_]u8{ 0x78, 0x56 })); writeIntBig(u72, &buf9, 0x123456789abcdef024); - testing.expect(eql(u8, buf9[0..], [_]u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 })); + testing.expect(eql(u8, buf9[0..], &[_]u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 })); writeIntLittle(u72, &buf9, 0xfedcba9876543210ec); - testing.expect(eql(u8, buf9[0..], [_]u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe })); + testing.expect(eql(u8, buf9[0..], &[_]u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe })); writeIntBig(i8, &buf1, -1); - testing.expect(eql(u8, buf1[0..], [_]u8{0xff})); + testing.expect(eql(u8, buf1[0..], &[_]u8{0xff})); writeIntLittle(i8, &buf1, -2); - testing.expect(eql(u8, buf1[0..], [_]u8{0xfe})); + testing.expect(eql(u8, buf1[0..], &[_]u8{0xfe})); writeIntBig(i16, &buf2, -3); - testing.expect(eql(u8, buf2[0..], [_]u8{ 0xff, 0xfd })); + testing.expect(eql(u8, buf2[0..], &[_]u8{ 0xff, 0xfd })); writeIntLittle(i16, &buf2, -4); - testing.expect(eql(u8, buf2[0..], [_]u8{ 0xfc, 0xff })); + testing.expect(eql(u8, buf2[0..], &[_]u8{ 0xfc, 0xff })); } /// Returns an iterator that iterates over the slices of `buffer` that are not @@ -1004,9 +1004,9 @@ pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []cons test "mem.join" { var buf: [1024]u8 = undefined; const a = &std.heap.FixedBufferAllocator.init(&buf).allocator; - testing.expect(eql(u8, try join(a, ",", [_][]const u8{ "a", "b", "c" }), "a,b,c")); - testing.expect(eql(u8, try join(a, ",", [_][]const u8{"a"}), "a")); - testing.expect(eql(u8, try join(a, ",", [_][]const u8{ "a", "", "b", "", "c" }), "a,,b,,c")); + testing.expect(eql(u8, try join(a, ",", &[_][]const u8{ "a", "b", "c" }), "a,b,c")); + testing.expect(eql(u8, try join(a, ",", &[_][]const u8{"a"}), "a")); + testing.expect(eql(u8, try join(a, ",", &[_][]const u8{ "a", "", "b", "", "c" }), "a,,b,,c")); } /// Copies each T from slices into a new slice that exactly holds all the elements. @@ -1037,13 +1037,13 @@ pub fn concat(allocator: *Allocator, comptime T: type, slices: []const []const T test "concat" { var buf: [1024]u8 = undefined; const a = &std.heap.FixedBufferAllocator.init(&buf).allocator; - testing.expect(eql(u8, try concat(a, u8, [_][]const u8{ "abc", "def", "ghi" }), "abcdefghi")); - testing.expect(eql(u32, try concat(a, u32, [_][]const u32{ - [_]u32{ 0, 1 }, - [_]u32{ 2, 3, 4 }, - [_]u32{}, - [_]u32{5}, - }), [_]u32{ 0, 1, 2, 3, 4, 5 })); + testing.expect(eql(u8, try concat(a, u8, &[_][]const u8{ "abc", "def", "ghi" }), "abcdefghi")); + testing.expect(eql(u32, try concat(a, u32, &[_][]const u32{ + &[_]u32{ 0, 1 }, + &[_]u32{ 2, 3, 4 }, + &[_]u32{}, + &[_]u32{5}, + }), &[_]u32{ 0, 1, 2, 3, 4, 5 })); } test "testStringEquality" { @@ -1111,19 +1111,19 @@ fn testWriteIntImpl() void { var bytes: [8]u8 = undefined; writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Big); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, })); writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Little); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, })); writeIntSlice(u64, bytes[0..], 0x12345678CAFEBABE, builtin.Endian.Big); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x12, 0x34, 0x56, @@ -1135,7 +1135,7 @@ fn testWriteIntImpl() void { })); writeIntSlice(u64, bytes[0..], 0xBEBAFECA78563412, builtin.Endian.Little); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x12, 0x34, 0x56, @@ -1147,7 +1147,7 @@ fn testWriteIntImpl() void { })); writeIntSlice(u32, bytes[0..], 0x12345678, builtin.Endian.Big); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x00, 0x00, 0x00, @@ -1159,7 +1159,7 @@ fn testWriteIntImpl() void { })); writeIntSlice(u32, bytes[0..], 0x78563412, builtin.Endian.Little); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x12, 0x34, 0x56, @@ -1171,7 +1171,7 @@ fn testWriteIntImpl() void { })); writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Big); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x00, 0x00, 0x00, @@ -1183,7 +1183,7 @@ fn testWriteIntImpl() void { })); writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Little); - testing.expect(eql(u8, bytes, [_]u8{ + testing.expect(eql(u8, &bytes, &[_]u8{ 0x34, 0x12, 0x00, @@ -1235,22 +1235,10 @@ pub fn reverse(comptime T: type, items: []T) void { } test "reverse" { - var arr = [_]i32{ - 5, - 3, - 1, - 2, - 4, - }; + var arr = [_]i32{ 5, 3, 1, 2, 4 }; reverse(i32, arr[0..]); - testing.expect(eql(i32, arr, [_]i32{ - 4, - 2, - 1, - 3, - 5, - })); + testing.expect(eql(i32, &arr, &[_]i32{ 4, 2, 1, 3, 5 })); } /// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1) @@ -1262,22 +1250,10 @@ pub fn rotate(comptime T: type, items: []T, amount: usize) void { } test "rotate" { - var arr = [_]i32{ - 5, - 3, - 1, - 2, - 4, - }; + var arr = [_]i32{ 5, 3, 1, 2, 4 }; rotate(i32, arr[0..], 2); - testing.expect(eql(i32, arr, [_]i32{ - 1, - 2, - 4, - 5, - 3, - })); + testing.expect(eql(i32, &arr, &[_]i32{ 1, 2, 4, 5, 3 })); } /// Converts a little-endian integer to host endianness. @@ -1394,14 +1370,14 @@ pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 { test "toBytes" { var my_bytes = toBytes(@as(u32, 0x12345678)); switch (builtin.endian) { - builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x12\x34\x56\x78")), - builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x78\x56\x34\x12")), + builtin.Endian.Big => testing.expect(eql(u8, &my_bytes, "\x12\x34\x56\x78")), + builtin.Endian.Little => testing.expect(eql(u8, &my_bytes, "\x78\x56\x34\x12")), } my_bytes[0] = '\x99'; switch (builtin.endian) { - builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x99\x34\x56\x78")), - builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x99\x56\x34\x12")), + builtin.Endian.Big => testing.expect(eql(u8, &my_bytes, "\x99\x34\x56\x78")), + builtin.Endian.Little => testing.expect(eql(u8, &my_bytes, "\x99\x56\x34\x12")), } } @@ -1495,14 +1471,14 @@ pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubA test "subArrayPtr" { const a1: [6]u8 = "abcdef".*; const sub1 = subArrayPtr(&a1, 2, 3); - testing.expect(eql(u8, sub1.*, "cde")); + testing.expect(eql(u8, sub1, "cde")); var a2: [6]u8 = "abcdef".*; var sub2 = subArrayPtr(&a2, 2, 3); testing.expect(eql(u8, sub2, "cde")); sub2[1] = 'X'; - testing.expect(eql(u8, a2, "abcXef")); + testing.expect(eql(u8, &a2, "abcXef")); } /// Round an address up to the nearest aligned address diff --git a/lib/std/meta/trait.zig b/lib/std/meta/trait.zig index 2388acbeb62ffd63fa1334d1561eb7517c4f00e6..5da6e464b673b10b0f0198e0ab4982a6e60dee3a 100644 --- a/lib/std/meta/trait.zig +++ b/lib/std/meta/trait.zig @@ -46,7 +46,7 @@ test "std.meta.trait.multiTrait" { } }; - const isVector = multiTrait([_]TraitFn{ + const isVector = multiTrait(&[_]TraitFn{ hasFn("add"), hasField("x"), hasField("y"), diff --git a/lib/std/net.zig b/lib/std/net.zig index 7a7b2de02622db5f0bba56fa282746ef92c21200..7502f1e26207ba2e1926cdf3828882937c8af9dd 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -291,7 +291,7 @@ pub const Address = extern union { }, os.AF_INET6 => { const port = mem.bigToNative(u16, self.in6.port); - if (mem.eql(u8, self.in6.addr[0..12], [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) { + if (mem.eql(u8, self.in6.addr[0..12], &[_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) { try std.fmt.format( context, Errors, @@ -339,7 +339,7 @@ pub const Address = extern union { unreachable; } - try std.fmt.format(context, Errors, output, "{}", self.un.path); + try std.fmt.format(context, Errors, output, "{}", &self.un.path); }, else => unreachable, } @@ -894,7 +894,7 @@ fn linuxLookupNameFromDnsSearch( } const search = if (rc.search.isNull() or dots >= rc.ndots or mem.endsWith(u8, name, ".")) - [_]u8{} + &[_]u8{} else rc.search.toSliceConst(); @@ -959,7 +959,7 @@ fn linuxLookupNameFromDns( for (afrrs) |afrr| { if (family != afrr.af) { - const len = os.res_mkquery(0, name, 1, afrr.rr, [_]u8{}, null, &qbuf[nq]); + const len = os.res_mkquery(0, name, 1, afrr.rr, &[_]u8{}, null, &qbuf[nq]); qp[nq] = qbuf[nq][0..len]; nq += 1; } diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index 778a39eb3c6bfba0b6d4484a0df5e278567ef232..8fff83d8c7d4e4ccc530686d1f9bad997733a48a 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -137,7 +137,7 @@ test "getrandom" { try os.getrandom(&buf_b); // If this test fails the chance is significantly higher that there is a bug than // that two sets of 50 bytes were equal. - expect(!mem.eql(u8, buf_a, buf_b)); + expect(!mem.eql(u8, &buf_a, &buf_b)); } test "getcwd" { diff --git a/lib/std/packed_int_array.zig b/lib/std/packed_int_array.zig index 57660f23d92927c3c75bee42915fa973f051c0c6..bc29e985b5edd41da4ebcefc932fe36daa7e2e46 100644 --- a/lib/std/packed_int_array.zig +++ b/lib/std/packed_int_array.zig @@ -201,7 +201,7 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian, ///Return the Int stored at index pub fn get(self: Self, index: usize) Int { debug.assert(index < int_count); - return Io.get(self.bytes, index, 0); + return Io.get(&self.bytes, index, 0); } ///Copy int into the array at index @@ -528,16 +528,7 @@ test "PackedInt(Array/Slice) sliceCast" { test "PackedInt(Array/Slice)Endian" { { const PackedArrayBe = PackedIntArrayEndian(u4, .Big, 8); - var packed_array_be = PackedArrayBe.init([_]u4{ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - }); + var packed_array_be = PackedArrayBe.init([_]u4{ 0, 1, 2, 3, 4, 5, 6, 7 }); testing.expect(packed_array_be.bytes[0] == 0b00000001); testing.expect(packed_array_be.bytes[1] == 0b00100011); @@ -563,16 +554,7 @@ test "PackedInt(Array/Slice)Endian" { { const PackedArrayBe = PackedIntArrayEndian(u11, .Big, 8); - var packed_array_be = PackedArrayBe.init([_]u11{ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - }); + var packed_array_be = PackedArrayBe.init([_]u11{ 0, 1, 2, 3, 4, 5, 6, 7 }); testing.expect(packed_array_be.bytes[0] == 0b00000000); testing.expect(packed_array_be.bytes[1] == 0b00000000); testing.expect(packed_array_be.bytes[2] == 0b00000100); diff --git a/lib/std/priority_queue.zig b/lib/std/priority_queue.zig index bf54f6937f3ed3e1508d7cb227ff37919005a7a9..3351ac994bec888a5a1c81991fce424c62617a06 100644 --- a/lib/std/priority_queue.zig +++ b/lib/std/priority_queue.zig @@ -22,7 +22,7 @@ pub fn PriorityQueue(comptime T: type) type { /// `fn lessThan(a: T, b: T) bool { return a < b; }` pub fn init(allocator: *Allocator, compareFn: fn (a: T, b: T) bool) Self { return Self{ - .items = [_]T{}, + .items = &[_]T{}, .len = 0, .allocator = allocator, .compareFn = compareFn, diff --git a/lib/std/process.zig b/lib/std/process.zig index e432be213f19a9258c8c37d8fd97f56c7851ebc1..0ce3cabc199c3dcb47da14bd97675370c9daf4ce 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -473,14 +473,14 @@ pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void { } test "windows arg parsing" { - testWindowsCmdLine("a b\tc d", [_][]const u8{ "a", "b", "c", "d" }); - testWindowsCmdLine("\"abc\" d e", [_][]const u8{ "abc", "d", "e" }); - testWindowsCmdLine("a\\\\\\b d\"e f\"g h", [_][]const u8{ "a\\\\\\b", "de fg", "h" }); - testWindowsCmdLine("a\\\\\\\"b c d", [_][]const u8{ "a\\\"b", "c", "d" }); - testWindowsCmdLine("a\\\\\\\\\"b c\" d e", [_][]const u8{ "a\\\\b c", "d", "e" }); - testWindowsCmdLine("a b\tc \"d f", [_][]const u8{ "a", "b", "c", "\"d", "f" }); + testWindowsCmdLine("a b\tc d", &[_][]const u8{ "a", "b", "c", "d" }); + testWindowsCmdLine("\"abc\" d e", &[_][]const u8{ "abc", "d", "e" }); + testWindowsCmdLine("a\\\\\\b d\"e f\"g h", &[_][]const u8{ "a\\\\\\b", "de fg", "h" }); + testWindowsCmdLine("a\\\\\\\"b c d", &[_][]const u8{ "a\\\"b", "c", "d" }); + testWindowsCmdLine("a\\\\\\\\\"b c\" d e", &[_][]const u8{ "a\\\\b c", "d", "e" }); + testWindowsCmdLine("a b\tc \"d f", &[_][]const u8{ "a", "b", "c", "\"d", "f" }); - testWindowsCmdLine("\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [_][]const u8{ + testWindowsCmdLine("\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", &[_][]const u8{ ".\\..\\zig-cache\\build", "bin\\zig.exe", ".\\..", diff --git a/lib/std/rand.zig b/lib/std/rand.zig index 1fea0526edefc3391d5fe1272a17d91eb531fd79..f9fa4a2d663580af98954fa2792baf52e0ac9a0c 100644 --- a/lib/std/rand.zig +++ b/lib/std/rand.zig @@ -54,7 +54,7 @@ pub const Random = struct { // use LE instead of native endian for better portability maybe? // TODO: endian portability is pointless if the underlying prng isn't endian portable. // TODO: document the endian portability of this library. - const byte_aligned_result = mem.readIntSliceLittle(ByteAlignedT, rand_bytes); + const byte_aligned_result = mem.readIntSliceLittle(ByteAlignedT, &rand_bytes); const unsigned_result = @truncate(UnsignedT, byte_aligned_result); return @bitCast(T, unsigned_result); } diff --git a/lib/std/segmented_list.zig b/lib/std/segmented_list.zig index e74b17dd5c2e39cef346c6e4aeaa1d8c66a06c77..8c5ded364777da15ab8842542ef6f119fce3d842 100644 --- a/lib/std/segmented_list.zig +++ b/lib/std/segmented_list.zig @@ -112,7 +112,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type .allocator = allocator, .len = 0, .prealloc_segment = undefined, - .dynamic_segments = [_][*]T{}, + .dynamic_segments = &[_][*]T{}, }; } @@ -192,7 +192,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type const len = @intCast(ShelfIndex, self.dynamic_segments.len); self.freeShelves(len, 0); self.allocator.free(self.dynamic_segments); - self.dynamic_segments = [_][*]T{}; + self.dynamic_segments = &[_][*]T{}; return; } @@ -385,18 +385,14 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { testing.expect(list.pop().? == 100); testing.expect(list.len == 99); - try list.pushMany([_]i32{ - 1, - 2, - 3, - }); + try list.pushMany(&[_]i32{ 1, 2, 3 }); testing.expect(list.len == 102); testing.expect(list.pop().? == 3); testing.expect(list.pop().? == 2); testing.expect(list.pop().? == 1); testing.expect(list.len == 99); - try list.pushMany([_]i32{}); + try list.pushMany(&[_]i32{}); testing.expect(list.len == 99); var i: i32 = 99; diff --git a/lib/std/sort.zig b/lib/std/sort.zig index 790fd46756f6af7173864a5b29e1afc9ac8f6210..f8b8a39134f5915d56beff380d965091e44d9756 100644 --- a/lib/std/sort.zig +++ b/lib/std/sort.zig @@ -1043,27 +1043,27 @@ fn cmpByValue(a: IdAndValue, b: IdAndValue) bool { test "std.sort" { const u8cases = [_][]const []const u8{ - [_][]const u8{ + &[_][]const u8{ "", "", }, - [_][]const u8{ + &[_][]const u8{ "a", "a", }, - [_][]const u8{ + &[_][]const u8{ "az", "az", }, - [_][]const u8{ + &[_][]const u8{ "za", "az", }, - [_][]const u8{ + &[_][]const u8{ "asdf", "adfs", }, - [_][]const u8{ + &[_][]const u8{ "one", "eno", }, @@ -1078,29 +1078,29 @@ test "std.sort" { } const i32cases = [_][]const []const i32{ - [_][]const i32{ - [_]i32{}, - [_]i32{}, + &[_][]const i32{ + &[_]i32{}, + &[_]i32{}, }, - [_][]const i32{ - [_]i32{1}, - [_]i32{1}, + &[_][]const i32{ + &[_]i32{1}, + &[_]i32{1}, }, - [_][]const i32{ - [_]i32{ 0, 1 }, - [_]i32{ 0, 1 }, + &[_][]const i32{ + &[_]i32{ 0, 1 }, + &[_]i32{ 0, 1 }, }, - [_][]const i32{ - [_]i32{ 1, 0 }, - [_]i32{ 0, 1 }, + &[_][]const i32{ + &[_]i32{ 1, 0 }, + &[_]i32{ 0, 1 }, }, - [_][]const i32{ - [_]i32{ 1, -1, 0 }, - [_]i32{ -1, 0, 1 }, + &[_][]const i32{ + &[_]i32{ 1, -1, 0 }, + &[_]i32{ -1, 0, 1 }, }, - [_][]const i32{ - [_]i32{ 2, 1, 3 }, - [_]i32{ 1, 2, 3 }, + &[_][]const i32{ + &[_]i32{ 2, 1, 3 }, + &[_]i32{ 1, 2, 3 }, }, }; @@ -1115,29 +1115,29 @@ test "std.sort" { test "std.sort descending" { const rev_cases = [_][]const []const i32{ - [_][]const i32{ - [_]i32{}, - [_]i32{}, + &[_][]const i32{ + &[_]i32{}, + &[_]i32{}, }, - [_][]const i32{ - [_]i32{1}, - [_]i32{1}, + &[_][]const i32{ + &[_]i32{1}, + &[_]i32{1}, }, - [_][]const i32{ - [_]i32{ 0, 1 }, - [_]i32{ 1, 0 }, + &[_][]const i32{ + &[_]i32{ 0, 1 }, + &[_]i32{ 1, 0 }, }, - [_][]const i32{ - [_]i32{ 1, 0 }, - [_]i32{ 1, 0 }, + &[_][]const i32{ + &[_]i32{ 1, 0 }, + &[_]i32{ 1, 0 }, }, - [_][]const i32{ - [_]i32{ 1, -1, 0 }, - [_]i32{ 1, 0, -1 }, + &[_][]const i32{ + &[_]i32{ 1, -1, 0 }, + &[_]i32{ 1, 0, -1 }, }, - [_][]const i32{ - [_]i32{ 2, 1, 3 }, - [_]i32{ 3, 2, 1 }, + &[_][]const i32{ + &[_]i32{ 2, 1, 3 }, + &[_]i32{ 3, 2, 1 }, }, }; @@ -1154,7 +1154,7 @@ test "another sort case" { var arr = [_]i32{ 5, 3, 1, 2, 4 }; sort(i32, arr[0..], asc(i32)); - testing.expect(mem.eql(i32, arr, [_]i32{ 1, 2, 3, 4, 5 })); + testing.expect(mem.eql(i32, &arr, &[_]i32{ 1, 2, 3, 4, 5 })); } test "sort fuzz testing" { diff --git a/lib/std/unicode.zig b/lib/std/unicode.zig index 726b84f1250aa6a3ca40f296c81735de309d0cb2..4af1b63a69e49085c93dde3f8f5fc50aa1a21284 100644 --- a/lib/std/unicode.zig +++ b/lib/std/unicode.zig @@ -499,14 +499,14 @@ test "utf16leToUtf8" { { mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A'); mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 'a'); - const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); + const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, &utf16le); testing.expect(mem.eql(u8, utf8, "Aa")); } { mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0x80); mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xffff); - const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); + const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, &utf16le); testing.expect(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf")); } @@ -514,7 +514,7 @@ test "utf16leToUtf8" { // the values just outside the surrogate half range mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd7ff); mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xe000); - const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); + const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, &utf16le); testing.expect(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80")); } @@ -522,7 +522,7 @@ test "utf16leToUtf8" { // smallest surrogate pair mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd800); mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00); - const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); + const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, &utf16le); testing.expect(mem.eql(u8, utf8, "\xf0\x90\x80\x80")); } @@ -530,14 +530,14 @@ test "utf16leToUtf8" { // largest surrogate pair mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff); mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdfff); - const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); + const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, &utf16le); testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf")); } { mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff); mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00); - const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le); + const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, &utf16le); testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80")); } } diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig index 0b2aea4cf63f90ef33cfd8dfb0ff7aaab5796f7e..e7d2b41784aa644b02f9871eca00d7d0f0b8d4af 100644 --- a/lib/std/zig/tokenizer.zig +++ b/lib/std/zig/tokenizer.zig @@ -1313,14 +1313,14 @@ pub const Tokenizer = struct { }; test "tokenizer" { - testTokenize("test", [_]Token.Id{Token.Id.Keyword_test}); + testTokenize("test", &[_]Token.Id{Token.Id.Keyword_test}); } test "tokenizer - unknown length pointer and then c pointer" { testTokenize( \\[*]u8 \\[*c]u8 - , [_]Token.Id{ + , &[_]Token.Id{ Token.Id.LBracket, Token.Id.Asterisk, Token.Id.RBracket, @@ -1336,70 +1336,70 @@ test "tokenizer - unknown length pointer and then c pointer" { test "tokenizer - char literal with hex escape" { testTokenize( \\'\x1b' - , [_]Token.Id{.CharLiteral}); + , &[_]Token.Id{.CharLiteral}); testTokenize( \\'\x1' - , [_]Token.Id{ .Invalid, .Invalid }); + , &[_]Token.Id{ .Invalid, .Invalid }); } test "tokenizer - char literal with unicode escapes" { // Valid unicode escapes testTokenize( \\'\u{3}' - , [_]Token.Id{.CharLiteral}); + , &[_]Token.Id{.CharLiteral}); testTokenize( \\'\u{01}' - , [_]Token.Id{.CharLiteral}); + , &[_]Token.Id{.CharLiteral}); testTokenize( \\'\u{2a}' - , [_]Token.Id{.CharLiteral}); + , &[_]Token.Id{.CharLiteral}); testTokenize( \\'\u{3f9}' - , [_]Token.Id{.CharLiteral}); + , &[_]Token.Id{.CharLiteral}); testTokenize( \\'\u{6E09aBc1523}' - , [_]Token.Id{.CharLiteral}); + , &[_]Token.Id{.CharLiteral}); testTokenize( \\"\u{440}" - , [_]Token.Id{.StringLiteral}); + , &[_]Token.Id{.StringLiteral}); // Invalid unicode escapes testTokenize( \\'\u' - , [_]Token.Id{.Invalid}); + , &[_]Token.Id{.Invalid}); testTokenize( \\'\u{{' - , [_]Token.Id{ .Invalid, .Invalid }); + , &[_]Token.Id{ .Invalid, .Invalid }); testTokenize( \\'\u{}' - , [_]Token.Id{ .Invalid, .Invalid }); + , &[_]Token.Id{ .Invalid, .Invalid }); testTokenize( \\'\u{s}' - , [_]Token.Id{ .Invalid, .Invalid }); + , &[_]Token.Id{ .Invalid, .Invalid }); testTokenize( \\'\u{2z}' - , [_]Token.Id{ .Invalid, .Invalid }); + , &[_]Token.Id{ .Invalid, .Invalid }); testTokenize( \\'\u{4a' - , [_]Token.Id{.Invalid}); + , &[_]Token.Id{.Invalid}); // Test old-style unicode literals testTokenize( \\'\u0333' - , [_]Token.Id{ .Invalid, .Invalid }); + , &[_]Token.Id{ .Invalid, .Invalid }); testTokenize( \\'\U0333' - , [_]Token.Id{ .Invalid, .IntegerLiteral, .Invalid }); + , &[_]Token.Id{ .Invalid, .IntegerLiteral, .Invalid }); } test "tokenizer - char literal with unicode code point" { testTokenize( \\'💩' - , [_]Token.Id{.CharLiteral}); + , &[_]Token.Id{.CharLiteral}); } test "tokenizer - float literal e exponent" { - testTokenize("a = 4.94065645841246544177e-324;\n", [_]Token.Id{ + testTokenize("a = 4.94065645841246544177e-324;\n", &[_]Token.Id{ Token.Id.Identifier, Token.Id.Equal, Token.Id.FloatLiteral, @@ -1408,7 +1408,7 @@ test "tokenizer - float literal e exponent" { } test "tokenizer - float literal p exponent" { - testTokenize("a = 0x1.a827999fcef32p+1022;\n", [_]Token.Id{ + testTokenize("a = 0x1.a827999fcef32p+1022;\n", &[_]Token.Id{ Token.Id.Identifier, Token.Id.Equal, Token.Id.FloatLiteral, @@ -1417,71 +1417,71 @@ test "tokenizer - float literal p exponent" { } test "tokenizer - chars" { - testTokenize("'c'", [_]Token.Id{Token.Id.CharLiteral}); + testTokenize("'c'", &[_]Token.Id{Token.Id.CharLiteral}); } test "tokenizer - invalid token characters" { - testTokenize("#", [_]Token.Id{Token.Id.Invalid}); - testTokenize("`", [_]Token.Id{Token.Id.Invalid}); - testTokenize("'c", [_]Token.Id{Token.Id.Invalid}); - testTokenize("'", [_]Token.Id{Token.Id.Invalid}); - testTokenize("''", [_]Token.Id{ Token.Id.Invalid, Token.Id.Invalid }); + testTokenize("#", &[_]Token.Id{Token.Id.Invalid}); + testTokenize("`", &[_]Token.Id{Token.Id.Invalid}); + testTokenize("'c", &[_]Token.Id{Token.Id.Invalid}); + testTokenize("'", &[_]Token.Id{Token.Id.Invalid}); + testTokenize("''", &[_]Token.Id{ Token.Id.Invalid, Token.Id.Invalid }); } test "tokenizer - invalid literal/comment characters" { - testTokenize("\"\x00\"", [_]Token.Id{ + testTokenize("\"\x00\"", &[_]Token.Id{ Token.Id.StringLiteral, Token.Id.Invalid, }); - testTokenize("//\x00", [_]Token.Id{ + testTokenize("//\x00", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\x1f", [_]Token.Id{ + testTokenize("//\x1f", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\x7f", [_]Token.Id{ + testTokenize("//\x7f", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); } test "tokenizer - utf8" { - testTokenize("//\xc2\x80", [_]Token.Id{Token.Id.LineComment}); - testTokenize("//\xf4\x8f\xbf\xbf", [_]Token.Id{Token.Id.LineComment}); + testTokenize("//\xc2\x80", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("//\xf4\x8f\xbf\xbf", &[_]Token.Id{Token.Id.LineComment}); } test "tokenizer - invalid utf8" { - testTokenize("//\x80", [_]Token.Id{ + testTokenize("//\x80", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xbf", [_]Token.Id{ + testTokenize("//\xbf", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xf8", [_]Token.Id{ + testTokenize("//\xf8", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xff", [_]Token.Id{ + testTokenize("//\xff", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xc2\xc0", [_]Token.Id{ + testTokenize("//\xc2\xc0", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xe0", [_]Token.Id{ + testTokenize("//\xe0", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xf0", [_]Token.Id{ + testTokenize("//\xf0", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xf0\x90\x80\xc0", [_]Token.Id{ + testTokenize("//\xf0\x90\x80\xc0", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); @@ -1489,28 +1489,28 @@ test "tokenizer - invalid utf8" { test "tokenizer - illegal unicode codepoints" { // unicode newline characters.U+0085, U+2028, U+2029 - testTokenize("//\xc2\x84", [_]Token.Id{Token.Id.LineComment}); - testTokenize("//\xc2\x85", [_]Token.Id{ + testTokenize("//\xc2\x84", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("//\xc2\x85", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xc2\x86", [_]Token.Id{Token.Id.LineComment}); - testTokenize("//\xe2\x80\xa7", [_]Token.Id{Token.Id.LineComment}); - testTokenize("//\xe2\x80\xa8", [_]Token.Id{ + testTokenize("//\xc2\x86", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("//\xe2\x80\xa7", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("//\xe2\x80\xa8", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xe2\x80\xa9", [_]Token.Id{ + testTokenize("//\xe2\x80\xa9", &[_]Token.Id{ Token.Id.LineComment, Token.Id.Invalid, }); - testTokenize("//\xe2\x80\xaa", [_]Token.Id{Token.Id.LineComment}); + testTokenize("//\xe2\x80\xaa", &[_]Token.Id{Token.Id.LineComment}); } test "tokenizer - string identifier and builtin fns" { testTokenize( \\const @"if" = @import("std"); - , [_]Token.Id{ + , &[_]Token.Id{ Token.Id.Keyword_const, Token.Id.Identifier, Token.Id.Equal, @@ -1523,21 +1523,21 @@ test "tokenizer - string identifier and builtin fns" { } test "tokenizer - pipe and then invalid" { - testTokenize("||=", [_]Token.Id{ + testTokenize("||=", &[_]Token.Id{ Token.Id.PipePipe, Token.Id.Equal, }); } test "tokenizer - line comment and doc comment" { - testTokenize("//", [_]Token.Id{Token.Id.LineComment}); - testTokenize("// a / b", [_]Token.Id{Token.Id.LineComment}); - testTokenize("// /", [_]Token.Id{Token.Id.LineComment}); - testTokenize("/// a", [_]Token.Id{Token.Id.DocComment}); - testTokenize("///", [_]Token.Id{Token.Id.DocComment}); - testTokenize("////", [_]Token.Id{Token.Id.LineComment}); - testTokenize("//!", [_]Token.Id{Token.Id.ContainerDocComment}); - testTokenize("//!!", [_]Token.Id{Token.Id.ContainerDocComment}); + testTokenize("//", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("// a / b", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("// /", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("/// a", &[_]Token.Id{Token.Id.DocComment}); + testTokenize("///", &[_]Token.Id{Token.Id.DocComment}); + testTokenize("////", &[_]Token.Id{Token.Id.LineComment}); + testTokenize("//!", &[_]Token.Id{Token.Id.ContainerDocComment}); + testTokenize("//!!", &[_]Token.Id{Token.Id.ContainerDocComment}); } test "tokenizer - line comment followed by identifier" { @@ -1545,7 +1545,7 @@ test "tokenizer - line comment followed by identifier" { \\ Unexpected, \\ // another \\ Another, - , [_]Token.Id{ + , &[_]Token.Id{ Token.Id.Identifier, Token.Id.Comma, Token.Id.LineComment, @@ -1555,14 +1555,14 @@ test "tokenizer - line comment followed by identifier" { } test "tokenizer - UTF-8 BOM is recognized and skipped" { - testTokenize("\xEF\xBB\xBFa;\n", [_]Token.Id{ + testTokenize("\xEF\xBB\xBFa;\n", &[_]Token.Id{ Token.Id.Identifier, Token.Id.Semicolon, }); } test "correctly parse pointer assignment" { - testTokenize("b.*=3;\n", [_]Token.Id{ + testTokenize("b.*=3;\n", &[_]Token.Id{ Token.Id.Identifier, Token.Id.PeriodAsterisk, Token.Id.Equal, diff --git a/src-self-hosted/dep_tokenizer.zig b/src-self-hosted/dep_tokenizer.zig index 1a6d54f639e1eb7b36b165150afff27b5272dc87..9509aab70235bb7e8a369bd90bcaa0133c1b5d99 100644 --- a/src-self-hosted/dep_tokenizer.zig +++ b/src-self-hosted/dep_tokenizer.zig @@ -992,7 +992,7 @@ fn printHexValue(out: var, value: u64, width: u8) !void { fn printCharValues(out: var, bytes: []const u8) !void { for (bytes) |b| { - try out.write([_]u8{printable_char_tab[b]}); + try out.write(&[_]u8{printable_char_tab[b]}); } } @@ -1001,7 +1001,7 @@ fn printUnderstandableChar(out: var, char: u8) !void { std.fmt.format(out.context, anyerror, out.output, "\\x{X:2}", char) catch {}; } else { try out.write("'"); - try out.write([_]u8{printable_char_tab[char]}); + try out.write(&[_]u8{printable_char_tab[char]}); try out.write("'"); } } diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index bf3fb4dea5bdd875fbdc4f4f0804a6f6bb454111..49b378e8fce83f36c290251569c23f318a1edc30 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -521,7 +521,7 @@ pub const usage_fmt = pub const args_fmt_spec = [_]Flag{ Flag.Bool("--help"), Flag.Bool("--check"), - Flag.Option("--color", [_][]const u8{ + Flag.Option("--color", &[_][]const u8{ "auto", "off", "on", diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig index 96bf4b7fdf14015b2814ea1dc632f07fb32d8f0d..f8caaf3da27d03af97721b90e6431cc750d80421 100644 --- a/src-self-hosted/stage1.zig +++ b/src-self-hosted/stage1.zig @@ -170,7 +170,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void { stderr = &stderr_file.outStream().stream; const args = args_list.toSliceConst(); - var flags = try Args.parse(allocator, self_hosted_main.args_fmt_spec, args[2..]); + var flags = try Args.parse(allocator, &self_hosted_main.args_fmt_spec, args[2..]); defer flags.deinit(); if (flags.present("help")) { @@ -286,7 +286,7 @@ fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void while (try dir_it.next()) |entry| { if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { - const full_path = try fs.path.join(fmt.allocator, [_][]const u8{ file_path, entry.name }); + const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name }); try fmtPath(fmt, full_path, check_mode); } } diff --git a/src/all_types.hpp b/src/all_types.hpp index 5b062efc9a5b2f4f453e7ae5a5d29e8004fc17af..a5fa7241e3e380a2df97bf82af3f2a91d02f340e 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2650,6 +2650,9 @@ struct IrInstruction { IrInstructionId id; // true if this instruction was generated by zig and not from user code bool is_gen; + + // for debugging purposes, this is useful to call to inspect the instruction + void dump(); }; struct IrInstructionDeclVarSrc { diff --git a/src/ir.cpp b/src/ir.cpp index 2772108a21d39e5f426a7f72e2fdf2da41b659c5..1e32679babe394522a28589567e4ccddf2e55552 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -218,7 +218,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *dest_type); static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime); + ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, + bool non_null_comptime, bool allow_discard); static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime, bool allow_discard); @@ -10417,9 +10418,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } if (cur_type->id == ZigTypeIdErrorSet) { - if (prev_type->id == ZigTypeIdArray) { - convert_to_const_slice = true; - } if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { return ira->codegen->builtin_types.entry_invalid; } @@ -10754,25 +10752,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } - if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && - cur_type->data.array.len != prev_type->data.array.len && - types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - convert_to_const_slice = true; - prev_inst = cur_inst; - continue; - } - - if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && - cur_type->data.array.len != prev_type->data.array.len && - types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - convert_to_const_slice = true; - continue; - } - // *[N]T to []T // *[N]T to E![]T if (cur_type->id == ZigTypeIdPointer && @@ -10820,19 +10799,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } - // [N]T to []T - if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) && - (prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const || - cur_type->data.array.len == 0) && - types_match_const_cast_only(ira, - prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type, - cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) - { - convert_to_const_slice = false; - continue; - } - - // *[N]T and *[M]T if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && cur_type->data.pointer.child_type->id == ZigTypeIdArray && @@ -10876,19 +10842,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT continue; } - // [N]T to []T - if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && - (cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const || - prev_type->data.array.len == 0) && - types_match_const_cast_only(ira, - cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type, - prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) - { - prev_inst = cur_inst; - convert_to_const_slice = false; - continue; - } - if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) { @@ -10924,18 +10877,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT free(errors); if (convert_to_const_slice) { - if (prev_inst->value->type->id == ZigTypeIdArray) { - ZigType *ptr_type = get_pointer_to_type_extra( - ira->codegen, prev_inst->value->type->data.array.child_type, - true, false, PtrLenUnknown, - 0, 0, 0, false); - ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); - if (err_set_type != nullptr) { - return get_error_union_type(ira->codegen, err_set_type, slice_type); - } else { - return slice_type; - } - } else if (prev_inst->value->type->id == ZigTypeIdPointer) { + if (prev_inst->value->type->id == ZigTypeIdPointer) { ZigType *array_type = prev_inst->value->type->data.pointer.child_type; src_assert(array_type->id == ZigTypeIdArray, source_node); ZigType *ptr_type = get_pointer_to_type_extra2( @@ -12021,52 +11963,6 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi return new_instruction; } -static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc) -{ - assert(is_slice(wanted_type)); - // In this function we honor the const-ness of wanted_type, because - // we may be casting [0]T to []const T which is perfectly valid. - - IrInstruction *array_ptr = nullptr; - IrInstruction *array; - if (array_arg->value->type->id == ZigTypeIdPointer) { - array = ir_get_deref(ira, source_instr, array_arg, nullptr); - array_ptr = array_arg; - } else { - array = array_arg; - } - ZigType *array_type = array->value->type; - assert(array_type->id == ZigTypeIdArray); - - if (instr_is_comptime(array) || array_type->data.array.len == 0) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); - init_const_slice(ira->codegen, result->value, array->value, 0, array_type->data.array.len, true); - result->value->type = wanted_type; - return result; - } - - IrInstruction *start = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); - init_const_usize(ira->codegen, start->value, 0); - - IrInstruction *end = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); - init_const_usize(ira->codegen, end->value, array_type->data.array.len); - - if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); - - if (result_loc == nullptr) result_loc = no_result_loc(); - IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, - true, false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { - return result_loc_inst; - } - IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst); - result->value->data.rh_slice.id = RuntimeHintSliceIdLen; - result->value->data.rh_slice.len = array_type->data.array.len; - - return result; -} - static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *union_type) { assert(union_type->id == ZigTypeIdUnion); @@ -13101,44 +12997,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); } - // cast from [N]T to []const T - // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this - if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { - ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; - assert(ptr_type->id == ZigTypeIdPointer); - if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && - types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, nullptr); - } - } - - // cast from [N]T to ?[]const T - // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this - if (wanted_type->id == ZigTypeIdOptional && - is_slice(wanted_type->data.maybe.child_type) && - actual_type->id == ZigTypeIdArray) - { - ZigType *ptr_type = - wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index]->type_entry; - assert(ptr_type->id == ZigTypeIdPointer); - if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && - types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); - if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; - - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); - if (type_is_invalid(cast2->value->type)) - return ira->codegen->invalid_instruction; - - return cast2; - } - } - // *[N]T to ?[]const T if (wanted_type->id == ZigTypeIdOptional && is_slice(wanted_type->data.maybe.child_type) && @@ -13284,20 +13142,41 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } // *@Frame(func) to anyframe->T or anyframe + // *@Frame(func) to ?anyframe->T or ?anyframe + // *@Frame(func) to E!anyframe->T or E!anyframe if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && !actual_type->data.pointer.is_const && - actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame && wanted_type->id == ZigTypeIdAnyFrame) + actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame) { - bool ok = true; - if (wanted_type->data.any_frame.result_type != nullptr) { - ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; - ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; - if (wanted_type->data.any_frame.result_type != fn_return_type) { - ok = false; - } + ZigType *anyframe_type; + if (wanted_type->id == ZigTypeIdAnyFrame) { + anyframe_type = wanted_type; + } else if (wanted_type->id == ZigTypeIdOptional && + wanted_type->data.maybe.child_type->id == ZigTypeIdAnyFrame) + { + anyframe_type = wanted_type->data.maybe.child_type; + } else if (wanted_type->id == ZigTypeIdErrorUnion && + wanted_type->data.error_union.payload_type->id == ZigTypeIdAnyFrame) + { + anyframe_type = wanted_type->data.error_union.payload_type; + } else { + anyframe_type = nullptr; } - if (ok) { - return ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, wanted_type); + if (anyframe_type != nullptr) { + bool ok = true; + if (anyframe_type->data.any_frame.result_type != nullptr) { + ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; + ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; + if (anyframe_type->data.any_frame.result_type != fn_return_type) { + ok = false; + } + } + if (ok) { + IrInstruction *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); + if (anyframe_type == wanted_type) + return cast1; + return ir_analyze_cast(ira, source_instr, wanted_type, cast1); + } } } @@ -13322,30 +13201,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); } - // cast from [N]T to E![]const T - if (wanted_type->id == ZigTypeIdErrorUnion && - is_slice(wanted_type->data.error_union.payload_type) && - actual_type->id == ZigTypeIdArray) - { - ZigType *ptr_type = - wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index]->type_entry; - assert(ptr_type->id == ZigTypeIdPointer); - if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && - types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); - if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; - - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); - if (type_is_invalid(cast2->value->type)) - return ira->codegen->invalid_instruction; - - return cast2; - } - } - // cast from E to E!T if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorSet) @@ -13541,6 +13396,16 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); } + // T to ?E!T + if (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdErrorUnion && + actual_type->id != ZigTypeIdOptional) + { + IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); + if (type_is_invalid(cast1->value->type)) + return ira->codegen->invalid_instruction; + return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); + } + ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, buf_sprintf("expected type '%s', found '%s'", buf_ptr(&wanted_type->name), @@ -15283,10 +15148,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i ZigValue *out_array_val; size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); - if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { - result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); - out_array_val = out_val; - } else if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { + if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { out_array_val = create_const_vals(1); out_array_val->special = ConstValSpecialStatic; out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); @@ -15314,6 +15176,9 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize; out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); + } else if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { + result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); + out_array_val = out_val; } else { result->value->type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); @@ -16142,7 +16007,8 @@ static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *su // when calling this function, at the callsite must check for result type noreturn and propagate it up static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) + ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, + bool non_null_comptime, bool allow_discard) { Error err; if (result_loc->resolved_loc != nullptr) { @@ -16275,8 +16141,12 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe ira->src_implicit_return_type_list.append(value); } peer_parent->skipped = true; - return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, + IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, value_type, value, force_runtime || !is_comptime, true, true); + if (parent_result_loc != nullptr) { + peer_parent->parent->written = true; + } + return parent_result_loc; } if (peer_parent->resolved_type == nullptr) { @@ -16317,30 +16187,16 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe force_runtime, non_null_comptime); } - ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type, - result_cast->base.source_instruction->source_node, false); - if (const_cast_result.id == ConstCastResultIdInvalid) - return ira->codegen->invalid_instruction; - if (const_cast_result.id != ConstCastResultIdOk) { - // We will not be able to provide a result location for this value. Create - // a new result location. - return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, - force_runtime, non_null_comptime); - } - - // In this case we can pointer cast the result location. IrInstruction *casted_value; if (value != nullptr) { casted_value = ir_implicit_cast(ira, value, dest_type); + if (type_is_invalid(casted_value->value->type)) + return ira->codegen->invalid_instruction; + dest_type = casted_value->value->type; } else { casted_value = nullptr; } - if (casted_value != nullptr && type_is_invalid(casted_value->value->type)) { - return casted_value; - } - - bool old_parent_result_loc_written = result_cast->parent->written; IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, dest_type, casted_value, force_runtime, non_null_comptime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || @@ -16378,26 +16234,24 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); - { - // we also need to check that this cast is OK. - ConstCastOnly const_cast_result = types_match_const_cast_only(ira, - parent_result_loc->value->type, ptr_type, - result_cast->base.source_instruction->source_node, false); - if (const_cast_result.id == ConstCastResultIdInvalid) - return ira->codegen->invalid_instruction; - if (const_cast_result.id != ConstCastResultIdOk) { - // We will not be able to provide a result location for this value. Create - // a new result location. - result_cast->parent->written = old_parent_result_loc_written; - return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, - force_runtime, non_null_comptime); + ConstCastOnly const_cast_result = types_match_const_cast_only(ira, + parent_result_loc->value->type, ptr_type, + result_cast->base.source_instruction->source_node, false); + if (const_cast_result.id == ConstCastResultIdInvalid) + return ira->codegen->invalid_instruction; + if (const_cast_result.id != ConstCastResultIdOk) { + if (allow_discard) { + return parent_result_loc; } + // We will not be able to provide a result location for this value. Create + // a new result location. + result_cast->parent->written = false; + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, + force_runtime, non_null_comptime); } - result_loc->written = true; - result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, + return ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, ptr_type, result_cast->base.source_instruction, false); - return result_loc->resolved_loc; } case ResultLocIdBitCast: { ResultLocBitCast *result_bit_cast = reinterpret_cast(result_loc); @@ -16483,7 +16337,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s result_loc_pass1 = no_result_loc(); } IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, - value, force_runtime, non_null_comptime); + value, force_runtime, non_null_comptime, allow_discard); if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value->type))) return result_loc; @@ -16496,7 +16350,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && - value_type->id != ZigTypeIdNull) + value_type->id != ZigTypeIdNull && value == nullptr) { result_loc_pass1->written = false; return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); @@ -16514,9 +16368,6 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s return unwrapped_err_ptr; } } - } else if (is_slice(actual_elem_type) && value_type->id == ZigTypeIdArray) { - // need to allow EndExpr to do the implicit cast from array to slice - result_loc_pass1->written = false; } return result_loc; } @@ -17520,11 +17371,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { ir_reset_result(call_instruction->result_loc); result_loc = nullptr; - } else { - call_instruction->base.value.type = impl_fn_type_id->return_type; - IrInstruction *casted_value = ir_implicit_cast(ira, &call_instruction->base, result_loc->value.type->data.pointer.child_type); - if (type_is_invalid(casted_value->value.type)) - return casted_value; } } } else if (call_instruction->is_async_call_builtin) { @@ -17687,11 +17533,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c if (!handle_is_ptr(result_loc->value->type->data.pointer.child_type)) { ir_reset_result(call_instruction->result_loc); result_loc = nullptr; - } else { - call_instruction->base.value.type = return_type; - IrInstruction *casted_value = ir_implicit_cast(ira, &call_instruction->base, result_loc->value.type->data.pointer.child_type); - if (type_is_invalid(casted_value->value.type)) - return casted_value; } } } else if (call_instruction->is_async_call_builtin) { @@ -21041,6 +20882,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, { // We're now done inferring the type. container_type->data.structure.resolve_status = ResolveStatusUnstarted; + } else if (container_type->id == ZigTypeIdVector) { + // OK } else { ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("type '%s' does not support array initialization", @@ -22434,17 +22277,23 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, return result; } -static ZigValue *get_const_field(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, + const char *name, size_t field_index) { + Error err; ensure_field_index(struct_value->type, name, field_index); - assert(struct_value->data.x_struct.fields[field_index]->special == ConstValSpecialStatic); - return struct_value->data.x_struct.fields[field_index]; + ZigValue *val = struct_value->data.x_struct.fields[field_index]; + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad))) + return nullptr; + return val; } static Error get_const_field_sentinel(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *struct_value, const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) { - ZigValue *field_val = get_const_field(ira, struct_value, name, field_index); + ZigValue *field_val = get_const_field(ira, source_instr->source_node, struct_value, name, field_index); + if (field_val == nullptr) + return ErrorSemanticAnalyzeFail; IrInstruction *field_inst = ir_const(ira, source_instr, field_val->type); IrInstruction *casted_field_inst = ir_implicit_cast(ira, field_inst, get_optional_type(ira->codegen, elem_type)); @@ -22455,23 +22304,31 @@ static Error get_const_field_sentinel(IrAnalyze *ira, IrInstruction *source_inst return ErrorNone; } -static bool get_const_field_bool(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, + const char *name, size_t field_index, bool *out) { - ZigValue *value = get_const_field(ira, struct_value, name, field_index); + ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); + if (value == nullptr) + return ErrorSemanticAnalyzeFail; assert(value->type == ira->codegen->builtin_types.entry_bool); - return value->data.x_bool; + *out = value->data.x_bool; + return ErrorNone; } -static BigInt *get_const_field_lit_int(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) { - ZigValue *value = get_const_field(ira, struct_value, name, field_index); + ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); + if (value == nullptr) + return nullptr; assert(value->type == ira->codegen->builtin_types.entry_num_lit_int); return &value->data.x_bigint; } -static ZigType *get_const_field_meta_type(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) { - ZigValue *value = get_const_field(ira, struct_value, name, field_index); + ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); + if (value == nullptr) + return ira->codegen->invalid_instruction->value->type; assert(value->type == ira->codegen->builtin_types.entry_type); return value->data.x_type; } @@ -22489,17 +22346,25 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi return ira->codegen->builtin_types.entry_bool; case ZigTypeIdUnreachable: return ira->codegen->builtin_types.entry_unreachable; - case ZigTypeIdInt: + case ZigTypeIdInt: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); - return get_int_type(ira->codegen, - get_const_field_bool(ira, payload, "is_signed", 0), - bigint_as_u32(get_const_field_lit_int(ira, payload, "bits", 1))); + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 1); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + bool is_signed; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_signed", 0, &is_signed))) + return ira->codegen->invalid_instruction->value->type; + return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); + } case ZigTypeIdFloat: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); - uint32_t bits = bigint_as_u32(get_const_field_lit_int(ira, payload, "bits", 0)); + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 0); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + uint32_t bits = bigint_as_u32(bi); switch (bits) { case 16: return ira->codegen->builtin_types.entry_f16; case 32: return ira->codegen->builtin_types.entry_f32; @@ -22515,27 +22380,51 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); assert(payload->special == ConstValSpecialStatic); assert(payload->type == type_info_pointer_type); - ZigValue *size_value = get_const_field(ira, payload, "size", 0); + ZigValue *size_value = get_const_field(ira, instruction->source_node, payload, "size", 0); assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); - ZigType *elem_type = get_const_field_meta_type(ira, payload, "child", 4); + ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 4); + if (type_is_invalid(elem_type)) + return ira->codegen->invalid_instruction->value->type; ZigValue *sentinel; if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 6, elem_type, &sentinel))) { - return nullptr; + return ira->codegen->invalid_instruction->value->type; } + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "alignment", 3); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + + bool is_const; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_const", 1, &is_const))) + return ira->codegen->invalid_instruction->value->type; + + bool is_volatile; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_volatile", 2, + &is_volatile))) + { + return ira->codegen->invalid_instruction->value->type; + } + + bool is_allowzero; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_allowzero", 5, + &is_allowzero))) + { + return ira->codegen->invalid_instruction->value->type; + } + ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, - get_const_field_bool(ira, payload, "is_const", 1), - get_const_field_bool(ira, payload, "is_volatile", 2), + is_const, + is_volatile, ptr_len, - bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)), + bigint_as_u32(bi), 0, // bit_offset_in_host 0, // host_int_bytes - get_const_field_bool(ira, payload, "is_allowzero", 5), + is_allowzero, VECTOR_INDEX_NONE, nullptr, sentinel); if (size_enum_index != 2) return ptr_type; @@ -22544,17 +22433,19 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdArray: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Array", nullptr)); - ZigType *elem_type = get_const_field_meta_type(ira, payload, "child", 1); + ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 1); + if (type_is_invalid(elem_type)) + return ira->codegen->invalid_instruction->value->type; ZigValue *sentinel; if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 2, elem_type, &sentinel))) { - return nullptr; + return ira->codegen->invalid_instruction->value->type; } - return get_array_type(ira->codegen, - elem_type, - bigint_as_u64(get_const_field_lit_int(ira, payload, "len", 0)), - sentinel); + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "len", 0); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel); } case ZigTypeIdComptimeFloat: return ira->codegen->builtin_types.entry_num_lit_float; @@ -22575,7 +22466,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdEnumLiteral: ir_add_error(ira, instruction, buf_sprintf( "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); - return nullptr; + return ira->codegen->invalid_instruction->value->type; case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdBoundFn: @@ -22583,7 +22474,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdStruct: ir_add_error(ira, instruction, buf_sprintf( "@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId))); - return nullptr; + return ira->codegen->invalid_instruction->value->type; } zig_unreachable(); } @@ -22602,7 +22493,7 @@ static IrInstruction *ir_analyze_instruction_type(IrAnalyze *ira, IrInstructionT return ira->codegen->invalid_instruction; ZigTypeId typeId = type_id_at_index(bigint_as_usize(&type_info_value->data.x_union.tag)); ZigType *type = type_info_to_type(ira, type_info_ir, typeId, type_info_value->data.x_union.payload); - if (!type) + if (type_is_invalid(type)) return ira->codegen->invalid_instruction; return ir_const_type(ira, &instruction->base, type); } @@ -28332,3 +28223,18 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { } return ErrorNone; } + +void IrInstruction::dump() { + IrInstruction *inst = this; + if (inst->source_node != nullptr) { + inst->source_node->src(); + } else { + fprintf(stderr, "(null source node)\n"); + } + IrPass pass = (inst->child == nullptr) ? IrPassGen : IrPassSrc; + ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); + if (pass == IrPassSrc) { + fprintf(stderr, "-> "); + ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); + } +} diff --git a/test/compare_output.zig b/test/compare_output.zig index 1535d0ae5236ec5fd974d54fc256b71ef1ef65f2..03f71d380e92e44e6eb3f9045a4450a1162be835 100644 --- a/test/compare_output.zig +++ b/test/compare_output.zig @@ -465,7 +465,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ ); - tc.setCommandLineArgs([_][]const u8{ + tc.setCommandLineArgs(&[_][]const u8{ "first arg", "'a' 'b' \\", "bare", @@ -506,7 +506,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ ); - tc.setCommandLineArgs([_][]const u8{ + tc.setCommandLineArgs(&[_][]const u8{ "first arg", "'a' 'b' \\", "bare", diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 47e74cd310c3a94d4c2fe83e5cce719239d4b798..1d51f822d07ea5631ff43cab1c2751bb506e7cef 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -20,7 +20,7 @@ test "arrays" { } expect(accumulator == 15); - expect(getArrayLen(array) == 5); + expect(getArrayLen(&array) == 5); } fn getArrayLen(a: []const u32) usize { return a.len; @@ -182,29 +182,29 @@ fn plusOne(x: u32) u32 { test "runtime initialize array elem and then implicit cast to slice" { var two: i32 = 2; - const x: []const i32 = [_]i32{two}; + const x: []const i32 = &[_]i32{two}; expect(x[0] == 2); } test "array literal as argument to function" { const S = struct { fn entry(two: i32) void { - foo([_]i32{ + foo(&[_]i32{ 1, 2, 3, }); - foo([_]i32{ + foo(&[_]i32{ 1, two, 3, }); - foo2(true, [_]i32{ + foo2(true, &[_]i32{ 1, 2, 3, }); - foo2(true, [_]i32{ + foo2(true, &[_]i32{ 1, two, 3, @@ -230,17 +230,17 @@ test "double nested array to const slice cast in array literal" { const S = struct { fn entry(two: i32) void { const cases = [_][]const []const i32{ - [_][]const i32{[_]i32{1}}, - [_][]const i32{[_]i32{ 2, 3 }}, - [_][]const i32{ - [_]i32{4}, - [_]i32{ 5, 6, 7 }, + &[_][]const i32{&[_]i32{1}}, + &[_][]const i32{&[_]i32{ 2, 3 }}, + &[_][]const i32{ + &[_]i32{4}, + &[_]i32{ 5, 6, 7 }, }, }; - check(cases); + check(&cases); const cases2 = [_][]const i32{ - [_]i32{1}, + &[_]i32{1}, &[_]i32{ two, 3 }, }; expect(cases2.len == 2); @@ -251,14 +251,14 @@ test "double nested array to const slice cast in array literal" { expect(cases2[1][1] == 3); const cases3 = [_][]const []const i32{ - [_][]const i32{[_]i32{1}}, + &[_][]const i32{&[_]i32{1}}, &[_][]const i32{&[_]i32{ two, 3 }}, - [_][]const i32{ - [_]i32{4}, - [_]i32{ 5, 6, 7 }, + &[_][]const i32{ + &[_]i32{4}, + &[_]i32{ 5, 6, 7 }, }, }; - check(cases3); + check(&cases3); } fn check(cases: []const []const []const i32) void { @@ -316,7 +316,7 @@ test "implicit cast zero sized array ptr to slice" { test "anonymous list literal syntax" { const S = struct { fn doTheTest() void { - var array: [4]u8 = .{1, 2, 3, 4}; + var array: [4]u8 = .{ 1, 2, 3, 4 }; expect(array[0] == 1); expect(array[1] == 2); expect(array[2] == 3); @@ -335,8 +335,8 @@ test "anonymous literal in array" { }; fn doTheTest() void { var array: [2]Foo = .{ - .{.a = 3}, - .{.b = 3}, + .{ .a = 3 }, + .{ .b = 3 }, }; expect(array[0].a == 3); expect(array[0].b == 4); @@ -351,7 +351,7 @@ test "anonymous literal in array" { test "access the null element of a null terminated array" { const S = struct { fn doTheTest() void { - var array: [4:0]u8 = .{'a', 'o', 'e', 'u'}; + var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; comptime expect(array[4] == 0); var len: usize = 4; expect(array[len] == 0); diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig index 67411601da1619397fd2b5d9d9495b2f633f08ed..78db00cc083c95eb16aba01c1b4e9044fea84e33 100644 --- a/test/stage1/behavior/async_fn.zig +++ b/test/stage1/behavior/async_fn.zig @@ -143,7 +143,7 @@ test "coroutine suspend, resume" { resume frame; seq('h'); - expect(std.mem.eql(u8, points, "abcdefgh")); + expect(std.mem.eql(u8, &points, "abcdefgh")); } fn amain() void { @@ -206,7 +206,7 @@ test "coroutine await" { resume await_a_promise; await_seq('i'); expect(await_final_result == 1234); - expect(std.mem.eql(u8, await_points, "abcdefghi")); + expect(std.mem.eql(u8, &await_points, "abcdefghi")); } async fn await_amain() void { await_seq('b'); @@ -240,7 +240,7 @@ test "coroutine await early return" { var p = async early_amain(); early_seq('f'); expect(early_final_result == 1234); - expect(std.mem.eql(u8, early_points, "abcdef")); + expect(std.mem.eql(u8, &early_points, "abcdef")); } async fn early_amain() void { early_seq('b'); @@ -1166,7 +1166,7 @@ test "suspend in for loop" { } fn atest() void { - expect(func([_]u8{ 1, 2, 3 }) == 6); + expect(func(&[_]u8{ 1, 2, 3 }) == 6); } fn func(stuff: []const u8) u32 { global_frame = @frame(); @@ -1211,7 +1211,7 @@ test "spill target expr in a for loop" { fn doTheTest() void { var foo = Foo{ - .slice = [_]i32{ 1, 2 }, + .slice = &[_]i32{ 1, 2 }, }; expect(atest(&foo) == 3); } @@ -1242,7 +1242,7 @@ test "spill target expr in a for loop, with a var decl in the loop body" { fn doTheTest() void { var foo = Foo{ - .slice = [_]i32{ 1, 2 }, + .slice = &[_]i32{ 1, 2 }, }; expect(atest(&foo) == 3); } diff --git a/test/stage1/behavior/await_struct.zig b/test/stage1/behavior/await_struct.zig index 6e4d330ea3b84f3fb3bfaf1f7f7bea93cf797178..2d4faadc27baaf5e17d6a5e18096d563d56c6f82 100644 --- a/test/stage1/behavior/await_struct.zig +++ b/test/stage1/behavior/await_struct.zig @@ -16,7 +16,7 @@ test "coroutine await struct" { resume await_a_promise; await_seq('i'); expect(await_final_result.x == 1234); - expect(std.mem.eql(u8, await_points, "abcdefghi")); + expect(std.mem.eql(u8, &await_points, "abcdefghi")); } async fn await_amain() void { await_seq('b'); diff --git a/test/stage1/behavior/bugs/1607.zig b/test/stage1/behavior/bugs/1607.zig index 3a1de80a86996b2c8d012b7ae2421b376216c2de..ffc1aa85dc0527b1ccf339efb2af325ca84bd1ab 100644 --- a/test/stage1/behavior/bugs/1607.zig +++ b/test/stage1/behavior/bugs/1607.zig @@ -10,6 +10,6 @@ fn checkAddress(s: []const u8) void { } test "slices pointing at the same address as global array." { - checkAddress(a); - comptime checkAddress(a); + checkAddress(&a); + comptime checkAddress(&a); } diff --git a/test/stage1/behavior/bugs/1914.zig b/test/stage1/behavior/bugs/1914.zig index 22269590d9069f41aca577843cfd94c7de884bb7..2c9e836e6a5ebb83a5cf86415fb1e2f72b4c2916 100644 --- a/test/stage1/behavior/bugs/1914.zig +++ b/test/stage1/behavior/bugs/1914.zig @@ -7,7 +7,7 @@ const B = struct { a_pointer: *const A, }; -const b_list: []B = [_]B{}; +const b_list: []B = &[_]B{}; const a = A{ .b_list_pointer = &b_list }; test "segfault bug" { @@ -24,7 +24,7 @@ pub const B2 = struct { pointer_array: []*A2, }; -var b_value = B2{ .pointer_array = [_]*A2{} }; +var b_value = B2{ .pointer_array = &[_]*A2{} }; test "basic stuff" { std.debug.assert(&b_value == &b_value); diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index fec4494ad9f01a29fd658eae19ebc6c129d64b41..ba538a0ebba852b0161eb7d44cf2bccda70b92f3 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -150,7 +150,7 @@ test "peer type resolution: [0]u8 and []const u8" { } fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { if (a) { - return [_]u8{}; + return &[_]u8{}; } return slice[0..1]; @@ -175,7 +175,7 @@ fn testCastZeroArrayToErrSliceMut() void { } fn gimmeErrOrSlice() anyerror![]u8 { - return [_]u8{}; + return &[_]u8{}; } test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { @@ -200,7 +200,7 @@ test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { } fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 { if (a) { - return [_]u8{}; + return &[_]u8{}; } return slice[0..1]; @@ -457,7 +457,7 @@ fn incrementVoidPtrValue(value: ?*c_void) void { test "implicit cast from [*]T to ?*c_void" { var a = [_]u8{ 3, 2, 1 }; incrementVoidPtrArray(a[0..].ptr, 3); - expect(std.mem.eql(u8, a, [_]u8{ 4, 3, 2 })); + expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); } fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { @@ -606,7 +606,12 @@ test "*const [N]null u8 to ?[]const u8" { test "peer resolution of string literals" { const S = struct { - const E = extern enum { a, b, c, d}; + const E = extern enum { + a, + b, + c, + d, + }; fn doTheTest(e: E) void { const cmd = switch (e) { @@ -627,15 +632,15 @@ test "type coercion related to sentinel-termination" { fn doTheTest() void { // [:x]T to []T { - var array = [4:0]i32{1,2,3,4}; + var array = [4:0]i32{ 1, 2, 3, 4 }; var slice: [:0]i32 = &array; var dest: []i32 = slice; - expect(mem.eql(i32, dest, &[_]i32{1,2,3,4})); + expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); } // [*:x]T to [*]T { - var array = [4:99]i32{1,2,3,4}; + var array = [4:99]i32{ 1, 2, 3, 4 }; var dest: [*]i32 = &array; expect(dest[0] == 1); expect(dest[1] == 2); @@ -646,21 +651,21 @@ test "type coercion related to sentinel-termination" { // [N:x]T to [N]T { - var array = [4:0]i32{1,2,3,4}; + var array = [4:0]i32{ 1, 2, 3, 4 }; var dest: [4]i32 = array; - expect(mem.eql(i32, dest, &[_]i32{1,2,3,4})); + expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 })); } // *[N:x]T to *[N]T { - var array = [4:0]i32{1,2,3,4}; + var array = [4:0]i32{ 1, 2, 3, 4 }; var dest: *[4]i32 = &array; - expect(mem.eql(i32, dest, &[_]i32{1,2,3,4})); + expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); } // [:x]T to [*:x]T { - var array = [4:0]i32{1,2,3,4}; + var array = [4:0]i32{ 1, 2, 3, 4 }; var slice: [:0]i32 = &array; var dest: [*:0]i32 = slice; expect(dest[0] == 1); @@ -674,3 +679,21 @@ test "type coercion related to sentinel-termination" { S.doTheTest(); comptime S.doTheTest(); } + +test "cast i8 fn call peers to i32 result" { + const S = struct { + fn doTheTest() void { + var cond = true; + const value: i32 = if (cond) smallBoi() else bigBoi(); + expect(value == 123); + } + fn smallBoi() i8 { + return 123; + } + fn bigBoi() i16 { + return 1234; + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig index b7bce26568fa256dbb33e7ea86560645966c437f..be7226d94ce408eeffadeea2d0b498c42061c418 100644 --- a/test/stage1/behavior/eval.zig +++ b/test/stage1/behavior/eval.zig @@ -717,7 +717,7 @@ test "@bytesToslice on a packed struct" { }; var b = [1]u8{9}; - var f = @bytesToSlice(F, b); + var f = @bytesToSlice(F, &b); expect(f[0].a == 9); } @@ -774,12 +774,12 @@ test "*align(1) u16 is the same as *align(1:0:2) u16" { test "array concatenation forces comptime" { var a = oneItem(3) ++ oneItem(4); - expect(std.mem.eql(i32, a, [_]i32{ 3, 4 })); + expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 })); } test "array multiplication forces comptime" { var a = oneItem(3) ** scalar(2); - expect(std.mem.eql(i32, a, [_]i32{ 3, 3 })); + expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 })); } fn oneItem(x: i32) [1]i32 { diff --git a/test/stage1/behavior/for.zig b/test/stage1/behavior/for.zig index cfa68bd216831a2e30f28055d3889127dcc0f7aa..5cf75ed497f806d877c5bf24fc6bcf08850c0479 100644 --- a/test/stage1/behavior/for.zig +++ b/test/stage1/behavior/for.zig @@ -26,7 +26,7 @@ test "for loop with pointer elem var" { var target: [source.len]u8 = undefined; mem.copy(u8, target[0..], source); mangleString(target[0..]); - expect(mem.eql(u8, target, "bcdefgh")); + expect(mem.eql(u8, &target, "bcdefgh")); for (source) |*c, i| expect(@typeOf(c) == *const u8); @@ -64,7 +64,7 @@ test "basic for loop" { buffer[buf_index] = @intCast(u8, index); buf_index += 1; } - const unknown_size: []const u8 = array; + const unknown_size: []const u8 = &array; for (unknown_size) |item| { buffer[buf_index] = item; buf_index += 1; @@ -74,7 +74,7 @@ test "basic for loop" { buf_index += 1; } - expect(mem.eql(u8, buffer[0..buf_index], expected_result)); + expect(mem.eql(u8, buffer[0..buf_index], &expected_result)); } test "break from outer for loop" { @@ -139,6 +139,6 @@ test "for with null and T peer types and inferred result location type" { } } }; - S.doTheTest([_]u8{ 1, 2 }); - comptime S.doTheTest([_]u8{ 1, 2 }); + S.doTheTest(&[_]u8{ 1, 2 }); + comptime S.doTheTest(&[_]u8{ 1, 2 }); } diff --git a/test/stage1/behavior/generics.zig b/test/stage1/behavior/generics.zig index 664b982c21af51c788384c68080c677371cf15e8..dc15ae1b8c1084e60d46d4051f6bf627ce497ce7 100644 --- a/test/stage1/behavior/generics.zig +++ b/test/stage1/behavior/generics.zig @@ -120,8 +120,8 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) T { } test "generic fn with implicit cast" { - expect(getFirstByte(u8, [_]u8{13}) == 13); - expect(getFirstByte(u16, [_]u16{ + expect(getFirstByte(u8, &[_]u8{13}) == 13); + expect(getFirstByte(u16, &[_]u16{ 0, 13, }) == 0); diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index 6ac745f5c50b478102eb59e505cc3e0318230c8c..a3da752f0d663c1dd9fa4d13427e62dde9fba322 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -241,7 +241,7 @@ fn memFree(comptime T: type, memory: []T) void {} test "cast undefined" { const array: [100]u8 = undefined; - const slice = @as([]const u8, array); + const slice = @as([]const u8, &array); testCastUndefined(slice); } fn testCastUndefined(x: []const u8) void {} @@ -614,7 +614,7 @@ test "slicing zero length array" { expect(s1.len == 0); expect(s2.len == 0); expect(mem.eql(u8, s1, "")); - expect(mem.eql(u32, s2, [_]u32{})); + expect(mem.eql(u32, s2, &[_]u32{})); } const addr1 = @ptrCast(*const u8, emptyFn); @@ -710,7 +710,7 @@ test "result location zero sized array inside struct field implicit cast to slic const E = struct { entries: []u32, }; - var foo = E{ .entries = [_]u32{} }; + var foo = E{ .entries = &[_]u32{} }; expect(foo.entries.len == 0); } diff --git a/test/stage1/behavior/ptrcast.zig b/test/stage1/behavior/ptrcast.zig index ddb5a63eeeb5d05896216ce04138f976e04f21f2..4c17b38e6e9e41af86a9daae50076378d049a245 100644 --- a/test/stage1/behavior/ptrcast.zig +++ b/test/stage1/behavior/ptrcast.zig @@ -37,7 +37,7 @@ fn testReinterpretBytesAsExternStruct() void { test "reinterpret struct field at comptime" { const numLittle = comptime Bytes.init(0x12345678); - expect(std.mem.eql(u8, [_]u8{ 0x78, 0x56, 0x34, 0x12 }, numLittle.bytes)); + expect(std.mem.eql(u8, &[_]u8{ 0x78, 0x56, 0x34, 0x12 }, &numLittle.bytes)); } const Bytes = struct { diff --git a/test/stage1/behavior/shuffle.zig b/test/stage1/behavior/shuffle.zig index 1985c8dc76abae31adefdb4e8a84e85834a81461..2189b3e0e1be17fef9bad84200fc95f50af09545 100644 --- a/test/stage1/behavior/shuffle.zig +++ b/test/stage1/behavior/shuffle.zig @@ -9,28 +9,28 @@ test "@shuffle" { var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 }; const mask: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) }; var res = @shuffle(i32, v, x, mask); - expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 40, 4 })); + expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 })); // Implicit cast from array (of mask) res = @shuffle(i32, v, x, [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) }); - expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 40, 4 })); + expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 })); // Undefined const mask2: @Vector(4, i32) = [4]i32{ 3, 1, 2, 0 }; res = @shuffle(i32, v, undefined, mask2); - expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 40, -2, 30, 2147483647 })); + expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 40, -2, 30, 2147483647 })); // Upcasting of b var v2: @Vector(2, i32) = [2]i32{ 2147483647, undefined }; const mask3: @Vector(4, i32) = [4]i32{ ~@as(i32, 0), 2, ~@as(i32, 0), 3 }; res = @shuffle(i32, x, v2, mask3); - expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 2147483647, 4 })); + expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 2147483647, 4 })); // Upcasting of a var v3: @Vector(2, i32) = [2]i32{ 2147483647, -2 }; const mask4: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 1, ~@as(i32, 3) }; res = @shuffle(i32, v3, x, mask4); - expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, -2, 4 })); + expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, -2, 4 })); // bool // Disabled because of #3317 @@ -39,7 +39,7 @@ test "@shuffle" { var v4: @Vector(2, bool) = [2]bool{ true, false }; const mask5: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; var res2 = @shuffle(bool, x2, v4, mask5); - expect(mem.eql(bool, @as([4]bool,res2), [4]bool{ false, false, true, false })); + expect(mem.eql(bool, &@as([4]bool, res2), &[4]bool{ false, false, true, false })); } // TODO re-enable when LLVM codegen is fixed @@ -49,7 +49,7 @@ test "@shuffle" { var v4: @Vector(2, bool) = [2]bool{ true, false }; const mask5: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; var res2 = @shuffle(bool, x2, v4, mask5); - expect(mem.eql(bool, @as([4]bool,res2), [4]bool{ false, false, true, false })); + expect(mem.eql(bool, &@as([4]bool, res2), &[4]bool{ false, false, true, false })); } } }; diff --git a/test/stage1/behavior/slice.zig b/test/stage1/behavior/slice.zig index 3c394e39a164fa2780fd45280a2dd1531153e8c5..e325c6c8c8509403529538cff9e7722ae3d6fff7 100644 --- a/test/stage1/behavior/slice.zig +++ b/test/stage1/behavior/slice.zig @@ -28,7 +28,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { test "implicitly cast array of size 0 to slice" { var msg = [_]u8{}; - assertLenIsZero(msg); + assertLenIsZero(&msg); } fn assertLenIsZero(msg: []const u8) void { @@ -51,8 +51,8 @@ fn sliceSum(comptime q: []const u8) i32 { } test "comptime slices are disambiguated" { - expect(sliceSum([_]u8{ 1, 2 }) == 3); - expect(sliceSum([_]u8{ 3, 4 }) == 7); + expect(sliceSum(&[_]u8{ 1, 2 }) == 3); + expect(sliceSum(&[_]u8{ 3, 4 }) == 7); } test "slice type with custom alignment" { diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index 7c2e58f2cb68b5fb30d698a91db1feeb0a6d0e49..408f5da6872696f0473bf5547e385db070e82911 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -184,7 +184,7 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 { } test "pass slice of empty struct to fn" { - expect(testPassSliceOfEmptyStructToFn([_]EmptyStruct2{EmptyStruct2{}}) == 1); + expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); } fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { return slice.len; @@ -432,7 +432,7 @@ const Expr = union(enum) { }; fn alloc(comptime T: type) []T { - return [_]T{}; + return &[_]T{}; } test "call method with mutable reference to struct with no fields" { @@ -495,7 +495,8 @@ test "non-byte-aligned array inside packed struct" { .a = true, .b = "abcdefghijklmnopqurstu".*, }; - bar(foo.b); + const value = foo.b; + bar(&value); } }; S.doTheTest(); @@ -783,7 +784,7 @@ test "struct with var field" { x: var, y: var, }; - const pt = Point { + const pt = Point{ .x = 1, .y = 2, }; diff --git a/test/stage1/behavior/struct_contains_slice_of_itself.zig b/test/stage1/behavior/struct_contains_slice_of_itself.zig index 2f3b5f41df645e2de36ab22c075e833c6dae7327..14bf0320a228b70fb169535658488f8192465e54 100644 --- a/test/stage1/behavior/struct_contains_slice_of_itself.zig +++ b/test/stage1/behavior/struct_contains_slice_of_itself.zig @@ -14,21 +14,21 @@ test "struct contains slice of itself" { var other_nodes = [_]Node{ Node{ .payload = 31, - .children = [_]Node{}, + .children = &[_]Node{}, }, Node{ .payload = 32, - .children = [_]Node{}, + .children = &[_]Node{}, }, }; var nodes = [_]Node{ Node{ .payload = 1, - .children = [_]Node{}, + .children = &[_]Node{}, }, Node{ .payload = 2, - .children = [_]Node{}, + .children = &[_]Node{}, }, Node{ .payload = 3, @@ -51,21 +51,21 @@ test "struct contains aligned slice of itself" { var other_nodes = [_]NodeAligned{ NodeAligned{ .payload = 31, - .children = [_]NodeAligned{}, + .children = &[_]NodeAligned{}, }, NodeAligned{ .payload = 32, - .children = [_]NodeAligned{}, + .children = &[_]NodeAligned{}, }, }; var nodes = [_]NodeAligned{ NodeAligned{ .payload = 1, - .children = [_]NodeAligned{}, + .children = &[_]NodeAligned{}, }, NodeAligned{ .payload = 2, - .children = [_]NodeAligned{}, + .children = &[_]NodeAligned{}, }, NodeAligned{ .payload = 3, diff --git a/test/stage1/behavior/type.zig b/test/stage1/behavior/type.zig index f083359d1d57a44d9d1da3ae99423d244eb74cfe..432a1e0e94541b7cae574b751d7ac4299466bd10 100644 --- a/test/stage1/behavior/type.zig +++ b/test/stage1/behavior/type.zig @@ -12,22 +12,22 @@ fn testTypes(comptime types: []const type) void { test "Type.MetaType" { testing.expect(type == @Type(TypeInfo{ .Type = undefined })); - testTypes([_]type{type}); + testTypes(&[_]type{type}); } test "Type.Void" { testing.expect(void == @Type(TypeInfo{ .Void = undefined })); - testTypes([_]type{void}); + testTypes(&[_]type{void}); } test "Type.Bool" { testing.expect(bool == @Type(TypeInfo{ .Bool = undefined })); - testTypes([_]type{bool}); + testTypes(&[_]type{bool}); } test "Type.NoReturn" { testing.expect(noreturn == @Type(TypeInfo{ .NoReturn = undefined })); - testTypes([_]type{noreturn}); + testTypes(&[_]type{noreturn}); } test "Type.Int" { @@ -37,7 +37,7 @@ test "Type.Int" { testing.expect(i8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = true, .bits = 8 } })); testing.expect(u64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = false, .bits = 64 } })); testing.expect(i64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .is_signed = true, .bits = 64 } })); - testTypes([_]type{ u8, u32, i64 }); + testTypes(&[_]type{ u8, u32, i64 }); } test "Type.Float" { @@ -45,11 +45,11 @@ test "Type.Float" { testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } })); testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } })); testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } })); - testTypes([_]type{ f16, f32, f64, f128 }); + testTypes(&[_]type{ f16, f32, f64, f128 }); } test "Type.Pointer" { - testTypes([_]type{ + testTypes(&[_]type{ // One Value Pointer Types *u8, *const u8, *volatile u8, *const volatile u8, @@ -115,18 +115,18 @@ test "Type.Array" { .sentinel = 0, }, })); - testTypes([_]type{ [1]u8, [30]usize, [7]bool }); + testTypes(&[_]type{ [1]u8, [30]usize, [7]bool }); } test "Type.ComptimeFloat" { - testTypes([_]type{comptime_float}); + testTypes(&[_]type{comptime_float}); } test "Type.ComptimeInt" { - testTypes([_]type{comptime_int}); + testTypes(&[_]type{comptime_int}); } test "Type.Undefined" { - testTypes([_]type{@typeOf(undefined)}); + testTypes(&[_]type{@typeOf(undefined)}); } test "Type.Null" { - testTypes([_]type{@typeOf(null)}); + testTypes(&[_]type{@typeOf(null)}); } diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index d7481b21c71dd7b71963e7bed8cc519109e4180e..43b26b79b89d9366de5e368d67e76e0a359305ec 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -241,7 +241,7 @@ pub const PackThis = union(enum) { }; test "constant packed union" { - testConstPackedUnion([_]PackThis{PackThis{ .StringLiteral = 1 }}); + testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }}); } fn testConstPackedUnion(expected_tokens: []const PackThis) void { diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig index f7b98b294f8135a28658cceb5e596497301ef995..b6033ea66057e4755418436303f88eeb784e5ade 100644 --- a/test/stage1/behavior/vector.zig +++ b/test/stage1/behavior/vector.zig @@ -8,7 +8,7 @@ test "implicit cast vector to array - bool" { fn doTheTest() void { const a: @Vector(4, bool) = [_]bool{ true, false, true, false }; const result_array: [4]bool = a; - expect(mem.eql(bool, result_array, [4]bool{ true, false, true, false })); + expect(mem.eql(bool, &result_array, &[4]bool{ true, false, true, false })); } }; S.doTheTest(); @@ -20,11 +20,11 @@ test "vector wrap operators" { fn doTheTest() void { var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 }; - expect(mem.eql(i32, @as([4]i32, v +% x), [4]i32{ -2147483648, 2147483645, 33, 44 })); - expect(mem.eql(i32, @as([4]i32, v -% x), [4]i32{ 2147483646, 2147483647, 27, 36 })); - expect(mem.eql(i32, @as([4]i32, v *% x), [4]i32{ 2147483647, 2, 90, 160 })); + expect(mem.eql(i32, &@as([4]i32, v +% x), &[4]i32{ -2147483648, 2147483645, 33, 44 })); + expect(mem.eql(i32, &@as([4]i32, v -% x), &[4]i32{ 2147483646, 2147483647, 27, 36 })); + expect(mem.eql(i32, &@as([4]i32, v *% x), &[4]i32{ 2147483647, 2, 90, 160 })); var z: @Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 }; - expect(mem.eql(i32, @as([4]i32, -%z), [4]i32{ -1, -2, -3, -2147483648 })); + expect(mem.eql(i32, &@as([4]i32, -%z), &[4]i32{ -1, -2, -3, -2147483648 })); } }; S.doTheTest(); @@ -36,12 +36,12 @@ test "vector bin compares with mem.eql" { fn doTheTest() void { var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 }; - expect(mem.eql(bool, @as([4]bool, v == x), [4]bool{ false, false, true, false })); - expect(mem.eql(bool, @as([4]bool, v != x), [4]bool{ true, true, false, true })); - expect(mem.eql(bool, @as([4]bool, v < x), [4]bool{ false, true, false, false })); - expect(mem.eql(bool, @as([4]bool, v > x), [4]bool{ true, false, false, true })); - expect(mem.eql(bool, @as([4]bool, v <= x), [4]bool{ false, true, true, false })); - expect(mem.eql(bool, @as([4]bool, v >= x), [4]bool{ true, false, true, true })); + expect(mem.eql(bool, &@as([4]bool, v == x), &[4]bool{ false, false, true, false })); + expect(mem.eql(bool, &@as([4]bool, v != x), &[4]bool{ true, true, false, true })); + expect(mem.eql(bool, &@as([4]bool, v < x), &[4]bool{ false, true, false, false })); + expect(mem.eql(bool, &@as([4]bool, v > x), &[4]bool{ true, false, false, true })); + expect(mem.eql(bool, &@as([4]bool, v <= x), &[4]bool{ false, true, true, false })); + expect(mem.eql(bool, &@as([4]bool, v >= x), &[4]bool{ true, false, true, true })); } }; S.doTheTest(); @@ -53,10 +53,10 @@ test "vector int operators" { fn doTheTest() void { var v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 }; var x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 }; - expect(mem.eql(i32, @as([4]i32, v + x), [4]i32{ 11, 22, 33, 44 })); - expect(mem.eql(i32, @as([4]i32, v - x), [4]i32{ 9, 18, 27, 36 })); - expect(mem.eql(i32, @as([4]i32, v * x), [4]i32{ 10, 40, 90, 160 })); - expect(mem.eql(i32, @as([4]i32, -v), [4]i32{ -10, -20, -30, -40 })); + expect(mem.eql(i32, &@as([4]i32, v + x), &[4]i32{ 11, 22, 33, 44 })); + expect(mem.eql(i32, &@as([4]i32, v - x), &[4]i32{ 9, 18, 27, 36 })); + expect(mem.eql(i32, &@as([4]i32, v * x), &[4]i32{ 10, 40, 90, 160 })); + expect(mem.eql(i32, &@as([4]i32, -v), &[4]i32{ -10, -20, -30, -40 })); } }; S.doTheTest(); @@ -68,10 +68,10 @@ test "vector float operators" { fn doTheTest() void { var v: @Vector(4, f32) = [4]f32{ 10, 20, 30, 40 }; var x: @Vector(4, f32) = [4]f32{ 1, 2, 3, 4 }; - expect(mem.eql(f32, @as([4]f32, v + x), [4]f32{ 11, 22, 33, 44 })); - expect(mem.eql(f32, @as([4]f32, v - x), [4]f32{ 9, 18, 27, 36 })); - expect(mem.eql(f32, @as([4]f32, v * x), [4]f32{ 10, 40, 90, 160 })); - expect(mem.eql(f32, @as([4]f32, -x), [4]f32{ -1, -2, -3, -4 })); + expect(mem.eql(f32, &@as([4]f32, v + x), &[4]f32{ 11, 22, 33, 44 })); + expect(mem.eql(f32, &@as([4]f32, v - x), &[4]f32{ 9, 18, 27, 36 })); + expect(mem.eql(f32, &@as([4]f32, v * x), &[4]f32{ 10, 40, 90, 160 })); + expect(mem.eql(f32, &@as([4]f32, -x), &[4]f32{ -1, -2, -3, -4 })); } }; S.doTheTest(); @@ -83,9 +83,9 @@ test "vector bit operators" { fn doTheTest() void { var v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 }; var x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 }; - expect(mem.eql(u8, @as([4]u8, v ^ x), [4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 })); - expect(mem.eql(u8, @as([4]u8, v | x), [4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 })); - expect(mem.eql(u8, @as([4]u8, v & x), [4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 })); + expect(mem.eql(u8, &@as([4]u8, v ^ x), &[4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 })); + expect(mem.eql(u8, &@as([4]u8, v | x), &[4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 })); + expect(mem.eql(u8, &@as([4]u8, v & x), &[4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 })); } }; S.doTheTest(); @@ -98,7 +98,7 @@ test "implicit cast vector to array" { var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 }; var result_array: [4]i32 = a; result_array = a; - expect(mem.eql(i32, result_array, [4]i32{ 1, 2, 3, 4 })); + expect(mem.eql(i32, &result_array, &[4]i32{ 1, 2, 3, 4 })); } }; S.doTheTest(); @@ -120,22 +120,22 @@ test "vector casts of sizes not divisable by 8" { { var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 }; var x: [4]u3 = v; - expect(mem.eql(u3, x, @as([4]u3, v))); + expect(mem.eql(u3, &x, &@as([4]u3, v))); } { var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 }; var x: [4]u2 = v; - expect(mem.eql(u2, x, @as([4]u2, v))); + expect(mem.eql(u2, &x, &@as([4]u2, v))); } { var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 }; var x: [4]u1 = v; - expect(mem.eql(u1, x, @as([4]u1, v))); + expect(mem.eql(u1, &x, &@as([4]u1, v))); } { var v: @Vector(4, bool) = [4]bool{ false, false, true, false }; var x: [4]bool = v; - expect(mem.eql(bool, x, @as([4]bool, v))); + expect(mem.eql(bool, &x, &@as([4]bool, v))); } } }; diff --git a/test/tests.zig b/test/tests.zig index 2bb0f33487715da4d8f2db920177d3113e3c319f..513c960f9510ab1731d598b4d1505e2fe28af72e 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -325,7 +325,7 @@ pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const M const exe = b.addExecutable("test-cli", "test/cli.zig"); const run_cmd = exe.run(); - run_cmd.addArgs([_][]const u8{ + run_cmd.addArgs(&[_][]const u8{ fs.realpathAlloc(b.allocator, b.zig_exe) catch unreachable, b.pathFromRoot(b.cache_root), }); @@ -411,7 +411,7 @@ pub fn addPkgTests( const ArchTag = @TagType(builtin.Arch); if (test_target.disable_native and test_target.target.getOs() == builtin.os and - @as(ArchTag,test_target.target.getArch()) == @as(ArchTag,builtin.arch)) + @as(ArchTag, test_target.target.getArch()) == @as(ArchTag, builtin.arch)) { continue; } @@ -429,7 +429,7 @@ pub fn addPkgTests( "bare"; const triple_prefix = if (test_target.target == .Native) - @as([]const u8,"native") + @as([]const u8, "native") else test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable; @@ -626,7 +626,7 @@ pub const CompareOutputContext = struct { warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name); - const child = std.ChildProcess.init([_][]const u8{full_exe_path}, b.allocator) catch unreachable; + const child = std.ChildProcess.init(&[_][]const u8{full_exe_path}, b.allocator) catch unreachable; defer child.deinit(); child.env_map = b.env_map; @@ -667,7 +667,7 @@ pub const CompareOutputContext = struct { .expected_output = expected_output, .link_libc = false, .special = special, - .cli_args = [_][]const u8{}, + .cli_args = &[_][]const u8{}, }; const root_src_name = if (special == Special.Asm) "source.s" else "source.zig"; tc.addSourceFile(root_src_name, source); @@ -704,7 +704,7 @@ pub const CompareOutputContext = struct { const root_src = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, case.sources.items[0].filename }, + &[_][]const u8{ b.cache_root, case.sources.items[0].filename }, ) catch unreachable; switch (case.special) { @@ -720,7 +720,7 @@ pub const CompareOutputContext = struct { for (case.sources.toSliceConst()) |src_file| { const expanded_src_path = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, src_file.filename }, + &[_][]const u8{ b.cache_root, src_file.filename }, ) catch unreachable; const write_src = b.addWriteFile(expanded_src_path, src_file.source); exe.step.dependOn(&write_src.step); @@ -752,7 +752,7 @@ pub const CompareOutputContext = struct { for (case.sources.toSliceConst()) |src_file| { const expanded_src_path = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, src_file.filename }, + &[_][]const u8{ b.cache_root, src_file.filename }, ) catch unreachable; const write_src = b.addWriteFile(expanded_src_path, src_file.source); exe.step.dependOn(&write_src.step); @@ -783,7 +783,7 @@ pub const CompareOutputContext = struct { for (case.sources.toSliceConst()) |src_file| { const expanded_src_path = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, src_file.filename }, + &[_][]const u8{ b.cache_root, src_file.filename }, ) catch unreachable; const write_src = b.addWriteFile(expanded_src_path, src_file.source); exe.step.dependOn(&write_src.step); @@ -816,7 +816,7 @@ pub const StackTracesContext = struct { const source_pathname = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, "source.zig" }, + &[_][]const u8{ b.cache_root, "source.zig" }, ) catch unreachable; for (self.modes) |mode| { @@ -1073,7 +1073,7 @@ pub const CompileErrorContext = struct { const root_src = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, self.case.sources.items[0].filename }, + &[_][]const u8{ b.cache_root, self.case.sources.items[0].filename }, ) catch unreachable; var zig_args = ArrayList([]const u8).init(b.allocator); @@ -1270,7 +1270,7 @@ pub const CompileErrorContext = struct { for (case.sources.toSliceConst()) |src_file| { const expanded_src_path = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, src_file.filename }, + &[_][]const u8{ b.cache_root, src_file.filename }, ) catch unreachable; const write_src = b.addWriteFile(expanded_src_path, src_file.source); compile_and_cmp_errors.step.dependOn(&write_src.step); @@ -1404,7 +1404,7 @@ pub const TranslateCContext = struct { const root_src = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, self.case.sources.items[0].filename }, + &[_][]const u8{ b.cache_root, self.case.sources.items[0].filename }, ) catch unreachable; var zig_args = ArrayList([]const u8).init(b.allocator); @@ -1577,7 +1577,7 @@ pub const TranslateCContext = struct { for (case.sources.toSliceConst()) |src_file| { const expanded_src_path = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, src_file.filename }, + &[_][]const u8{ b.cache_root, src_file.filename }, ) catch unreachable; const write_src = b.addWriteFile(expanded_src_path, src_file.source); translate_c_and_cmp.step.dependOn(&write_src.step); @@ -1700,7 +1700,7 @@ pub const GenHContext = struct { const b = self.b; const root_src = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, case.sources.items[0].filename }, + &[_][]const u8{ b.cache_root, case.sources.items[0].filename }, ) catch unreachable; const mode = builtin.Mode.Debug; @@ -1715,7 +1715,7 @@ pub const GenHContext = struct { for (case.sources.toSliceConst()) |src_file| { const expanded_src_path = fs.path.join( b.allocator, - [_][]const u8{ b.cache_root, src_file.filename }, + &[_][]const u8{ b.cache_root, src_file.filename }, ) catch unreachable; const write_src = b.addWriteFile(expanded_src_path, src_file.source); obj.step.dependOn(&write_src.step); -- 2.54.0 From bcdb3a90066148dc5a91d176a8fc7f5d9c7487b1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 28 Nov 2019 00:02:53 -0500 Subject: [PATCH 04/19] more progress --- src/ir.cpp | 72 ++++++++++++++++++++++++---------- src/ir_print.cpp | 44 +++++++++++++++------ src/ir_print.hpp | 1 + test/stage1/behavior/cast.zig | 13 ++++++ test/stage1/behavior/union.zig | 29 ++++++++++++++ 5 files changed, 126 insertions(+), 33 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 1e32679babe394522a28589567e4ccddf2e55552..4cedaf95e302b4ff0d3092e2cf671b185e83dfd3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -41,6 +41,9 @@ struct IrAnalyze { ZigList src_implicit_return_type_list; ZigList resume_stack; IrBasicBlock *const_predecessor_bb; + + // For the purpose of using in a debugger + void dump(); }; enum ConstCastResultId { @@ -350,6 +353,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte case ZigTypeIdErrorSet: case ZigTypeIdOpaque: case ZigTypeIdAnyFrame: + case ZigTypeIdFn: return true; case ZigTypeIdFloat: return expected->data.floating.bit_count == actual->data.floating.bit_count; @@ -361,7 +365,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte case ZigTypeIdErrorUnion: case ZigTypeIdEnum: case ZigTypeIdUnion: - case ZigTypeIdFn: case ZigTypeIdArgTuple: case ZigTypeIdVector: case ZigTypeIdFnFrame: @@ -3941,6 +3944,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode scope_block->peer_parent = allocate(1, "ResultLocPeerParent"); scope_block->peer_parent->base.id = ResultLocIdPeerParent; scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; + scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; scope_block->peer_parent->end_bb = scope_block->end_block; scope_block->peer_parent->is_comptime = scope_block->is_comptime; scope_block->peer_parent->parent = result_loc; @@ -4195,6 +4199,7 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction ResultLocPeerParent *peer_parent = allocate(1); peer_parent->base.id = ResultLocIdPeerParent; peer_parent->base.source_instruction = cond_br_inst; + peer_parent->base.allow_write_through_const = parent->allow_write_through_const; peer_parent->end_bb = end_block; peer_parent->is_comptime = is_comptime; peer_parent->parent = parent; @@ -6388,6 +6393,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo ResultLocVar *result_loc_var = allocate(1); result_loc_var->base.id = ResultLocIdVar; result_loc_var->base.source_instruction = alloca; + result_loc_var->base.allow_write_through_const = true; result_loc_var->var = var; ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); @@ -6401,6 +6407,7 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de ResultLocCast *result_loc_cast = allocate(1); result_loc_cast->base.id = ResultLocIdCast; result_loc_cast->base.source_instruction = dest_type; + result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const; ir_ref_instruction(dest_type, irb->current_basic_block); result_loc_cast->parent = parent_result_loc; @@ -7581,6 +7588,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ResultLocPeerParent *peer_parent = allocate(1); peer_parent->base.id = ResultLocIdPeerParent; + peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; peer_parent->end_bb = end_block; peer_parent->is_comptime = is_comptime; peer_parent->parent = result_loc; @@ -13396,16 +13404,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); } - // T to ?E!T - if (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdErrorUnion && - actual_type->id != ZigTypeIdOptional) - { + // T to ?U, where T implicitly casts to U + if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); if (type_is_invalid(cast1->value->type)) return ira->codegen->invalid_instruction; return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); } + // T to E!U, where T implicitly casts to U + if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && + actual_type->id != ZigTypeIdErrorSet) + { + IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); + if (type_is_invalid(cast1->value->type)) + return ira->codegen->invalid_instruction; + return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); + } + ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, buf_sprintf("expected type '%s', found '%s'", buf_ptr(&wanted_type->name), @@ -16046,7 +16062,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe bool force_comptime; if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) return ira->codegen->invalid_instruction; - bool is_comptime = force_comptime || (value != nullptr && + bool is_comptime = force_comptime || (!force_runtime && value != nullptr && value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); if (alloca_src->base.child == nullptr || is_comptime) { @@ -16064,7 +16080,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, alloca_src->name_hint, force_comptime); } - if (alloca_src->base.child != nullptr) { + if (alloca_src->base.child != nullptr && !result_loc->written) { alloca_src->base.child->ref_count = 0; } alloca_src->base.child = alloca_gen; @@ -16079,6 +16095,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return result_loc->resolved_loc; } case ResultLocIdReturn: { + if (value != nullptr) { + reinterpret_cast(result_loc)->implicit_return_type_done = true; + ira->src_implicit_return_type_list.append(value); + } if (!non_null_comptime) { bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime; if (is_comptime) @@ -16121,10 +16141,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return result_loc->resolved_loc; } - bool is_comptime; - if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) + bool is_condition_comptime; + if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) return ira->codegen->invalid_instruction; - if (is_comptime) { + if (is_condition_comptime) { peer_parent->skipped = true; if (non_null_comptime) { return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, @@ -16136,17 +16156,18 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) return ira->codegen->invalid_instruction; if (peer_parent_has_type) { - if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { - reinterpret_cast(peer_parent->parent)->implicit_return_type_done = true; - ira->src_implicit_return_type_list.append(value); - } peer_parent->skipped = true; IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - value_type, value, force_runtime || !is_comptime, true, true); - if (parent_result_loc != nullptr) { - peer_parent->parent->written = true; + value_type, value, force_runtime || !is_condition_comptime, true, true); + if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || + parent_result_loc->value->type->id == ZigTypeIdUnreachable) + { + return parent_result_loc; } - return parent_result_loc; + peer_parent->parent->written = true; + result_loc->written = true; + result_loc->resolved_loc = parent_result_loc; + return result_loc->resolved_loc; } if (peer_parent->resolved_type == nullptr) { @@ -16168,14 +16189,14 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe { return parent_result_loc; } - // because is_comptime is false, we mark this a runtime pointer + // because is_condition_comptime is false, we mark this a runtime pointer parent_result_loc->value->special = ConstValSpecialRuntime; result_loc->written = true; result_loc->resolved_loc = parent_result_loc; return result_loc->resolved_loc; } case ResultLocIdCast: { - if (value != nullptr && value->value->special != ConstValSpecialRuntime) + if (value != nullptr && value->value->special != ConstValSpecialRuntime && !non_null_comptime) return nullptr; ResultLocCast *result_cast = reinterpret_cast(result_loc); ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); @@ -16204,6 +16225,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe { return parent_result_loc; } + ZigType *parent_ptr_type = parent_result_loc->value->type; assert(parent_ptr_type->id == ZigTypeIdPointer); if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, @@ -16354,7 +16376,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s { result_loc_pass1->written = false; return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); - } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { + } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && value == nullptr) { if (value_type->id == ZigTypeIdErrorSet) { return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); } else { @@ -28238,3 +28260,11 @@ void IrInstruction::dump() { ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); } } + +void IrAnalyze::dump() { + ir_print(this->codegen, stderr, this->new_irb.exec, 0, IrPassGen); + if (this->new_irb.current_basic_block != nullptr) { + fprintf(stderr, "Current basic block:\n"); + ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); + } +} diff --git a/src/ir_print.cpp b/src/ir_print.cpp index c3733311b61455d14033dc24b8a95977ec90e74e..1ce111e1fd6cc78d6b6f3963af907a16ac3c211a 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -2530,6 +2530,37 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool fprintf(irp->f, "\n"); } +static void irp_print_basic_block(IrPrint *irp, IrBasicBlock *current_block) { + fprintf(irp->f, "%s_%" ZIG_PRI_usize ":\n", current_block->name_hint, current_block->debug_id); + for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) { + IrInstruction *instruction = current_block->instruction_list.at(instr_i); + if (irp->pass != IrPassSrc) { + irp->printed.put(instruction, 0); + irp->pending.clear(); + } + ir_print_instruction(irp, instruction, false); + for (size_t j = 0; j < irp->pending.length; ++j) + ir_print_instruction(irp, irp->pending.at(j), true); + } +} + +void ir_print_basic_block(CodeGen *codegen, FILE *f, IrBasicBlock *bb, int indent_size, IrPass pass) { + IrPrint ir_print = {}; + ir_print.pass = pass; + ir_print.codegen = codegen; + ir_print.f = f; + ir_print.indent = indent_size; + ir_print.indent_size = indent_size; + ir_print.printed = {}; + ir_print.printed.init(64); + ir_print.pending = {}; + + irp_print_basic_block(&ir_print, bb); + + ir_print.pending.deinit(); + ir_print.printed.deinit(); +} + void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass) { IrPrint ir_print = {}; IrPrint *irp = &ir_print; @@ -2543,18 +2574,7 @@ void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_si irp->pending = {}; for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) { - IrBasicBlock *current_block = executable->basic_block_list.at(bb_i); - fprintf(irp->f, "%s_%" ZIG_PRI_usize ":\n", current_block->name_hint, current_block->debug_id); - for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) { - IrInstruction *instruction = current_block->instruction_list.at(instr_i); - if (irp->pass != IrPassSrc) { - irp->printed.put(instruction, 0); - irp->pending.clear(); - } - ir_print_instruction(irp, instruction, false); - for (size_t j = 0; j < irp->pending.length; ++j) - ir_print_instruction(irp, irp->pending.at(j), true); - } + irp_print_basic_block(irp, executable->basic_block_list.at(bb_i)); } irp->pending.deinit(); diff --git a/src/ir_print.hpp b/src/ir_print.hpp index d8b0b56c291b93eeadd8374136ee45c63d0d06e2..1292779ac47d75aaa2d92c8e78848ca124e8de5d 100644 --- a/src/ir_print.hpp +++ b/src/ir_print.hpp @@ -15,6 +15,7 @@ void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass); void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass); void ir_print_const_expr(CodeGen *codegen, FILE *f, ZigValue *value, int indent_size, IrPass pass); +void ir_print_basic_block(CodeGen *codegen, FILE *f, IrBasicBlock *bb, int indent_size, IrPass pass); const char* ir_instruction_type_str(IrInstructionId id); diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index ba538a0ebba852b0161eb7d44cf2bccda70b92f3..6540166cc7214c2e6a954fb528f1acebd007988d 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -697,3 +697,16 @@ test "cast i8 fn call peers to i32 result" { S.doTheTest(); comptime S.doTheTest(); } + +test "return u8 coercing into ?u32 return type" { + const S = struct { + fn doTheTest() void { + expect(foo(123).? == 123); + } + fn foo(arg: u8) ?u32 { + return arg; + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index 43b26b79b89d9366de5e368d67e76e0a359305ec..d831b51b08c1713b66c8d135fa540f2f37146e4a 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -582,3 +582,32 @@ test "update the tag value for zero-sized unions" { x = S{ .U1 = {} }; expect(x == .U1); } + +test "function call result coerces from tagged union to the tag" { + const S = struct { + const Arch = union(enum) { + One, + Two: usize, + }; + + const ArchTag = @TagType(Arch); + + fn doTheTest() void { + var x: ArchTag = getArch1(); + expect(x == .One); + + var y: ArchTag = getArch2(); + expect(y == .Two); + } + + pub fn getArch1() Arch { + return .One; + } + + pub fn getArch2() Arch { + return .{ .Two = 99 }; + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} -- 2.54.0 From 815b4cfd9d77e5cf3330cc74caf0987f353a8935 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Nov 2019 18:21:21 -0500 Subject: [PATCH 05/19] fix return result loc as peer result loc in inferred error set function --- src/ir.cpp | 14 ++++++++------ test/stage1/behavior/error.zig | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 4cedaf95e302b4ff0d3092e2cf671b185e83dfd3..78df2287ebc7977a135b9eca0b60f8e9b51e2f94 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10373,10 +10373,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT continue; } ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; - if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { + bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && + cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { return ira->codegen->builtin_types.entry_invalid; } - if (type_is_global_error_set(cur_err_set_type)) { + if (!allow_infer && type_is_global_error_set(cur_err_set_type)) { err_set_type = ira->codegen->builtin_types.entry_global_error_set; prev_inst = cur_inst; continue; @@ -16079,6 +16081,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } else { alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, alloca_src->name_hint, force_comptime); + if (force_runtime) { + alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; + alloca_gen->value->special = ConstValSpecialRuntime; + } } if (alloca_src->base.child != nullptr && !result_loc->written) { alloca_src->base.child->ref_count = 0; @@ -26993,10 +26999,6 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) return result_loc; - if (instruction->result_loc_cast->parent->gen_instruction != nullptr) { - return instruction->result_loc_cast->parent->gen_instruction; - } - ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); if (type_is_invalid(dest_type)) return ira->codegen->invalid_instruction; diff --git a/test/stage1/behavior/error.zig b/test/stage1/behavior/error.zig index 9b7904e9cf6c7d5e87cde5f74d5a480c8fd0f79c..f9b331caaf544d0baaef98b0e69cad43ae4f7148 100644 --- a/test/stage1/behavior/error.zig +++ b/test/stage1/behavior/error.zig @@ -400,3 +400,30 @@ test "function pointer with return type that is error union with payload which i }; S.doTheTest(); } + +test "return result loc as peer result loc in inferred error set function" { + const S = struct { + fn doTheTest() void { + if (foo(2)) |x| { + expect(x.Two); + } else |e| switch (e) { + error.Whatever => @panic("fail"), + } + expectError(error.Whatever, foo(99)); + } + const FormValue = union(enum) { + One: void, + Two: bool, + }; + + fn foo(id: u64) !FormValue { + return switch (id) { + 2 => FormValue{ .Two = true }, + 1 => FormValue{ .One = {} }, + else => return error.Whatever, + }; + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} -- 2.54.0 From 559bd27b08f6504addd668a1df01b484dd130430 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Nov 2019 19:58:00 -0500 Subject: [PATCH 06/19] fix `@bitCast` result coercing to error union by returning --- src/ir.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 78df2287ebc7977a135b9eca0b60f8e9b51e2f94..e7f75dd567f72932cd93f098f8838eef588c41b0 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16314,6 +16314,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe IrInstruction *bitcasted_value; if (value != nullptr) { bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type); + dest_type = bitcasted_value->value->type; } else { bitcasted_value = nullptr; } @@ -16378,11 +16379,13 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && - value_type->id != ZigTypeIdNull && value == nullptr) + value_type->id != ZigTypeIdNull && type_has_bits(value_type)) { result_loc_pass1->written = false; return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); - } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && value == nullptr) { + } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && + type_has_bits(value_type)) + { if (value_type->id == ZigTypeIdErrorSet) { return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); } else { -- 2.54.0 From 7278c51ddd1f3d0a06a4181f3588032d6940a8d4 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Nov 2019 21:36:12 -0500 Subject: [PATCH 07/19] fix empty result location for parameters not working --- src/ir.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index e7f75dd567f72932cd93f098f8838eef588c41b0..8f79841df3d987a2c141a5fbfe7e143211d4ff96 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5971,7 +5971,9 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true); - ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc()); + ResultLoc *no_result = no_result_loc(); + ir_build_reset_result(irb, scope, node, no_result); + ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); if (arg == irb->codegen->invalid_instruction) @@ -16278,8 +16280,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe force_runtime, non_null_comptime); } - return ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, + result_loc->written = true; + result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, ptr_type, result_cast->base.source_instruction, false); + return result_loc->resolved_loc; } case ResultLocIdBitCast: { ResultLocBitCast *result_bit_cast = reinterpret_cast(result_loc); -- 2.54.0 From 6936243ee1b933cba5d5e86c398ec39865e4db28 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Nov 2019 21:49:08 -0500 Subject: [PATCH 08/19] fix self-hosted compiler regressions --- src-self-hosted/arg.zig | 2 +- src-self-hosted/compilation.zig | 28 +++++++++++++++------------ src-self-hosted/introspect.zig | 4 ++-- src-self-hosted/libc_installation.zig | 6 +++--- src-self-hosted/main.zig | 10 +++++----- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src-self-hosted/arg.zig b/src-self-hosted/arg.zig index 37767e0ea36e7ba405fcc589ed665c1799452c25..3d12bb3e83d81afc862b4fd31fe1b575785d4731 100644 --- a/src-self-hosted/arg.zig +++ b/src-self-hosted/arg.zig @@ -178,7 +178,7 @@ pub const Args = struct { else => @panic("attempted to retrieve flag with wrong type"), } } else { - return [_][]const u8{}; + return &[_][]const u8{}; } } }; diff --git a/src-self-hosted/compilation.zig b/src-self-hosted/compilation.zig index 2f0de0c5212a263606b9b6e7606b23db12669403..183c28d5ed31acdb9babcdfd5648d7824b4beaec 100644 --- a/src-self-hosted/compilation.zig +++ b/src-self-hosted/compilation.zig @@ -103,8 +103,8 @@ pub const ZigCompiler = struct { /// Must be called only once, ever. Sets global state. pub fn setLlvmArgv(allocator: *Allocator, llvm_argv: []const []const u8) !void { if (llvm_argv.len != 0) { - var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(allocator, [_][]const []const u8{ - [_][]const u8{"zig (LLVM option parsing)"}, + var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(allocator, &[_][]const []const u8{ + &[_][]const u8{"zig (LLVM option parsing)"}, llvm_argv, }); defer c_compatible_args.deinit(); @@ -359,7 +359,11 @@ pub const Compilation = struct { is_static, zig_lib_dir, ); - return optional_comp orelse if (await frame) |_| unreachable else |err| err; + if (optional_comp) |comp| { + return comp; + } else { + if (await frame) |_| unreachable else |err| return err; + } } async fn createAsync( @@ -412,20 +416,20 @@ pub const Compilation = struct { .strip = false, .is_static = is_static, .linker_rdynamic = false, - .clang_argv = [_][]const u8{}, - .lib_dirs = [_][]const u8{}, - .rpath_list = [_][]const u8{}, - .assembly_files = [_][]const u8{}, - .link_objects = [_][]const u8{}, + .clang_argv = &[_][]const u8{}, + .lib_dirs = &[_][]const u8{}, + .rpath_list = &[_][]const u8{}, + .assembly_files = &[_][]const u8{}, + .link_objects = &[_][]const u8{}, .fn_link_set = event.Locked(FnLinkSet).init(FnLinkSet.init()), .windows_subsystem_windows = false, .windows_subsystem_console = false, .link_libs_list = undefined, .libc_link_lib = null, .err_color = errmsg.Color.Auto, - .darwin_frameworks = [_][]const u8{}, + .darwin_frameworks = &[_][]const u8{}, .darwin_version_min = DarwinVersionMin.None, - .test_filters = [_][]const u8{}, + .test_filters = &[_][]const u8{}, .test_name_prefix = null, .emit_file_type = Emit.Binary, .link_out_file = null, @@ -478,7 +482,7 @@ pub const Compilation = struct { comp.name = try Buffer.init(comp.arena(), name); comp.llvm_triple = try util.getTriple(comp.arena(), target); comp.llvm_target = try util.llvmTargetFromTriple(comp.llvm_triple); - comp.zig_std_dir = try std.fs.path.join(comp.arena(), [_][]const u8{ zig_lib_dir, "std" }); + comp.zig_std_dir = try std.fs.path.join(comp.arena(), &[_][]const u8{ zig_lib_dir, "std" }); const opt_level = switch (build_mode) { .Debug => llvm.CodeGenLevelNone, @@ -520,7 +524,7 @@ pub const Compilation = struct { comp.events = try allocator.create(event.Channel(Event)); defer allocator.destroy(comp.events); - comp.events.init([0]Event{}); + comp.events.init(&[0]Event{}); defer comp.events.deinit(); if (root_src_path) |root_src| { diff --git a/src-self-hosted/introspect.zig b/src-self-hosted/introspect.zig index d5204f031e470042be72437b9643b07eb8ebd313..8f822c79df0a66d2fd4a881ea8abbf4543d0a259 100644 --- a/src-self-hosted/introspect.zig +++ b/src-self-hosted/introspect.zig @@ -8,10 +8,10 @@ const warn = std.debug.warn; /// Caller must free result pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 { - const test_zig_dir = try fs.path.join(allocator, [_][]const u8{ test_path, "lib", "zig" }); + const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" }); errdefer allocator.free(test_zig_dir); - const test_index_file = try fs.path.join(allocator, [_][]const u8{ test_zig_dir, "std", "std.zig" }); + const test_index_file = try fs.path.join(allocator, &[_][]const u8{ test_zig_dir, "std", "std.zig" }); defer allocator.free(test_index_file); var file = try fs.File.openRead(test_index_file); diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig index 42e7de5d0839c17b0b64634599bd3be9ce54bada..b7a30dbb9faa6c750f5df4ec0a851c2152513a89 100644 --- a/src-self-hosted/libc_installation.zig +++ b/src-self-hosted/libc_installation.zig @@ -193,7 +193,7 @@ pub const LibCInstallation = struct { "/dev/null", }; // TODO make this use event loop - const errorable_result = std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024); + const errorable_result = std.ChildProcess.exec(allocator, &argv, null, null, 1024 * 1024); const exec_result = if (std.debug.runtime_safety) blk: { break :blk errorable_result catch unreachable; } else blk: { @@ -233,7 +233,7 @@ pub const LibCInstallation = struct { while (path_i < search_paths.len) : (path_i += 1) { const search_path_untrimmed = search_paths.at(search_paths.len - path_i - 1); const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " "); - const stdlib_path = try fs.path.join(allocator, [_][]const u8{ search_path, "stdlib.h" }); + const stdlib_path = try fs.path.join(allocator, &[_][]const u8{ search_path, "stdlib.h" }); defer allocator.free(stdlib_path); if (try fileExists(stdlib_path)) { @@ -401,7 +401,7 @@ async fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname // TODO This simulates evented I/O for the child process exec std.event.Loop.instance.?.yield(); - const errorable_result = std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024); + const errorable_result = std.ChildProcess.exec(allocator, &argv, null, null, 1024 * 1024); const exec_result = if (std.debug.runtime_safety) blk: { break :blk errorable_result catch unreachable; } else blk: { diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 49b378e8fce83f36c290251569c23f318a1edc30..b934ad8ee5613320d27351eb217d0b35f06691f6 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -191,12 +191,12 @@ const usage_build_generic = const args_build_generic = [_]Flag{ Flag.Bool("--help"), - Flag.Option("--color", [_][]const u8{ + Flag.Option("--color", &[_][]const u8{ "auto", "off", "on", }), - Flag.Option("--mode", [_][]const u8{ + Flag.Option("--mode", &[_][]const u8{ "debug", "release-fast", "release-safe", @@ -204,7 +204,7 @@ const args_build_generic = [_]Flag{ }), Flag.ArgMergeN("--assembly", 1), - Flag.Option("--emit", [_][]const u8{ + Flag.Option("--emit", &[_][]const u8{ "asm", "bin", "llvm-ir", @@ -252,7 +252,7 @@ const args_build_generic = [_]Flag{ }; fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Compilation.Kind) !void { - var flags = try Args.parse(allocator, args_build_generic, args); + var flags = try Args.parse(allocator, &args_build_generic, args); defer flags.deinit(); if (flags.present("help")) { @@ -579,7 +579,7 @@ async fn findLibCAsync(zig_compiler: *ZigCompiler) void { } fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { - var flags = try Args.parse(allocator, args_fmt_spec, args); + var flags = try Args.parse(allocator, &args_fmt_spec, args); defer flags.deinit(); if (flags.present("help")) { -- 2.54.0 From d87b13f2f7cef04058537c8bfeb1ceda1a067e73 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Nov 2019 21:55:27 -0500 Subject: [PATCH 09/19] fix windows std lib regressions --- lib/std/coff.zig | 6 +++--- lib/std/debug.zig | 6 +++--- lib/std/os.zig | 4 ++-- lib/std/os/windows.zig | 6 +++--- lib/std/pdb.zig | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/std/coff.zig b/lib/std/coff.zig index c6d7660f8badf15613f1e05eb8f4beaec87bb07c..b1be21c4d370604b6a1f72988fffd6a3f3fc095c 100644 --- a/lib/std/coff.zig +++ b/lib/std/coff.zig @@ -61,7 +61,7 @@ pub const Coff = struct { var magic: [2]u8 = undefined; try in.readNoEof(magic[0..]); - if (!mem.eql(u8, magic, "MZ")) + if (!mem.eql(u8, &magic, "MZ")) return error.InvalidPEMagic; // Seek to PE File Header (coff header) @@ -71,7 +71,7 @@ pub const Coff = struct { var pe_header_magic: [4]u8 = undefined; try in.readNoEof(pe_header_magic[0..]); - if (!mem.eql(u8, pe_header_magic, [_]u8{ 'P', 'E', 0, 0 })) + if (!mem.eql(u8, &pe_header_magic, &[_]u8{ 'P', 'E', 0, 0 })) return error.InvalidPEHeader; self.coff_header = CoffHeader{ @@ -163,7 +163,7 @@ pub const Coff = struct { var cv_signature: [4]u8 = undefined; // CodeView signature try in.readNoEof(cv_signature[0..]); // 'RSDS' indicates PDB70 format, used by lld. - if (!mem.eql(u8, cv_signature, "RSDS")) + if (!mem.eql(u8, &cv_signature, "RSDS")) return error.InvalidPEMagic; try in.readNoEof(self.guid[0..]); self.age = try in.readIntLittle(u32); diff --git a/lib/std/debug.zig b/lib/std/debug.zig index a6a3e148d4f88c9f97b0d5f1c78adfc5e394d40c..ecd3ebaef19fe4a8baac3c7c56b7d814d10a0ef6 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -825,7 +825,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { const len = try di.coff.getPdbPath(path_buf[0..]); const raw_path = path_buf[0..len]; - const path = try fs.path.resolve(allocator, [_][]const u8{raw_path}); + const path = try fs.path.resolve(allocator, &[_][]const u8{raw_path}); try di.pdb.openFile(di.coff, path); @@ -834,10 +834,10 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { const signature = try pdb_stream.stream.readIntLittle(u32); const age = try pdb_stream.stream.readIntLittle(u32); var guid: [16]u8 = undefined; - try pdb_stream.stream.readNoEof(guid[0..]); + try pdb_stream.stream.readNoEof(&guid); if (version != 20000404) // VC70, only value observed by LLVM team return error.UnknownPDBVersion; - if (!mem.eql(u8, di.coff.guid, guid) or di.coff.age != age) + if (!mem.eql(u8, &di.coff.guid, &guid) or di.coff.age != age) return error.PDBMismatch; // We validated the executable and pdb match. diff --git a/lib/std/os.zig b/lib/std/os.zig index 22d52b24a616434505e974e840b96e5ed65a03a6..f083fabb6d2f9503dcdb32fb8fb515554247e9b2 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1569,8 +1569,8 @@ pub fn isCygwinPty(handle: fd_t) bool { const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]); const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)]; const name_wide = @bytesToSlice(u16, name_bytes); - return mem.indexOf(u16, name_wide, [_]u16{ 'm', 's', 'y', 's', '-' }) != null or - mem.indexOf(u16, name_wide, [_]u16{ '-', 'p', 't', 'y' }) != null; + return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or + mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null; } pub const SocketError = error{ diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 5fc18accb82f6f01bd2e234f3f176be6fb497776..ca3a0126c42e553993cfaac1d7b7e5a5313038c7 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -932,9 +932,9 @@ pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE:0]u16 { // TODO https://github.com/ziglang/zig/issues/2765 var result: [PATH_MAX_WIDE:0]u16 = undefined; - const start_index = if (mem.startsWith(u16, s, [_]u16{ '\\', '?' })) 0 else blk: { + const start_index = if (mem.startsWith(u16, s, &[_]u16{ '\\', '?' })) 0 else blk: { const prefix = [_]u16{ '\\', '?', '?', '\\' }; - mem.copy(u16, result[0..], prefix); + mem.copy(u16, result[0..], &prefix); break :blk prefix.len; }; const end_index = start_index + s.len; @@ -961,7 +961,7 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) } const start_index = if (mem.startsWith(u8, s, "\\?") or !std.fs.path.isAbsolute(s)) 0 else blk: { const prefix = [_]u16{ '\\', '?', '?', '\\' }; - mem.copy(u16, result[0..], prefix); + mem.copy(u16, result[0..], &prefix); break :blk prefix.len; }; const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s); diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig index 8e4a9b5d6a9cf7f2c23b69faad8890c46f2fb16f..aef68631b778b99c5265c8a6ffebf2556fdab632 100644 --- a/lib/std/pdb.zig +++ b/lib/std/pdb.zig @@ -500,7 +500,7 @@ const Msf = struct { const superblock = try in.readStruct(SuperBlock); // Sanity checks - if (!mem.eql(u8, superblock.FileMagic, SuperBlock.file_magic)) + if (!mem.eql(u8, &superblock.FileMagic, SuperBlock.file_magic)) return error.InvalidDebugInfo; if (superblock.FreeBlockMapBlock != 1 and superblock.FreeBlockMapBlock != 2) return error.InvalidDebugInfo; @@ -546,7 +546,7 @@ const Msf = struct { const size = stream_sizes[i]; if (size == 0) { stream.* = MsfStream{ - .blocks = [_]u32{}, + .blocks = &[_]u32{}, }; } else { var blocks = try allocator.alloc(u32, size); -- 2.54.0 From b220be7a33a9835a1ec7a033e472830290332d57 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Nov 2019 23:04:19 -0500 Subject: [PATCH 10/19] more test regression fixes --- lib/std/fs.zig | 2 +- lib/std/os.zig | 2 +- test/cli.zig | 26 ++++++++++++------------ test/runtime_safety.zig | 4 ++-- test/stage1/behavior/array.zig | 6 ++++++ test/stage1/c_abi/build.zig | 2 +- test/stage1/c_abi/main.zig | 2 +- test/standalone/mix_o_files/build.zig | 2 +- test/standalone/shared_library/build.zig | 2 +- test/standalone/static_c_lib/build.zig | 2 +- 10 files changed, 28 insertions(+), 22 deletions(-) diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 7116d2fd9e31c00520cf33a2fb2a6b16695576a0..60ecff1fa329dce6ef55bfcee534c089ec9cd4da 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -609,7 +609,7 @@ pub const Dir = struct { const name_utf16le = @ptrCast([*]u16, &dir_info.FileName)[0 .. dir_info.FileNameLength / 2]; - if (mem.eql(u16, name_utf16le, [_]u16{'.'}) or mem.eql(u16, name_utf16le, [_]u16{ '.', '.' })) + if (mem.eql(u16, name_utf16le, &[_]u16{'.'}) or mem.eql(u16, name_utf16le, &[_]u16{ '.', '.' })) continue; // Trust that Windows gives us valid UTF-16LE const name_utf8_len = std.unicode.utf16leToUtf8(self.name_data[0..], name_utf16le) catch unreachable; diff --git a/lib/std/os.zig b/lib/std/os.zig index f083fabb6d2f9503dcdb32fb8fb515554247e9b2..d137617b894ba0080adf667d9c6c42950bfc644c 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -2633,7 +2633,7 @@ pub fn realpathW(pathname: [*:0]const u16, out_buffer: *[MAX_PATH_BYTES]u8) Real // Windows returns \\?\ prepended to the path. // We strip it to make this function consistent across platforms. const prefix = [_]u16{ '\\', '\\', '?', '\\' }; - const start_index = if (mem.startsWith(u16, wide_slice, prefix)) prefix.len else 0; + const start_index = if (mem.startsWith(u16, wide_slice, &prefix)) prefix.len else 0; // Trust that Windows gives us valid UTF-16LE. const end_index = std.unicode.utf16leToUtf8(out_buffer, wide_slice[start_index..]) catch unreachable; diff --git a/test/cli.zig b/test/cli.zig index 0820870412a46464f314f4249b0a6d85679815eb..b36742566ace1569dced6c0b18874b1a58574f6b 100644 --- a/test/cli.zig +++ b/test/cli.zig @@ -26,9 +26,9 @@ pub fn main() !void { std.debug.warn("Expected second argument to be cache root directory path\n"); return error.InvalidArgs; }); - const zig_exe = try fs.path.resolve(a, [_][]const u8{zig_exe_rel}); + const zig_exe = try fs.path.resolve(a, &[_][]const u8{zig_exe_rel}); - const dir_path = try fs.path.join(a, [_][]const u8{ cache_root, "clitest" }); + const dir_path = try fs.path.join(a, &[_][]const u8{ cache_root, "clitest" }); const TestFn = fn ([]const u8, []const u8) anyerror!void; const test_fns = [_]TestFn{ testZigInitLib, @@ -85,22 +85,22 @@ fn exec(cwd: []const u8, argv: []const []const u8) !ChildProcess.ExecResult { } fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void { - _ = try exec(dir_path, [_][]const u8{ zig_exe, "init-lib" }); - const test_result = try exec(dir_path, [_][]const u8{ zig_exe, "build", "test" }); + _ = try exec(dir_path, &[_][]const u8{ zig_exe, "init-lib" }); + const test_result = try exec(dir_path, &[_][]const u8{ zig_exe, "build", "test" }); testing.expect(std.mem.endsWith(u8, test_result.stderr, "All 1 tests passed.\n")); } fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void { - _ = try exec(dir_path, [_][]const u8{ zig_exe, "init-exe" }); - const run_result = try exec(dir_path, [_][]const u8{ zig_exe, "build", "run" }); + _ = try exec(dir_path, &[_][]const u8{ zig_exe, "init-exe" }); + const run_result = try exec(dir_path, &[_][]const u8{ zig_exe, "build", "run" }); testing.expect(std.mem.eql(u8, run_result.stderr, "All your base are belong to us.\n")); } fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void { if (builtin.os != .linux or builtin.arch != .x86_64) return; - const example_zig_path = try fs.path.join(a, [_][]const u8{ dir_path, "example.zig" }); - const example_s_path = try fs.path.join(a, [_][]const u8{ dir_path, "example.s" }); + const example_zig_path = try fs.path.join(a, &[_][]const u8{ dir_path, "example.zig" }); + const example_s_path = try fs.path.join(a, &[_][]const u8{ dir_path, "example.s" }); try std.io.writeFile(example_zig_path, \\// Type your code here, or load an example. @@ -123,7 +123,7 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void { "--strip", "--release-fast", example_zig_path, "--disable-gen-h", }; - _ = try exec(dir_path, args); + _ = try exec(dir_path, &args); const out_asm = try std.io.readFileAlloc(a, example_s_path); testing.expect(std.mem.indexOf(u8, out_asm, "square:") != null); @@ -132,10 +132,10 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void { } fn testMissingOutputPath(zig_exe: []const u8, dir_path: []const u8) !void { - _ = try exec(dir_path, [_][]const u8{ zig_exe, "init-exe" }); - const output_path = try fs.path.join(a, [_][]const u8{ "does", "not", "exist" }); - const source_path = try fs.path.join(a, [_][]const u8{ "src", "main.zig" }); - _ = try exec(dir_path, [_][]const u8{ + _ = try exec(dir_path, &[_][]const u8{ zig_exe, "init-exe" }); + const output_path = try fs.path.join(a, &[_][]const u8{ "does", "not", "exist" }); + const source_path = try fs.path.join(a, &[_][]const u8{ "src", "main.zig" }); + _ = try exec(dir_path, &[_][]const u8{ zig_exe, "build-exe", source_path, "--output-dir", output_path, }); } diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig index d278407ee1c34951c1d5a9801747e50781f1cf77..045326ffd443a7b34b12c94e7e0ad867c466b956 100644 --- a/test/runtime_safety.zig +++ b/test/runtime_safety.zig @@ -261,7 +261,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\} \\pub fn main() void { \\ const a = [_]i32{1, 2, 3, 4}; - \\ baz(bar(a)); + \\ baz(bar(&a)); \\} \\fn bar(a: []const i32) i32 { \\ return a[4]; @@ -471,7 +471,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ @import("std").os.exit(126); \\} \\pub fn main() !void { - \\ const x = widenSlice([_]u8{1, 2, 3, 4, 5}); + \\ const x = widenSlice(&[_]u8{1, 2, 3, 4, 5}); \\ if (x.len == 0) return error.Whatever; \\} \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 { diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 1d51f822d07ea5631ff43cab1c2751bb506e7cef..49419f15f18a5b8445b565fb4f28e300309de7d4 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -360,3 +360,9 @@ test "access the null element of a null terminated array" { S.doTheTest(); comptime S.doTheTest(); } + +test "type coerce sentinel-terminated array to non-sentinel-terminated array" { + var array: [2]u8 = [_:255]u8{1, 2}; + expect(array[0] == 1); + expect(array[1] == 2); +} diff --git a/test/stage1/c_abi/build.zig b/test/stage1/c_abi/build.zig index c2a270ec34113e044c35f4725faa52f082bc9bc0..cf21d403f741c815a2d5cb538290424aaf76ce2e 100644 --- a/test/stage1/c_abi/build.zig +++ b/test/stage1/c_abi/build.zig @@ -4,7 +4,7 @@ pub fn build(b: *Builder) void { const rel_opts = b.standardReleaseOptions(); const c_obj = b.addObject("cfuncs", null); - c_obj.addCSourceFile("cfuncs.c", [_][]const u8{"-std=c99"}); + c_obj.addCSourceFile("cfuncs.c", &[_][]const u8{"-std=c99"}); c_obj.setBuildMode(rel_opts); c_obj.linkSystemLibrary("c"); diff --git a/test/stage1/c_abi/main.zig b/test/stage1/c_abi/main.zig index f9de9fecb7f4665cf9bc4739663981f88ba3280b..3c2b73152422d69c0d0f85e179296dc6fa8b0ed2 100644 --- a/test/stage1/c_abi/main.zig +++ b/test/stage1/c_abi/main.zig @@ -124,7 +124,7 @@ test "C ABI array" { } export fn zig_array(x: [10]u8) void { - expect(std.mem.eql(u8, x, "1234567890")); + expect(std.mem.eql(u8, &x, "1234567890")); } const BigStruct = extern struct { diff --git a/test/standalone/mix_o_files/build.zig b/test/standalone/mix_o_files/build.zig index 7c72cfcc3abec05242d03e308bda4c6de0ce967a..d498e2e20a116c1788cc1260bc8542dbe858da90 100644 --- a/test/standalone/mix_o_files/build.zig +++ b/test/standalone/mix_o_files/build.zig @@ -4,7 +4,7 @@ pub fn build(b: *Builder) void { const obj = b.addObject("base64", "base64.zig"); const exe = b.addExecutable("test", null); - exe.addCSourceFile("test.c", [_][]const u8{"-std=c99"}); + exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); exe.addObject(obj); exe.linkSystemLibrary("c"); diff --git a/test/standalone/shared_library/build.zig b/test/standalone/shared_library/build.zig index 129c5dc1c9fa6e76520df88987c66fe5f7ecbebf..cb7437bcaaae3a37f37a6be65c080b76c7f20e16 100644 --- a/test/standalone/shared_library/build.zig +++ b/test/standalone/shared_library/build.zig @@ -4,7 +4,7 @@ pub fn build(b: *Builder) void { const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0)); const exe = b.addExecutable("test", null); - exe.addCSourceFile("test.c", [_][]const u8{"-std=c99"}); + exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); exe.linkLibrary(lib); exe.linkSystemLibrary("c"); diff --git a/test/standalone/static_c_lib/build.zig b/test/standalone/static_c_lib/build.zig index 4af00705a8e81a8b6471973b40f3bb94bef39832..2b604f5c0f61aa02ad425f57fa26eb94c18324d8 100644 --- a/test/standalone/static_c_lib/build.zig +++ b/test/standalone/static_c_lib/build.zig @@ -4,7 +4,7 @@ pub fn build(b: *Builder) void { const mode = b.standardReleaseOptions(); const foo = b.addStaticLibrary("foo", null); - foo.addCSourceFile("foo.c", [_][]const u8{}); + foo.addCSourceFile("foo.c", &[_][]const u8{}); foo.setBuildMode(mode); foo.addIncludeDir("."); -- 2.54.0 From b5df18c8fd725a2993c520ddc8777ecad71e3d11 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 00:29:16 -0500 Subject: [PATCH 11/19] inline ConstGlobalRefs into ZigValue Having ConstGlobalRefs be a pointer in ZigValue was a hack that caused plenty of bugs. It was used to work around difficulties in type coercing array values into slices. However, after #3787 is merged, array values no longer type coerce into slices, and so this provided an opportunity to clean up the code. This has the nice effect of reducing stage1 peak RAM usage during the std lib tests from 3.443 GiB to 3.405 GiB (saving 39 MiB). There is one behavior test failing in this branch, which I plan to debug after merging #3787. --- src/all_types.hpp | 10 +-- src/analyze.cpp | 29 ++------ src/codegen.cpp | 110 +++++++++++----------------- src/ir.cpp | 112 +++++++++++++---------------- test/stage1/behavior/bugs/1607.zig | 4 +- test/stage1/behavior/struct.zig | 2 +- 6 files changed, 103 insertions(+), 164 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 5b062efc9a5b2f4f453e7ae5a5d29e8004fc17af..458aa912756d5fbbc1c953b5489043d09398b1ab 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -313,12 +313,6 @@ struct RuntimeHintSlice { uint64_t len; }; -struct ConstGlobalRefs { - LLVMValueRef llvm_value; - LLVMValueRef llvm_global; - uint32_t align; -}; - enum LazyValueId { LazyValueIdInvalid, LazyValueIdAlignOf, @@ -409,8 +403,10 @@ struct LazyValueErrUnionType { struct ZigValue { ZigType *type; ConstValSpecial special; + uint32_t llvm_align; ConstParent parent; - ConstGlobalRefs *global_refs; + LLVMValueRef llvm_value; + LLVMValueRef llvm_global; union { // populated if special == ConstValSpecialStatic diff --git a/src/analyze.cpp b/src/analyze.cpp index c0d2d636eff8192aab75c3b239a9a9c2c52dd567..abef74052e013f8588ac9e30c47b11465cd4b029 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -5908,12 +5908,7 @@ ZigValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_ ZigValue *create_const_vals(size_t count) { - ConstGlobalRefs *global_refs = allocate(count, "ConstGlobalRefs"); - ZigValue *vals = allocate(count, "ZigValue"); - for (size_t i = 0; i < count; i += 1) { - vals[i].global_refs = &global_refs[i]; - } - return vals; + return allocate(count, "ZigValue"); } ZigValue **alloc_const_vals_ptrs(size_t count) { @@ -6480,20 +6475,14 @@ bool const_values_equal_ptr(ZigValue *a, ZigValue *b) { return false; return true; case ConstPtrSpecialBaseArray: - if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val && - a->data.x_ptr.data.base_array.array_val->global_refs != - b->data.x_ptr.data.base_array.array_val->global_refs) - { + if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val) { return false; } if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index) return false; return true; case ConstPtrSpecialBaseStruct: - if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val && - a->data.x_ptr.data.base_struct.struct_val->global_refs != - b->data.x_ptr.data.base_struct.struct_val->global_refs) - { + if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val) { return false; } if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index) @@ -6501,27 +6490,21 @@ bool const_values_equal_ptr(ZigValue *a, ZigValue *b) { return true; case ConstPtrSpecialBaseErrorUnionCode: if (a->data.x_ptr.data.base_err_union_code.err_union_val != - b->data.x_ptr.data.base_err_union_code.err_union_val && - a->data.x_ptr.data.base_err_union_code.err_union_val->global_refs != - b->data.x_ptr.data.base_err_union_code.err_union_val->global_refs) + b->data.x_ptr.data.base_err_union_code.err_union_val) { return false; } return true; case ConstPtrSpecialBaseErrorUnionPayload: if (a->data.x_ptr.data.base_err_union_payload.err_union_val != - b->data.x_ptr.data.base_err_union_payload.err_union_val && - a->data.x_ptr.data.base_err_union_payload.err_union_val->global_refs != - b->data.x_ptr.data.base_err_union_payload.err_union_val->global_refs) + b->data.x_ptr.data.base_err_union_payload.err_union_val) { return false; } return true; case ConstPtrSpecialBaseOptionalPayload: if (a->data.x_ptr.data.base_optional_payload.optional_val != - b->data.x_ptr.data.base_optional_payload.optional_val && - a->data.x_ptr.data.base_optional_payload.optional_val->global_refs != - b->data.x_ptr.data.base_optional_payload.optional_val->global_refs) + b->data.x_ptr.data.base_optional_payload.optional_val) { return false; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 32dd6091f36b002f9bc31b384ee2614996de2ea5..06834a7e4b859dd9dbb9e720ac8025c69c2e0da1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -946,7 +946,7 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { ZigValue *val = &g->panic_msg_vals[msg_id]; - if (!val->global_refs->llvm_global) { + if (!val->llvm_global) { Buf *buf_msg = panic_msg_buf(msg_id); ZigValue *array_val = create_const_str_lit(g, buf_msg)->data.x_ptr.data.ref.pointee; @@ -955,13 +955,13 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { render_const_val(g, val, ""); render_const_val_global(g, val, ""); - assert(val->global_refs->llvm_global); + assert(val->llvm_global); } ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); ZigType *str_type = get_slice_type(g, u8_ptr_type); - return LLVMConstBitCast(val->global_refs->llvm_global, LLVMPointerType(get_llvm_type(g, str_type), 0)); + return LLVMConstBitCast(val->llvm_global, LLVMPointerType(get_llvm_type(g, str_type), 0)); } static ZigType *ptr_to_stack_trace_type(CodeGen *g) { @@ -1727,9 +1727,9 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { if (handle_is_ptr(instruction->value->type)) { render_const_val_global(g, instruction->value, ""); ZigType *ptr_type = get_pointer_to_type(g, instruction->value->type, true); - instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->global_refs->llvm_global, get_llvm_type(g, ptr_type), ""); + instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->llvm_global, get_llvm_type(g, ptr_type), ""); } else { - instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->global_refs->llvm_value, + instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->llvm_value, get_llvm_type(g, instruction->value->type), ""); } assert(instruction->llvm_value); @@ -6374,7 +6374,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ZigValue *val, ConstParent *paren case ConstParentIdNone: render_const_val(g, val, ""); render_const_val_global(g, val, ""); - return val->global_refs->llvm_global; + return val->llvm_global; case ConstParentIdStruct: return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val, parent->data.p_struct.field_index); @@ -6392,7 +6392,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ZigValue *val, ConstParent *paren case ConstParentIdScalar: render_const_val(g, parent->data.p_scalar.scalar_val, ""); render_const_val_global(g, parent->data.p_scalar.scalar_val, ""); - return parent->data.p_scalar.scalar_val->global_refs->llvm_global; + return parent->data.p_scalar.scalar_val->llvm_global; } zig_unreachable(); } @@ -6623,17 +6623,15 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha zig_unreachable(); case ConstPtrSpecialRef: { - assert(const_val->global_refs != nullptr); ZigValue *pointee = const_val->data.x_ptr.data.ref.pointee; render_const_val(g, pointee, ""); render_const_val_global(g, pointee, ""); - const_val->global_refs->llvm_value = LLVMConstBitCast(pointee->global_refs->llvm_global, + const_val->llvm_value = LLVMConstBitCast(pointee->llvm_global, get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } case ConstPtrSpecialBaseArray: { - assert(const_val->global_refs != nullptr); ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val; assert(array_const_val->type->id == ZigTypeIdArray); if (!type_has_bits(array_const_val->type)) { @@ -6641,102 +6639,97 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha ZigValue *pointee = array_const_val->type->data.array.sentinel; render_const_val(g, pointee, ""); render_const_val_global(g, pointee, ""); - const_val->global_refs->llvm_value = LLVMConstBitCast(pointee->global_refs->llvm_global, + const_val->llvm_value = LLVMConstBitCast(pointee->llvm_global, get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } else { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), + const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } } size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, elem_index); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); - const_val->global_refs->llvm_value = ptr_val; + const_val->llvm_value = ptr_val; return ptr_val; } case ConstPtrSpecialBaseStruct: { - assert(const_val->global_refs != nullptr); ZigValue *struct_const_val = const_val->data.x_ptr.data.base_struct.struct_val; assert(struct_const_val->type->id == ZigTypeIdStruct); if (!type_has_bits(struct_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), + const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index; size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index]->gen_index; LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val, gen_field_index); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); - const_val->global_refs->llvm_value = ptr_val; + const_val->llvm_value = ptr_val; return ptr_val; } case ConstPtrSpecialBaseErrorUnionCode: { - assert(const_val->global_refs != nullptr); ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_code.err_union_val; assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); if (!type_has_bits(err_union_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), + const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_code_recursive(g, err_union_const_val); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); - const_val->global_refs->llvm_value = ptr_val; + const_val->llvm_value = ptr_val; return ptr_val; } case ConstPtrSpecialBaseErrorUnionPayload: { - assert(const_val->global_refs != nullptr); ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_payload.err_union_val; assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); if (!type_has_bits(err_union_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), + const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_payload_recursive(g, err_union_const_val); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); - const_val->global_refs->llvm_value = ptr_val; + const_val->llvm_value = ptr_val; return ptr_val; } case ConstPtrSpecialBaseOptionalPayload: { - assert(const_val->global_refs != nullptr); ZigValue *optional_const_val = const_val->data.x_ptr.data.base_optional_payload.optional_val; assert(optional_const_val->type->id == ZigTypeIdOptional); if (!type_has_bits(optional_const_val->type)) { // make this a null pointer ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), + const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } LLVMValueRef uncasted_ptr_val = gen_const_ptr_optional_payload_recursive(g, optional_const_val); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); - const_val->global_refs->llvm_value = ptr_val; + const_val->llvm_value = ptr_val; return ptr_val; } case ConstPtrSpecialHardCodedAddr: { - assert(const_val->global_refs != nullptr); uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr; ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr( + const_val->llvm_value = LLVMConstIntToPtr( LLVMConstInt(usize->llvm_type, addr_value, false), get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + return const_val->llvm_value; } case ConstPtrSpecialFunction: return LLVMConstBitCast(fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry), @@ -7175,34 +7168,29 @@ check: switch (const_val->special) { } static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name) { - if (!const_val->global_refs) - const_val->global_refs = allocate(1); - if (!const_val->global_refs->llvm_value) - const_val->global_refs->llvm_value = gen_const_val(g, const_val, name); + if (!const_val->llvm_value) + const_val->llvm_value = gen_const_val(g, const_val, name); - if (const_val->global_refs->llvm_global) - LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value); + if (const_val->llvm_global) + LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); } static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char *name) { - if (!const_val->global_refs) - const_val->global_refs = allocate(1); - - if (!const_val->global_refs->llvm_global) { - LLVMTypeRef type_ref = const_val->global_refs->llvm_value ? - LLVMTypeOf(const_val->global_refs->llvm_value) : get_llvm_type(g, const_val->type); + if (!const_val->llvm_global) { + LLVMTypeRef type_ref = const_val->llvm_value ? + LLVMTypeOf(const_val->llvm_value) : get_llvm_type(g, const_val->type); LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name); LLVMSetLinkage(global_value, LLVMInternalLinkage); LLVMSetGlobalConstant(global_value, true); LLVMSetUnnamedAddr(global_value, true); - LLVMSetAlignment(global_value, (const_val->global_refs->align == 0) ? - get_abi_alignment(g, const_val->type) : const_val->global_refs->align); + LLVMSetAlignment(global_value, (const_val->llvm_align == 0) ? + get_abi_alignment(g, const_val->type) : const_val->llvm_align); - const_val->global_refs->llvm_global = global_value; + const_val->llvm_global = global_value; } - if (const_val->global_refs->llvm_value) - LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value); + if (const_val->llvm_value) + LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); } static void generate_error_name_table(CodeGen *g) { @@ -7403,7 +7391,7 @@ static void do_code_gen(CodeGen *g) { bool exported = (linkage != GlobalLinkageIdInternal); render_const_val(g, var->const_value, symbol_name); render_const_val_global(g, var->const_value, symbol_name); - global_value = var->const_value->global_refs->llvm_global; + global_value = var->const_value->llvm_global; if (exported) { LLVMSetLinkage(global_value, to_llvm_linkage(linkage)); @@ -7418,7 +7406,7 @@ static void do_code_gen(CodeGen *g) { // Here we use const_value->type because that's the type of the llvm global, // which we const ptr cast upon use to whatever it needs to be. if (var->gen_is_const && var->const_value->type->id != ZigTypeIdFn) { - gen_global_var(g, var, var->const_value->global_refs->llvm_value, var->const_value->type); + gen_global_var(g, var, var->const_value->llvm_value, var->const_value->type); } LLVMSetGlobalConstant(global_value, var->gen_is_const); @@ -8012,31 +8000,26 @@ static void define_intern_values(CodeGen *g) { { auto& value = g->intern.x_undefined; value.type = g->builtin_types.entry_undef; - value.global_refs = allocate(1, "ConstGlobalRefs.undefined"); value.special = ConstValSpecialStatic; } { auto& value = g->intern.x_void; value.type = g->builtin_types.entry_void; - value.global_refs = allocate(1, "ConstGlobalRefs.void"); value.special = ConstValSpecialStatic; } { auto& value = g->intern.x_null; value.type = g->builtin_types.entry_null; - value.global_refs = allocate(1, "ConstGlobalRefs.null"); value.special = ConstValSpecialStatic; } { auto& value = g->intern.x_unreachable; value.type = g->builtin_types.entry_unreachable; - value.global_refs = allocate(1, "ConstGlobalRefs.unreachable"); value.special = ConstValSpecialStatic; } { auto& value = g->intern.zero_byte; value.type = g->builtin_types.entry_u8; - value.global_refs = allocate(1, "ConstGlobalRefs.zero_byte"); value.special = ConstValSpecialStatic; bigint_init_unsigned(&value.data.x_bigint, 0); } @@ -8669,19 +8652,10 @@ static void init(CodeGen *g) { g->invalid_instruction = &sentinel_instructions[0]; g->invalid_instruction->value = allocate(1, "ZigValue"); g->invalid_instruction->value->type = g->builtin_types.entry_invalid; - g->invalid_instruction->value->global_refs = allocate(1); g->unreach_instruction = &sentinel_instructions[1]; g->unreach_instruction->value = allocate(1, "ZigValue"); g->unreach_instruction->value->type = g->builtin_types.entry_unreachable; - g->unreach_instruction->value->global_refs = allocate(1); - - { - ConstGlobalRefs *global_refs = allocate(PanicMsgIdCount); - for (size_t i = 0; i < PanicMsgIdCount; i += 1) { - g->panic_msg_vals[i].global_refs = &global_refs[i]; - } - } define_builtin_fns(g); Error err; diff --git a/src/ir.cpp b/src/ir.cpp index 272442a563569e510abe493f49cdf925ee0c1e59..52ab2f9d069b52fc1b98d03813482911554c2e4c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -219,7 +219,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on); static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); -static void copy_const_val(ZigValue *dest, ZigValue *src, bool same_global_refs); +static void copy_const_val(ZigValue *dest, ZigValue *src); static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, ZigType *ptr_type); @@ -1165,7 +1165,6 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no special_instruction->base.debug_id = exec_next_debug_id(irb->exec); special_instruction->base.owner_bb = irb->current_basic_block; special_instruction->base.value = allocate(1, "ZigValue"); - special_instruction->base.value->global_refs = allocate(1, "ConstGlobalRefs"); return special_instruction; } @@ -8735,7 +8734,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) return err; ZigValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); - copy_const_val(child_val, &tmp, false); + copy_const_val(child_val, &tmp); return ErrorNone; } @@ -11018,18 +11017,14 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } -static void copy_const_val(ZigValue *dest, ZigValue *src, bool same_global_refs) { - ConstGlobalRefs *global_refs = dest->global_refs; +static void copy_const_val(ZigValue *dest, ZigValue *src) { memcpy(dest, src, sizeof(ZigValue)); - if (!same_global_refs) { - dest->global_refs = global_refs; - if (src->special != ConstValSpecialStatic) - return; - if (dest->type->id == ZigTypeIdStruct) { - dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); - for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { - copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i], false); - } + if (src->special != ConstValSpecialStatic) + return; + if (dest->type->id == ZigTypeIdStruct) { + dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); + for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { + copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]); } } } @@ -11048,13 +11043,11 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ case CastOpErrSet: case CastOpBitCast: zig_panic("TODO"); - case CastOpNoop: - { - bool same_global_refs = other_val->special == ConstValSpecialStatic; - copy_const_val(const_val, other_val, same_global_refs); - const_val->type = new_type; - break; - } + case CastOpNoop: { + copy_const_val(const_val, other_val); + const_val->type = new_type; + break; + } case CastOpNumLitToConcrete: if (other_val->type->id == ZigTypeIdComptimeFloat) { assert(new_type->id == ZigTypeIdFloat); @@ -11775,7 +11768,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so source_instr->scope, source_instr->source_node); const_instruction->base.value->special = ConstValSpecialStatic; if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { - copy_const_val(const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); + copy_const_val(const_instruction->base.value, val); } else { const_instruction->base.value->data.x_optional = val; } @@ -12779,7 +12772,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * if (instr_is_comptime(array)) { // arrays and vectors have the same ZigValue representation IrInstruction *result = ir_const(ira, source_instr, vector_type); - copy_const_val(result->value, array->value, false); + copy_const_val(result->value, array->value); result->value->type = vector_type; return result; } @@ -12792,7 +12785,7 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * if (instr_is_comptime(vector)) { // arrays and vectors have the same ZigValue representation IrInstruction *result = ir_const(ira, source_instr, array_type); - copy_const_val(result->value, vector->value, false); + copy_const_val(result->value, vector->value); result->value->type = array_type; return result; } @@ -13080,7 +13073,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { IrInstruction *result = ir_const(ira, source_instr, wanted_type); if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { - copy_const_val(result->value, value->value, false); + copy_const_val(result->value, value->value); result->value->type = wanted_type; } else { float_init_bigint(&result->value->data.x_bigint, value->value); @@ -13963,7 +13956,7 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { IrInstruction *result = ir_const(ira, &instruction->base, nullptr); - copy_const_val(result->value, instruction->base.value, true); + copy_const_val(result->value, instruction->base.value); return result; } @@ -14502,7 +14495,7 @@ never_mind_just_calculate_it_normally: &op1_val->data.x_array.data.s_none.elements[i], &op2_val->data.x_array.data.s_none.elements[i], bin_op_instruction, op_id, one_possible_value); - copy_const_val(&result->value->data.x_array.data.s_none.elements[i], cur_res->value, false); + copy_const_val(&result->value->data.x_array.data.s_none.elements[i], cur_res->value); } return result; } @@ -15368,21 +15361,21 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i size_t next_index = 0; for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; - copy_const_val(elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i], false); + copy_const_val(elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i]); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_array_val; elem_dest_val->parent.data.p_array.elem_index = next_index; } for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; - copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i], false); + copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i]); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_array_val; elem_dest_val->parent.data.p_array.elem_index = next_index; } if (next_index < full_len) { ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; - copy_const_val(elem_dest_val, sentinel, false); + copy_const_val(elem_dest_val, sentinel); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_array_val; elem_dest_val->parent.data.p_array.elem_index = next_index; @@ -15467,7 +15460,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * for (uint64_t x = 0; x < mult_amt; x += 1) { for (uint64_t y = 0; y < old_array_len; y += 1) { ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; - copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y], false); + copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y]); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_val; elem_dest_val->parent.data.p_array.elem_index = i; @@ -15478,7 +15471,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * if (array_type->data.array.sentinel != nullptr) { ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; - copy_const_val(elem_dest_val, array_type->data.array.sentinel, false); + copy_const_val(elem_dest_val, array_type->data.array.sentinel); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_val; elem_dest_val->parent.data.p_array.elem_index = i; @@ -15628,7 +15621,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, var->const_value = init_val; } else { var->const_value = create_const_vals(1); - copy_const_val(var->const_value, init_val, false); + copy_const_val(var->const_value, init_val); } } } @@ -15738,7 +15731,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, if (instr_is_comptime(var_ptr) && var->mem_slot_index != SIZE_MAX) { assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); ZigValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); - copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); + copy_const_val(mem_slot, init_val); if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { return ir_const_void(ira, &decl_var_instruction->base); @@ -16217,8 +16210,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } IrInstruction *alloca_gen; if (is_comptime && value != nullptr) { - if (align > value->value->global_refs->align) { - value->value->global_refs->align = align; + if (align > value->value->llvm_align) { + value->value->llvm_align = align; } alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false); } else { @@ -16782,7 +16775,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod arg_val = create_const_runtime(casted_arg->value->type); } if (arg_part_of_generic_id) { - copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); + copy_const_val(&generic_id->params[generic_id->param_count], arg_val); generic_id->param_count += 1; } @@ -16963,7 +16956,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source IrInstruction *casted_ptr; if (instr_is_comptime(ptr)) { casted_ptr = ir_const(ira, source_instr, struct_ptr_type); - copy_const_val(casted_ptr->value, ptr->value, false); + copy_const_val(casted_ptr->value, ptr->value); casted_ptr->value->type = struct_ptr_type; } else { casted_ptr = ir_build_cast(&ira->new_irb, source_instr->scope, @@ -17026,14 +17019,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source if (dest_val == nullptr) return ira->codegen->invalid_instruction; if (dest_val->special != ConstValSpecialRuntime) { - // TODO this allows a value stored to have the original value modified and then - // have that affect what should be a copy. We need some kind of advanced copy-on-write - // system to make these two tests pass at the same time: - // * "string literal used as comptime slice is memoized" - // * "comptime modification of const struct field" - except modified to avoid - // ConstPtrMutComptimeVar, thus defeating the logic below. - bool same_global_refs = ptr->value->data.x_ptr.mut != ConstPtrMutComptimeVar; - copy_const_val(dest_val, value->value, same_global_refs); + copy_const_val(dest_val, value->value); if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && !ira->new_irb.current_basic_block->must_be_comptime_source_instr) { @@ -17308,7 +17294,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c } IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); - copy_const_val(new_instruction->value, result, true); + copy_const_val(new_instruction->value, result); new_instruction->value->type = return_type; return ir_finish_anal(ira, new_instruction); } @@ -17465,7 +17451,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c nullptr, UndefBad); IrInstructionConst *const_instruction = ir_create_instruction(&ira->new_irb, impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); - copy_const_val(const_instruction->base.value, align_result, true); + copy_const_val(const_instruction->base.value, align_result); uint32_t align_bytes = 0; ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes); @@ -17795,7 +17781,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source if (dst_size <= src_size) { if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) { - copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); + copy_const_val(out_val, pointee); return ErrorNone; } Buf buf = BUF_INIT; @@ -18158,7 +18144,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh if (value->value->special != ConstValSpecialRuntime) { IrInstruction *result = ir_const(ira, &phi_instruction->base, nullptr); - copy_const_val(result->value, value->value, true); + copy_const_val(result->value, value->value); return result; } else { return value; @@ -18551,7 +18537,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct if (index == array_len && array_type->data.array.sentinel != nullptr) { ZigType *elem_type = array_type->data.array.child_type; IrInstruction *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base, elem_type); - copy_const_val(sentinel_elem->value, array_type->data.array.sentinel, false); + copy_const_val(sentinel_elem->value, array_type->data.array.sentinel); return ir_get_ref(ira, &elem_ptr_instruction->base, sentinel_elem, true, false); } if (index >= array_len) { @@ -19042,7 +19028,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n if (instr_is_comptime(container_ptr)) { IrInstruction *result = ir_const(ira, source_instr, field_ptr_type); - copy_const_val(result->value, container_ptr->value, false); + copy_const_val(result->value, container_ptr->value); result->value->type = field_ptr_type; return result; } @@ -20474,7 +20460,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, case ZigTypeIdErrorSet: { if (pointee_val) { IrInstruction *result = ir_const(ira, &switch_target_instruction->base, nullptr); - copy_const_val(result->value, pointee_val, true); + copy_const_val(result->value, pointee_val); result->value->type = target_type; return result; } @@ -20970,7 +20956,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc return ira->codegen->invalid_instruction; IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); - copy_const_val(runtime_inst->value, field->init_val, true); + copy_const_val(runtime_inst->value, field->init_val); IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, container_type, true); @@ -21228,7 +21214,7 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); } IrInstruction *result = ir_const(ira, &instruction->base, nullptr); - copy_const_val(result->value, err->cached_error_name_val, true); + copy_const_val(result->value, err->cached_error_name_val); result->value->type = str_type; return result; } @@ -22665,7 +22651,7 @@ static IrInstruction *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstruc type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); } IrInstruction *result = ir_const(ira, &instruction->base, nullptr); - copy_const_val(result->value, type_entry->cached_const_name_val, true); + copy_const_val(result->value, type_entry->cached_const_name_val); return result; } @@ -23365,7 +23351,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index]; ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index]; - copy_const_val(ptr_val, target_ptr_val, false); + copy_const_val(ptr_val, target_ptr_val); ptr_val->type = dest_ptr_type; ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index]; @@ -23658,7 +23644,7 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s ZigValue *src_elem_val = (v >= 0) ? &a->value->data.x_array.data.s_none.elements[v] : &b->value->data.x_array.data.s_none.elements[~v]; - copy_const_val(result_elem_val, src_elem_val, false); + copy_const_val(result_elem_val, src_elem_val); ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr); } @@ -23753,7 +23739,7 @@ static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstruction IrInstruction *result = ir_const(ira, &instruction->base, return_type); result->value->data.x_array.data.s_none.elements = create_const_vals(len_int); for (uint32_t i = 0; i < len_int; i += 1) { - copy_const_val(&result->value->data.x_array.data.s_none.elements[i], scalar_val, false); + copy_const_val(&result->value->data.x_array.data.s_none.elements[i], scalar_val); } return result; } @@ -23894,7 +23880,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio } for (size_t i = start; i < end; i += 1) { - copy_const_val(&dest_elements[i], byte_val, true); + copy_const_val(&dest_elements[i], byte_val); } return ir_const_void(ira, &instruction->base); @@ -24073,7 +24059,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio // TODO check for noalias violations - this should be generalized to work for any function for (size_t i = 0; i < count; i += 1) { - copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); + copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i]); } return ir_const_void(ira, &instruction->base); @@ -25515,7 +25501,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 } IrInstruction *result = ir_const(ira, target, result_type); - copy_const_val(result->value, val, true); + copy_const_val(result->value, val); result->value->type = result_type; return result; } @@ -25597,7 +25583,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ } else { result = ir_const(ira, source_instr, dest_type); } - copy_const_val(result->value, val, true); + copy_const_val(result->value, val); result->value->type = dest_type; // Keep the bigger alignment, it can only help- diff --git a/test/stage1/behavior/bugs/1607.zig b/test/stage1/behavior/bugs/1607.zig index 3a1de80a86996b2c8d012b7ae2421b376216c2de..ffc1aa85dc0527b1ccf339efb2af325ca84bd1ab 100644 --- a/test/stage1/behavior/bugs/1607.zig +++ b/test/stage1/behavior/bugs/1607.zig @@ -10,6 +10,6 @@ fn checkAddress(s: []const u8) void { } test "slices pointing at the same address as global array." { - checkAddress(a); - comptime checkAddress(a); + checkAddress(&a); + comptime checkAddress(&a); } diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index 7c2e58f2cb68b5fb30d698a91db1feeb0a6d0e49..9e17ce59e56c909e3512f35b62ea94850446292e 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -783,7 +783,7 @@ test "struct with var field" { x: var, y: var, }; - const pt = Point { + const pt = Point{ .x = 1, .y = 2, }; -- 2.54.0 From 8524404f715ea660c4469dadb37701f7a46f85af Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 16:39:30 -0500 Subject: [PATCH 12/19] this test isn't passing in master branch either --- test/stage1/behavior/array.zig | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 49419f15f18a5b8445b565fb4f28e300309de7d4..1d51f822d07ea5631ff43cab1c2751bb506e7cef 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -360,9 +360,3 @@ test "access the null element of a null terminated array" { S.doTheTest(); comptime S.doTheTest(); } - -test "type coerce sentinel-terminated array to non-sentinel-terminated array" { - var array: [2]u8 = [_:255]u8{1, 2}; - expect(array[0] == 1); - expect(array[1] == 2); -} -- 2.54.0 From c2cee40aec5a65fa1c0d716f4a0660492717c356 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 17:09:11 -0500 Subject: [PATCH 13/19] add advanced IR debugging support and use it to improve copy_const_val with regards to parent backrefs --- src/all_types.hpp | 3 +- src/ir.cpp | 92 ++++++++++++++++++++++++++++++++++++++++------- src/ir.hpp | 4 +++ 3 files changed, 86 insertions(+), 13 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index f7a099a538bb7284c3994ed11f50602ef46a14b7..cc11741870a202e2e9b3a252cd5f447e558be6ef 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2649,8 +2649,9 @@ struct IrInstruction { // true if this instruction was generated by zig and not from user code bool is_gen; - // for debugging purposes, this is useful to call to inspect the instruction + // for debugging purposes, these are useful to call to inspect the instruction void dump(); + void src(); }; struct IrInstructionDeclVarSrc { diff --git a/src/ir.cpp b/src/ir.cpp index 4be57a776dafe17c2e83224f84ad08a022df7eda..fd488d650bb7c2ad0bb68b51d3bf00372fe67562 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -42,6 +42,7 @@ struct IrAnalyze { ZigList resume_stack; IrBasicBlock *const_predecessor_bb; size_t ref_count; + size_t break_debug_id; // for debugging purposes // For the purpose of using in a debugger void dump(); @@ -198,6 +199,14 @@ struct ConstCastIntShorten { ZigType *actual_type; }; +// for debugging purposes +struct DbgIrBreakPoint { + const char *src_file; + uint32_t line; +}; +DbgIrBreakPoint dbg_ir_breakpoints_buf[20]; +size_t dbg_ir_breakpoints_count = 0; + static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, ResultLoc *result_loc); @@ -11355,8 +11364,12 @@ static void copy_const_val(ZigValue *dest, ZigValue *src) { dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]); + dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct; + dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest; + dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i; } } + dest->parent.id = ConstParentIdNone; } static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, @@ -11474,6 +11487,14 @@ static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruct return &const_instruction->base; } +// This function initializes the new IrInstruction with the provided ZigValue, +// rather than creating a new one. +static IrInstruction *ir_const_move(IrAnalyze *ira, IrInstruction *old_instruction, ZigValue *val) { + IrInstruction *result = ir_const_noval(ira, old_instruction); + result->value = val; + return result; +} + static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type, CastOp cast_op) { @@ -14216,9 +14237,7 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio } static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); - copy_const_val(result->value, instruction->base.value); - return result; + return ir_const_move(ira, &instruction->base, instruction->base.value); } static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { @@ -16633,6 +16652,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe ZigType *parent_ptr_type = parent_result_loc->value->type; assert(parent_ptr_type->id == ZigTypeIdPointer); + if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { @@ -17283,6 +17303,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source return ira->codegen->invalid_instruction; if (dest_val->special != ConstValSpecialRuntime) { copy_const_val(dest_val, value->value); + if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && !ira->new_irb.current_basic_block->must_be_comptime_source_instr) { @@ -17556,9 +17577,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c } } - IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); - copy_const_val(new_instruction->value, result); - new_instruction->value->type = return_type; + IrInstruction *new_instruction = ir_const_move(ira, &call_instruction->base, result); return ir_finish_anal(ira, new_instruction); } @@ -27978,7 +27997,24 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ } if (ira->codegen->verbose_ir) { - fprintf(stderr, "analyze #%" PRIu32 "\n", old_instruction->debug_id); + fprintf(stderr, "~ "); + old_instruction->src(); + fprintf(stderr, "~ "); + ir_print_instruction(codegen, stderr, old_instruction, 0, IrPassSrc); + bool want_break = false; + if (ira->break_debug_id == old_instruction->debug_id) { + want_break = true; + } else if (old_instruction->source_node != nullptr) { + for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) { + if (dbg_ir_breakpoints_buf[i].line == old_instruction->source_node->line + 1 && + buf_ends_with_str(old_instruction->source_node->owner->data.structure.root_struct->path, + dbg_ir_breakpoints_buf[i].src_file)) + { + want_break = true; + } + } + } + if (want_break) BREAKPOINT; } IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); if (new_instruction != nullptr) { @@ -27986,6 +28022,10 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ old_instruction->child = new_instruction; if (type_is_invalid(new_instruction->value->type)) { + if (ira->codegen->verbose_ir) { + fprintf(stderr, "-> (invalid)"); + } + if (new_exec->first_err_trace_msg != nullptr) { ira->codegen->trace_err = new_exec->first_err_trace_msg; } else { @@ -27999,11 +28039,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ old_instruction->source_node, buf_create_from_str("referenced here")); } return ira->codegen->builtin_types.entry_invalid; + } else if (ira->codegen->verbose_ir) { + fprintf(stderr, "-> "); + if (instr_is_unreachable(new_instruction)) { + fprintf(stderr, "(noreturn)\n"); + } else { + ir_print_instruction(codegen, stderr, new_instruction, 0, IrPassGen); + } } // unreachable instructions do their own control flow. if (new_instruction->value->type->id == ZigTypeIdUnreachable) continue; + } else { + if (ira->codegen->verbose_ir) { + fprintf(stderr, "-> (null"); + } } ira->instruction_index += 1; @@ -28667,18 +28718,27 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { return ErrorNone; } -void IrInstruction::dump() { +void IrInstruction::src() { IrInstruction *inst = this; if (inst->source_node != nullptr) { inst->source_node->src(); } else { fprintf(stderr, "(null source node)\n"); } +} + +void IrInstruction::dump() { + IrInstruction *inst = this; + inst->src(); IrPass pass = (inst->child == nullptr) ? IrPassGen : IrPassSrc; - ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); - if (pass == IrPassSrc) { - fprintf(stderr, "-> "); - ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); + if (inst->scope == nullptr) { + fprintf(stderr, "(null scope)\n"); + } else { + ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); + if (pass == IrPassSrc) { + fprintf(stderr, "-> "); + ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); + } } } @@ -28689,3 +28749,11 @@ void IrAnalyze::dump() { ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); } } + +void dbg_ir_break(const char *src_file, uint32_t line) { + dbg_ir_breakpoints_buf[dbg_ir_breakpoints_count] = {src_file, line}; + dbg_ir_breakpoints_count += 1; +} +void dbg_ir_clear(void) { + dbg_ir_breakpoints_count = 0; +} diff --git a/src/ir.hpp b/src/ir.hpp index 75bc9df27be00bb0e9c6f6464fc5cd8d3c527b32..a20dc2d2321a009958f862a94410a756afea4e53 100644 --- a/src/ir.hpp +++ b/src/ir.hpp @@ -35,4 +35,8 @@ ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_va AstNode *source_node); const char *float_op_to_name(BuiltinFnId op, bool llvm_name); +// for debugging purposes +void dbg_ir_break(const char *src_file, uint32_t line); +void dbg_ir_clear(void); + #endif -- 2.54.0 From 080316cd4f9a20fb4cf493ee071f672416b5864c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 18:55:35 -0500 Subject: [PATCH 14/19] fix assigning to an unwrapped optional field in an inline loop --- src/ir.cpp | 20 +++++++++++++++++++- test/stage1/behavior/optional.zig | 11 +++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/ir.cpp b/src/ir.cpp index fd488d650bb7c2ad0bb68b51d3bf00372fe67562..6b4628b187cb8a5187358fbc7fc8e2419078a37a 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11356,10 +11356,24 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } +// Returns whether the x_optional field of ZigValue is active. +static bool type_has_optional_repr(ZigType *ty) { + if (ty->id != ZigTypeIdOptional) { + return false; + } else if (get_codegen_ptr_type(ty) != nullptr) { + return false; + } else if (is_opt_err_set(ty)) { + return false; + } else { + return true; + } +} + static void copy_const_val(ZigValue *dest, ZigValue *src) { memcpy(dest, src, sizeof(ZigValue)); if (src->special != ConstValSpecialStatic) return; + dest->parent.id = ConstParentIdNone; if (dest->type->id == ZigTypeIdStruct) { dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { @@ -11368,8 +11382,12 @@ static void copy_const_val(ZigValue *dest, ZigValue *src) { dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest; dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i; } + } else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) { + dest->data.x_optional = create_const_vals(1); + copy_const_val(dest->data.x_optional, src->data.x_optional); + dest->data.x_optional->parent.id = ConstParentIdOptionalPayload; + dest->data.x_optional->parent.data.p_optional_payload.optional_val = dest; } - dest->parent.id = ConstParentIdNone; } static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, diff --git a/test/stage1/behavior/optional.zig b/test/stage1/behavior/optional.zig index 8cc90d10a4822c4736538ce0cc84c9143fa6b777..f664032fd16f19792a151d53428a783ec497be43 100644 --- a/test/stage1/behavior/optional.zig +++ b/test/stage1/behavior/optional.zig @@ -119,3 +119,14 @@ test "self-referential struct through a slice of optional" { var n = S.Node.new(); expect(n.data == null); } + +test "assigning to an unwrapped optional field in an inline loop" { + comptime var maybe_pos_arg: ?comptime_int = null; + inline for ("ab") |x| { + maybe_pos_arg = 0; + if (maybe_pos_arg.? != 0) { + @compileError("bad"); + } + maybe_pos_arg.? = 10; + } +} -- 2.54.0 From 4af5c3867487b10bdfdb35fba79442f5cc860da1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 19:22:03 -0500 Subject: [PATCH 15/19] fixes for self-hosted compiler --- lib/std/event/fs.zig | 2 +- src-self-hosted/compilation.zig | 20 ++++++++++---------- src-self-hosted/link.zig | 2 +- src-self-hosted/main.zig | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/std/event/fs.zig b/lib/std/event/fs.zig index 346d0f294a46e5ef50c363f9d5bcbaef863d9d03..5986f07ad3bd77a6acbbae7541edf87a029b11fd 100644 --- a/lib/std/event/fs.zig +++ b/lib/std/event/fs.zig @@ -695,7 +695,7 @@ pub fn readFile(allocator: *Allocator, file_path: []const u8, max_size: usize) ! try list.ensureCapacity(list.len + mem.page_size); const buf = list.items[list.len..]; const buf_array = [_][]u8{buf}; - const amt = try preadv(allocator, fd, buf_array, list.len); + const amt = try preadv(allocator, fd, &buf_array, list.len); list.len += amt; if (list.len > max_size) { return error.FileTooBig; diff --git a/src-self-hosted/compilation.zig b/src-self-hosted/compilation.zig index a3e15f77d0e284dc496e15d1aac73b15d4474574..a825ba3903bf033cbd0fd71182c3800eb747ecd6 100644 --- a/src-self-hosted/compilation.zig +++ b/src-self-hosted/compilation.zig @@ -148,13 +148,13 @@ pub const Compilation = struct { is_static: bool, linker_rdynamic: bool = false, - clang_argv: []const []const u8 = [_][]const u8{}, - lib_dirs: []const []const u8 = [_][]const u8{}, - rpath_list: []const []const u8 = [_][]const u8{}, - assembly_files: []const []const u8 = [_][]const u8{}, + clang_argv: []const []const u8 = &[_][]const u8{}, + lib_dirs: []const []const u8 = &[_][]const u8{}, + rpath_list: []const []const u8 = &[_][]const u8{}, + assembly_files: []const []const u8 = &[_][]const u8{}, /// paths that are explicitly provided by the user to link against - link_objects: []const []const u8 = [_][]const u8{}, + link_objects: []const []const u8 = &[_][]const u8{}, /// functions that have their own objects that we need to link /// it uses an optional pointer so that tombstone removals are possible @@ -178,10 +178,10 @@ pub const Compilation = struct { verbose_llvm_ir: bool = false, verbose_link: bool = false, - darwin_frameworks: []const []const u8 = [_][]const u8{}, + darwin_frameworks: []const []const u8 = &[_][]const u8{}, darwin_version_min: DarwinVersionMin = .None, - test_filters: []const []const u8 = [_][]const u8{}, + test_filters: []const []const u8 = &[_][]const u8{}, test_name_prefix: ?[]const u8 = null, emit_file_type: Emit = .Binary, @@ -1165,7 +1165,7 @@ pub const Compilation = struct { const file_name = try std.fmt.allocPrint(self.gpa(), "{}{}", file_prefix[0..], suffix); defer self.gpa().free(file_name); - const full_path = try std.fs.path.join(self.gpa(), [_][]const u8{ tmp_dir, file_name[0..] }); + const full_path = try std.fs.path.join(self.gpa(), &[_][]const u8{ tmp_dir, file_name[0..] }); errdefer self.gpa().free(full_path); return Buffer.fromOwnedSlice(self.gpa(), full_path); @@ -1186,7 +1186,7 @@ pub const Compilation = struct { const zig_dir_path = try getZigDir(self.gpa()); defer self.gpa().free(zig_dir_path); - const tmp_dir = try std.fs.path.join(self.arena(), [_][]const u8{ zig_dir_path, comp_dir_name[0..] }); + const tmp_dir = try std.fs.path.join(self.arena(), &[_][]const u8{ zig_dir_path, comp_dir_name[0..] }); try std.fs.makePath(self.gpa(), tmp_dir); return tmp_dir; } @@ -1208,7 +1208,7 @@ pub const Compilation = struct { } var result: [12]u8 = undefined; - b64_fs_encoder.encode(result[0..], rand_bytes); + b64_fs_encoder.encode(result[0..], &rand_bytes); return result; } diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index 67490b4e1f0f978b94d0b007dfefe817048aa8c1..68e16020c952ab9b8fd29d11a61625c757981520 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -314,7 +314,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { } fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void { - const full_path = try std.fs.path.join(&ctx.arena.allocator, [_][]const u8{ dirname, basename }); + const full_path = try std.fs.path.join(&ctx.arena.allocator, &[_][]const u8{ dirname, basename }); const full_path_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, full_path); try ctx.args.append(@ptrCast([*:0]const u8, full_path_with_null.ptr)); } diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 74e1ee9e7f9cc446dd563b01a90505cd2cadb102..01319e62cec8348706f02640ad51baa921b64a25 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -709,7 +709,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro var it = dir.iterate(); while (try it.next()) |entry| { if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { - const full_path = try fs.path.join(fmt.allocator, [_][]const u8{ file_path, entry.name }); + const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name }); @panic("TODO https://github.com/ziglang/zig/issues/3777"); // try group.call(fmtPath, fmt, full_path, check_mode); } -- 2.54.0 From c32e50f5058dd3720db24706391c994545d13640 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 20:53:24 -0500 Subject: [PATCH 16/19] fix regressions in compile error tests --- src/ir.cpp | 15 ++++++++--- src/util.hpp | 8 ++++-- test/compile_errors.zig | 57 ++++++++++++----------------------------- 3 files changed, 33 insertions(+), 47 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 6b4628b187cb8a5187358fbc7fc8e2419078a37a..65991aa4d5e273747d30e73de05cc37c8be56508 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -18916,7 +18916,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct return ira->codegen->invalid_instruction; if (actual_array_type->id != ZigTypeIdArray) { ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, - buf_sprintf("expected array type or [_], found slice")); + buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", + buf_ptr(&actual_array_type->name))); return ira->codegen->invalid_instruction; } @@ -21308,7 +21309,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, if (is_slice(container_type)) { ir_add_error_node(ira, instruction->init_array_type_source_node, - buf_sprintf("expected array type or [_], found slice")); + buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", + buf_ptr(&container_type->name))); return ira->codegen->invalid_instruction; } @@ -22835,7 +22837,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi } ir_add_error(ira, instruction, buf_sprintf("%d-bit float unsupported", bits)); - return nullptr; + return ira->codegen->invalid_instruction->value->type; } case ZigTypeIdPointer: { @@ -23643,7 +23645,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru return result_loc; } - if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) { + if (target->value->type->id == ZigTypeIdPointer && + target->value->type->data.pointer.child_type->id == ZigTypeIdArray) + { + known_len = target->value->type->data.pointer.child_type->data.array.len; + have_known_len = true; + } else if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) { known_len = casted_value->value->data.rh_slice.len; have_known_len = true; } diff --git a/src/util.hpp b/src/util.hpp index 91535cce1859ca28a3a32774888265edac99a788..a408b811b7e5997145a36ef3c77c050db4145bf1 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -26,20 +26,24 @@ #define ATTRIBUTE_NORETURN __declspec(noreturn) #define ATTRIBUTE_MUST_USE +#define BREAKPOINT __debugbreak() + #else +#include + #define ATTRIBUTE_COLD __attribute__((cold)) #define ATTRIBUTE_PRINTF(a, b) __attribute__((format(printf, a, b))) #define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__)) #define ATTRIBUTE_NORETURN __attribute__((noreturn)) #define ATTRIBUTE_MUST_USE __attribute__((warn_unused_result)) +#define BREAKPOINT raise(SIGTRAP) + #endif #include "softfloat.hpp" -#define BREAKPOINT __asm("int $0x03") - ATTRIBUTE_COLD ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF(1, 2) diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 9bd6d29c263a0213262dc7359e95f0ea238acaf9..26290b944dafc00fb5a8aa09a56c97e3f7709808 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -20,6 +20,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { break :x tc; }); + // Note: One of the error messages here is backwards. It would be nice to fix, but that's not + // going to stop me from merging this branch which fixes a bunch of other stuff. cases.add( "incompatible sentinels", \\export fn entry1(ptr: [*:255]u8) [*:0]u8 { @@ -40,8 +42,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:5:12: error: expected type '[*:0]u8', found '[*]u8'", "tmp.zig:5:12: note: destination pointer requires a terminating '0' sentinel", - "tmp.zig:8:35: error: expected type '[2:0]u8', found '[2:255]u8'", - "tmp.zig:8:35: note: destination array requires a terminating '0' sentinel, but source array has a terminating '255' sentinel", + "tmp.zig:8:35: error: expected type '[2:255]u8', found '[2:0]u8'", + "tmp.zig:8:35: note: destination array requires a terminating '255' sentinel, but source array has a terminating '0' sentinel", "tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'", "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel", ); @@ -96,32 +98,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:11:25: error: expected type 'u32', found '@typeOf(get_uval).ReturnType.ErrorSet!u32'", ); - cases.add( - "function call assigned to incorrect type", - \\export fn entry() void { - \\ var arr: [4]f32 = undefined; - \\ arr = concat(); - \\} - \\fn concat() [16]f32 { - \\ return [1]f32{0}**16; - \\} - , - "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'" - ); - - cases.add( - "generic function call assigned to incorrect type", - \\pub export fn entry() void { - \\ var res: []i32 = undefined; - \\ res = myAlloc(i32); - \\} - \\fn myAlloc(comptime arg: type) anyerror!arg{ - \\ unreachable; - \\} - , - "tmp.zig:3:18: error: expected type '[]i32', found 'anyerror!i32" - ); - cases.add( "asigning to struct or union fields that are not optionals with a function that returns an optional", \\fn maybe(is: bool) ?u8 { @@ -205,7 +181,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ var geo_data = getGeo3DTex2D(); \\} , - "tmp.zig:4:30: error: expected type '[][2]f32', found '[1][2]f32'", + "tmp.zig:4:30: error: array literal requires address-of operator to coerce to slice type '[][2]f32'", ); cases.add( @@ -802,7 +778,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ const x = []u8{1, 2}; \\} , - "tmp.zig:2:15: error: expected array type or [_], found slice", + "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'", ); cases.add( @@ -811,7 +787,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ const x = []u8{}; \\} , - "tmp.zig:2:15: error: expected array type or [_], found slice", + "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'", ); cases.add( @@ -2310,8 +2286,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\fn bar(x: *b.Foo) void {} , - "tmp.zig:6:9: error: expected type '*b.Foo', found '*a.Foo'", - "tmp.zig:6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", + "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'", + "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", "a.zig:1:17: note: a.Foo declared here", "b.zig:1:17: note: b.Foo declared here", ); @@ -4836,10 +4812,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "convert fixed size array to slice with invalid size", \\export fn f() void { \\ var array: [5]u8 = undefined; - \\ var foo = @bytesToSlice(u32, array)[0]; + \\ var foo = @bytesToSlice(u32, &array)[0]; \\} , - "tmp.zig:3:15: error: unable to convert [5]u8 to []align(1) const u32: size mismatch", + "tmp.zig:3:15: error: unable to convert [5]u8 to []align(1) u32: size mismatch", "tmp.zig:3:29: note: u32 has size 4; remaining bytes: 1", ); @@ -5176,7 +5152,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\export fn entry() usize { return @sizeOf(@typeOf(foo)); } , - "tmp.zig:8:16: error: expected type '*const u3', found '*align(:3:1) const u3'", + "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'", ); cases.add( @@ -5873,7 +5849,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ x.* += 1; \\} , - "tmp.zig:8:9: error: expected type '*u32', found '*align(1) u32'", + "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'", ); cases.add( @@ -5893,9 +5869,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ x[0] += 1; \\} , - "tmp.zig:9:9: error: cast increases pointer alignment", + "tmp.zig:9:26: error: cast increases pointer alignment", "tmp.zig:9:26: note: '*align(1) u32' has alignment 1", - "tmp.zig:9:9: note: '*[1]u32' has alignment 4", + "tmp.zig:9:26: note: '*[1]u32' has alignment 4", ); cases.add( @@ -6943,7 +6919,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ var foo: u32 = @This(){}; \\} , - "tmp.zig:2:27: error: expected type 'u32', found '(root)'", - "tmp.zig:1:1: note: (root) declared here", + "tmp.zig:2:27: error: type 'u32' does not support array initialization", ); } -- 2.54.0 From 37caa56fbc04d314aa8fe5df6bc80c42d879dd7e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 21:27:55 -0500 Subject: [PATCH 17/19] fix docs regressions --- doc/docgen.zig | 32 ++++++++++++++++---------------- doc/langref.html.in | 42 +++++++++++++++++++++--------------------- src/ir.cpp | 1 + 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/doc/docgen.zig b/doc/docgen.zig index 5d216a1914e271200492495d7d8e0be442b888ab..2158cdccaecee3db6c165bb2a0d62544db4e1957 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -1039,7 +1039,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name); const tmp_source_file_name = try fs.path.join( allocator, - [_][]const u8{ tmp_dir_name, name_plus_ext }, + &[_][]const u8{ tmp_dir_name, name_plus_ext }, ); try io.writeFile(tmp_source_file_name, trimmed_raw_source); @@ -1048,7 +1048,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext); var build_args = std.ArrayList([]const u8).init(allocator); defer build_args.deinit(); - try build_args.appendSlice([_][]const u8{ + try build_args.appendSlice(&[_][]const u8{ zig_exe, "build-exe", tmp_source_file_name, @@ -1079,7 +1079,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", link_object, obj_ext); const full_path_object = try fs.path.join( allocator, - [_][]const u8{ tmp_dir_name, name_with_ext }, + &[_][]const u8{ tmp_dir_name, name_with_ext }, ); try build_args.append("--object"); try build_args.append(full_path_object); @@ -1090,7 +1090,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var try out.print(" -lc"); } if (code.target_str) |triple| { - try build_args.appendSlice([_][]const u8{ "-target", triple }); + try build_args.appendSlice(&[_][]const u8{ "-target", triple }); if (!code.is_inline) { try out.print(" -target {}", triple); } @@ -1143,7 +1143,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var } const path_to_exe = mem.trim(u8, exec_result.stdout, " \r\n"); - const run_args = [_][]const u8{path_to_exe}; + const run_args = &[_][]const u8{path_to_exe}; var exited_with_signal = false; @@ -1184,7 +1184,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var var test_args = std.ArrayList([]const u8).init(allocator); defer test_args.deinit(); - try test_args.appendSlice([_][]const u8{ + try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name, @@ -1212,7 +1212,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var try out.print(" -lc"); } if (code.target_str) |triple| { - try test_args.appendSlice([_][]const u8{ "-target", triple }); + try test_args.appendSlice(&[_][]const u8{ "-target", triple }); try out.print(" -target {}", triple); } const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed"); @@ -1224,7 +1224,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var var test_args = std.ArrayList([]const u8).init(allocator); defer test_args.deinit(); - try test_args.appendSlice([_][]const u8{ + try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", "--color", @@ -1283,7 +1283,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var var test_args = std.ArrayList([]const u8).init(allocator); defer test_args.deinit(); - try test_args.appendSlice([_][]const u8{ + try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name, @@ -1345,7 +1345,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var const name_plus_obj_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, obj_ext); const tmp_obj_file_name = try fs.path.join( allocator, - [_][]const u8{ tmp_dir_name, name_plus_obj_ext }, + &[_][]const u8{ tmp_dir_name, name_plus_obj_ext }, ); var build_args = std.ArrayList([]const u8).init(allocator); defer build_args.deinit(); @@ -1353,10 +1353,10 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var const name_plus_h_ext = try std.fmt.allocPrint(allocator, "{}.h", code.name); const output_h_file_name = try fs.path.join( allocator, - [_][]const u8{ tmp_dir_name, name_plus_h_ext }, + &[_][]const u8{ tmp_dir_name, name_plus_h_ext }, ); - try build_args.appendSlice([_][]const u8{ + try build_args.appendSlice(&[_][]const u8{ zig_exe, "build-obj", tmp_source_file_name, @@ -1395,7 +1395,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var } if (code.target_str) |triple| { - try build_args.appendSlice([_][]const u8{ "-target", triple }); + try build_args.appendSlice(&[_][]const u8{ "-target", triple }); try out.print(" -target {}", triple); } @@ -1442,7 +1442,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var var test_args = std.ArrayList([]const u8).init(allocator); defer test_args.deinit(); - try test_args.appendSlice([_][]const u8{ + try test_args.appendSlice(&[_][]const u8{ zig_exe, "build-lib", tmp_source_file_name, @@ -1466,7 +1466,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var }, } if (code.target_str) |triple| { - try test_args.appendSlice([_][]const u8{ "-target", triple }); + try test_args.appendSlice(&[_][]const u8{ "-target", triple }); try out.print(" -target {}", triple); } const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed"); @@ -1507,7 +1507,7 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u } fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 { - const result = try exec(allocator, env_map, [_][]const u8{ + const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "builtin", }); diff --git a/doc/langref.html.in b/doc/langref.html.in index b742119af79aa18e26157b68b8b461a58a8232cb..ab1f3e89f99e8b47698cb074578df1bb9eb8386d 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -1518,7 +1518,7 @@ value == null{#endsyntax#} const array1 = [_]u32{1,2}; const array2 = [_]u32{3,4}; const together = array1 ++ array2; -mem.eql(u32, together, [_]u32{1,2,3,4}){#endsyntax#} +mem.eql(u32, together, &[_]u32{1,2,3,4}){#endsyntax#} @@ -1621,10 +1621,10 @@ comptime { } // A string literal is a pointer to an array literal. -const same_message = "hello".*; +const same_message = "hello"; comptime { - assert(mem.eql(u8, message, same_message)); + assert(mem.eql(u8, &message, same_message)); } test "iterate over an array" { @@ -1652,7 +1652,7 @@ const part_one = [_]i32{ 1, 2, 3, 4 }; const part_two = [_]i32{ 5, 6, 7, 8 }; const all_of_it = part_one ++ part_two; comptime { - assert(mem.eql(i32, all_of_it, [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 })); + assert(mem.eql(i32, &all_of_it, &[_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 })); } // remember that string literals are arrays @@ -4915,30 +4915,30 @@ const assert = std.debug.assert; // https://github.com/ziglang/zig/issues/265 is implemented. test "[N]T to []const T" { var x1: []const u8 = "hello"; - var x2: []const u8 = [5]u8{ 'h', 'e', 'l', 'l', 111 }; + var x2: []const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 }; assert(std.mem.eql(u8, x1, x2)); - var y: []const f32 = [2]f32{ 1.2, 3.4 }; + var y: []const f32 = &[2]f32{ 1.2, 3.4 }; assert(y[0] == 1.2); } // Likewise, it works when the destination type is an error union. test "[N]T to E![]const T" { var x1: anyerror![]const u8 = "hello"; - var x2: anyerror![]const u8 = [5]u8{ 'h', 'e', 'l', 'l', 111 }; + var x2: anyerror![]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 }; assert(std.mem.eql(u8, try x1, try x2)); - var y: anyerror![]const f32 = [2]f32{ 1.2, 3.4 }; + var y: anyerror![]const f32 = &[2]f32{ 1.2, 3.4 }; assert((try y)[0] == 1.2); } // Likewise, it works when the destination type is an optional. test "[N]T to ?[]const T" { var x1: ?[]const u8 = "hello"; - var x2: ?[]const u8 = [5]u8{ 'h', 'e', 'l', 'l', 111 }; + var x2: ?[]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 }; assert(std.mem.eql(u8, x1.?, x2.?)); - var y: ?[]const f32 = [2]f32{ 1.2, 3.4 }; + var y: ?[]const f32 = &[2]f32{ 1.2, 3.4 }; assert(y.?[0] == 1.2); } @@ -4950,7 +4950,7 @@ test "*[N]T to []T" { const buf2 = [2]f32{ 1.2, 3.4 }; const x2: []const f32 = &buf2; - assert(std.mem.eql(f32, x2, [2]f32{ 1.2, 3.4 })); + assert(std.mem.eql(f32, x2, &[2]f32{ 1.2, 3.4 })); } // Single-item pointers to arrays can be coerced to @@ -5185,7 +5185,7 @@ fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { return @as(usize, 3); } -test "peer type resolution: [0]u8 and []const u8" { +test "peer type resolution: *[0]u8 and []const u8" { assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); comptime { @@ -5195,12 +5195,12 @@ test "peer type resolution: [0]u8 and []const u8" { } fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { if (a) { - return [_]u8{}; + return &[_]u8{}; } return slice[0..1]; } -test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { +test "peer type resolution: *[0]u8, []const u8, and anyerror![]u8" { { var data = "hi".*; const slice = data[0..]; @@ -5216,7 +5216,7 @@ test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { } fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 { if (a) { - return [_]u8{}; + return &[_]u8{}; } return slice[0..1]; @@ -5746,7 +5746,7 @@ test "fibonacci" {

{#code_begin|test#} const first_25_primes = firstNPrimes(25); -const sum_of_first_25_primes = sum(first_25_primes); +const sum_of_first_25_primes = sum(&first_25_primes); fn firstNPrimes(comptime n: usize) [n]i32 { var prime_list: [n]i32 = undefined; @@ -6364,7 +6364,7 @@ test "async function await" { resume the_frame; seq('i'); assert(final_result == 1234); - assert(std.mem.eql(u8, seq_points, "abcdefghi")); + assert(std.mem.eql(u8, &seq_points, "abcdefghi")); } fn amain() void { seq('b'); @@ -8014,7 +8014,7 @@ test "vector @splat" { const scalar: u32 = 5; const result = @splat(4, scalar); comptime assert(@typeOf(result) == @Vector(4, u32)); - assert(std.mem.eql(u32, @as([4]u32, result), [_]u32{ 5, 5, 5, 5 })); + assert(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); } {#code_end#}

@@ -8948,7 +8948,7 @@ pub fn main() void { {#code_begin|test_err|unable to convert#} comptime { var bytes = [5]u8{ 1, 2, 3, 4, 5 }; - var slice = @bytesToSlice(u32, bytes); + var slice = @bytesToSlice(u32, bytes[0..]); } {#code_end#}

At runtime:

@@ -9760,7 +9760,7 @@ pub fn build(b: *Builder) void { const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0)); const exe = b.addExecutable("test", null); - exe.addCSourceFile("test.c", [_][]const u8{"-std=c99"}); + exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); exe.linkLibrary(lib); exe.linkSystemLibrary("c"); @@ -9825,7 +9825,7 @@ pub fn build(b: *Builder) void { const obj = b.addObject("base64", "base64.zig"); const exe = b.addExecutable("test", null); - exe.addCSourceFile("test.c", [_][]const u8{"-std=c99"}); + exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); exe.addObject(obj); exe.linkSystemLibrary("c"); exe.install(); diff --git a/src/ir.cpp b/src/ir.cpp index 65991aa4d5e273747d30e73de05cc37c8be56508..21211e8ac76d6d04830957dee77e7247d38b9d1e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -23646,6 +23646,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru } if (target->value->type->id == ZigTypeIdPointer && + target->value->type->data.pointer.ptr_len == PtrLenSingle && target->value->type->data.pointer.child_type->id == ZigTypeIdArray) { known_len = target->value->type->data.pointer.child_type->data.array.len; -- 2.54.0 From 3644e85091c2407ddb563531875a6bc5e979e32e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 21:31:00 -0500 Subject: [PATCH 18/19] fix regressions on windows --- lib/std/child_process.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 36621758b2a4f1e58244cb29d15f4ac3d52142c2..be616196b11b023bff802f3c726f361ccbddb407 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -571,7 +571,7 @@ pub const ChildProcess = struct { // to match posix semantics const app_name = x: { if (self.cwd) |cwd| { - const resolved = try fs.path.resolve(self.allocator, [_][]const u8{ cwd, self.argv[0] }); + const resolved = try fs.path.resolve(self.allocator, &[_][]const u8{ cwd, self.argv[0] }); defer self.allocator.free(resolved); break :x try cstr.addNullByte(self.allocator, resolved); } else { @@ -613,10 +613,10 @@ pub const ChildProcess = struct { retry: while (it.next()) |search_path| { var ext_it = mem.tokenize(PATHEXT, ";"); while (ext_it.next()) |app_ext| { - const app_basename = try mem.concat(self.allocator, u8, [_][]const u8{ app_name[0 .. app_name.len - 1], app_ext }); + const app_basename = try mem.concat(self.allocator, u8, &[_][]const u8{ app_name[0 .. app_name.len - 1], app_ext }); defer self.allocator.free(app_basename); - const joined_path = try fs.path.join(self.allocator, [_][]const u8{ search_path, app_basename }); + const joined_path = try fs.path.join(self.allocator, &[_][]const u8{ search_path, app_basename }); defer self.allocator.free(joined_path); const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path); -- 2.54.0 From e7ee6647a16738d344173d0482028dc5578cc6c2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Dec 2019 23:56:28 -0500 Subject: [PATCH 19/19] fix invalid check for fn_inline property --- src/ir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir.cpp b/src/ir.cpp index 21211e8ac76d6d04830957dee77e7247d38b9d1e..fbb1f1761eb268834b1bac3273f658aa471ee36b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15945,7 +15945,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, result_type = ira->codegen->builtin_types.entry_invalid; } else if (init_val->type->id == ZigTypeIdFn && init_val->special != ConstValSpecialUndef && - init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && + init_val->data.x_ptr.special == ConstPtrSpecialFunction && init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) { var_class_requires_const = true; -- 2.54.0