Commit 902df103c6

Andrew Kelley <andrew@ziglang.org>
2021-11-30 08:13:07
std lib API deprecations for the upcoming 0.9.0 release
See #3811
1 parent 173d562
doc/langref.html.in
@@ -5708,7 +5708,7 @@ const mem = std.mem;
 test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
     const window_name = [1][*]const u8{"window name"};
     const x: [*]const ?[*]const u8 = &window_name;
-    try expect(mem.eql(u8, std.mem.spanZ(@ptrCast([*:0]const u8, x[0].?)), "window name"));
+    try expect(mem.eql(u8, std.mem.sliceTo(@ptrCast([*:0]const u8, x[0].?), 0), "window name"));
 }
       {#code_end#}
       {#header_close#}
@@ -7364,7 +7364,7 @@ fn amain() !void {
 var global_download_frame: anyframe = undefined;
 fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
     _ = url; // this is just an example, we don't actually do it!
-    const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents");
+    const result = try allocator.dupe(u8, "this is the downloaded url contents");
     errdefer allocator.free(result);
     suspend {
         global_download_frame = @frame();
@@ -7376,7 +7376,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
 var global_file_frame: anyframe = undefined;
 fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
     _ = filename; // this is just an example, we don't actually do it!
-    const result = try std.mem.dupe(allocator, u8, "this is the file contents");
+    const result = try allocator.dupe(u8, "this is the file contents");
     errdefer allocator.free(result);
     suspend {
         global_file_frame = @frame();
@@ -7435,7 +7435,7 @@ fn amain() !void {
 
 fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
     _ = url; // this is just an example, we don't actually do it!
-    const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents");
+    const result = try allocator.dupe(u8, "this is the downloaded url contents");
     errdefer allocator.free(result);
     std.debug.print("fetchUrl returning\n", .{});
     return result;
@@ -7443,7 +7443,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
 
 fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
     _ = filename; // this is just an example, we don't actually do it!
-    const result = try std.mem.dupe(allocator, u8, "this is the file contents");
+    const result = try allocator.dupe(u8, "this is the file contents");
     errdefer allocator.free(result);
     std.debug.print("readFile returning\n", .{});
     return result;
lib/std/build/CheckFileStep.zig
@@ -4,7 +4,6 @@ const Step = build.Step;
 const Builder = build.Builder;
 const fs = std.fs;
 const mem = std.mem;
-const warn = std.debug.warn;
 
 const CheckFileStep = @This();
 
@@ -40,7 +39,7 @@ fn make(step: *Step) !void {
 
     for (self.expected_matches) |expected_match| {
         if (mem.indexOf(u8, contents, expected_match) == null) {
-            warn(
+            std.debug.print(
                 \\
                 \\========= Expected to find: ===================
                 \\{s}
lib/std/build/InstallRawStep.zig
@@ -12,7 +12,6 @@ const elf = std.elf;
 const fs = std.fs;
 const io = std.io;
 const sort = std.sort;
-const warn = std.debug.warn;
 
 const BinaryElfSection = struct {
     elfOffset: u64,
@@ -387,7 +386,7 @@ fn make(step: *Step) !void {
     const builder = self.builder;
 
     if (self.artifact.target.getObjectFormat() != .elf) {
-        warn("InstallRawStep only works with ELF format.\n", .{});
+        std.debug.print("InstallRawStep only works with ELF format.\n", .{});
         return error.InvalidObjectFormat;
     }
 
lib/std/build/RunStep.zig
@@ -10,7 +10,6 @@ const mem = std.mem;
 const process = std.process;
 const ArrayList = std.ArrayList;
 const BufMap = std.BufMap;
-const warn = std.debug.warn;
 
 const max_stdout_size = 1 * 1024 * 1024; // 1 MiB
 
@@ -189,7 +188,7 @@ fn make(step: *Step) !void {
         printCmd(cwd, argv);
 
     child.spawn() catch |err| {
-        warn("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) });
+        std.debug.print("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) });
         return err;
     };
 
@@ -216,7 +215,7 @@ fn make(step: *Step) !void {
     }
 
     const term = child.wait() catch |err| {
-        warn("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) });
+        std.debug.print("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) });
         return err;
     };
 
@@ -224,12 +223,12 @@ fn make(step: *Step) !void {
         .Exited => |code| {
             if (code != self.expected_exit_code) {
                 if (self.builder.prominent_compile_errors) {
-                    warn("Run step exited with error code {} (expected {})\n", .{
+                    std.debug.print("Run step exited with error code {} (expected {})\n", .{
                         code,
                         self.expected_exit_code,
                     });
                 } else {
-                    warn("The following command exited with error code {} (expected {}):\n", .{
+                    std.debug.print("The following command exited with error code {} (expected {}):\n", .{
                         code,
                         self.expected_exit_code,
                     });
@@ -240,7 +239,7 @@ fn make(step: *Step) !void {
             }
         },
         else => {
-            warn("The following command terminated unexpectedly:\n", .{});
+            std.debug.print("The following command terminated unexpectedly:\n", .{});
             printCmd(cwd, argv);
             return error.UncleanExit;
         },
@@ -250,7 +249,7 @@ fn make(step: *Step) !void {
         .inherit, .ignore => {},
         .expect_exact => |expected_bytes| {
             if (!mem.eql(u8, expected_bytes, stderr.?)) {
-                warn(
+                std.debug.print(
                     \\
                     \\========= Expected this stderr: =========
                     \\{s}
@@ -264,7 +263,7 @@ fn make(step: *Step) !void {
         },
         .expect_matches => |matches| for (matches) |match| {
             if (mem.indexOf(u8, stderr.?, match) == null) {
-                warn(
+                std.debug.print(
                     \\
                     \\========= Expected to find in stderr: =========
                     \\{s}
@@ -282,7 +281,7 @@ fn make(step: *Step) !void {
         .inherit, .ignore => {},
         .expect_exact => |expected_bytes| {
             if (!mem.eql(u8, expected_bytes, stdout.?)) {
-                warn(
+                std.debug.print(
                     \\
                     \\========= Expected this stdout: =========
                     \\{s}
@@ -296,7 +295,7 @@ fn make(step: *Step) !void {
         },
         .expect_matches => |matches| for (matches) |match| {
             if (mem.indexOf(u8, stdout.?, match) == null) {
-                warn(
+                std.debug.print(
                     \\
                     \\========= Expected to find in stdout: =========
                     \\{s}
@@ -312,11 +311,11 @@ fn make(step: *Step) !void {
 }
 
 fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void {
-    if (cwd) |yes_cwd| warn("cd {s} && ", .{yes_cwd});
+    if (cwd) |yes_cwd| std.debug.print("cd {s} && ", .{yes_cwd});
     for (argv) |arg| {
-        warn("{s} ", .{arg});
+        std.debug.print("{s} ", .{arg});
     }
-    warn("\n", .{});
+    std.debug.print("\n", .{});
 }
 
 fn addPathForDynLibs(self: *RunStep, artifact: *LibExeObjStep) void {
lib/std/build/WriteFileStep.zig
@@ -3,7 +3,6 @@ const build = @import("../build.zig");
 const Step = build.Step;
 const Builder = build.Builder;
 const fs = std.fs;
-const warn = std.debug.warn;
 const ArrayList = std.ArrayList;
 
 const WriteFileStep = @This();
@@ -91,7 +90,7 @@ fn make(step: *Step) !void {
     });
     // TODO replace with something like fs.makePathAndOpenDir
     fs.cwd().makePath(self.output_dir) catch |err| {
-        warn("unable to make path {s}: {s}\n", .{ self.output_dir, @errorName(err) });
+        std.debug.print("unable to make path {s}: {s}\n", .{ self.output_dir, @errorName(err) });
         return err;
     };
     var dir = try fs.cwd().openDir(self.output_dir, .{});
@@ -100,7 +99,7 @@ fn make(step: *Step) !void {
         var it = self.files.first;
         while (it) |node| : (it = node.next) {
             dir.writeFile(node.data.basename, node.data.bytes) catch |err| {
-                warn("unable to write {s} into {s}: {s}\n", .{
+                std.debug.print("unable to write {s} into {s}: {s}\n", .{
                     node.data.basename,
                     self.output_dir,
                     @errorName(err),
lib/std/c/tokenizer.zig
@@ -126,7 +126,7 @@ pub const Token = struct {
         Keyword_error,
         Keyword_pragma,
 
-        pub fn symbol(id: std.meta.TagType(Id)) []const u8 {
+        pub fn symbol(id: std.meta.Tag(Id)) []const u8 {
             return switch (id) {
                 .Invalid => "Invalid",
                 .Eof => "Eof",
@@ -342,7 +342,7 @@ pub const Token = struct {
 pub const Tokenizer = struct {
     buffer: []const u8,
     index: usize = 0,
-    prev_tok_id: std.meta.TagType(Token.Id) = .Invalid,
+    prev_tok_id: std.meta.Tag(Token.Id) = .Invalid,
     pp_directive: bool = false,
 
     pub fn next(self: *Tokenizer) Token {
lib/std/crypto/benchmark.zig
@@ -343,7 +343,7 @@ fn benchmarkPwhash(
 }
 
 fn usage() void {
-    std.debug.warn(
+    std.debug.print(
         \\throughput_test [options]
         \\
         \\Options:
lib/std/fs/get_app_data_dir.zig
@@ -24,7 +24,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
             )) {
                 os.windows.S_OK => {
                     defer os.windows.ole32.CoTaskMemFree(@ptrCast(*c_void, dir_path_ptr));
-                    const global_dir = unicode.utf16leToUtf8Alloc(allocator, mem.spanZ(dir_path_ptr)) catch |err| switch (err) {
+                    const global_dir = unicode.utf16leToUtf8Alloc(allocator, mem.sliceTo(dir_path_ptr, 0)) catch |err| switch (err) {
                         error.UnexpectedSecondSurrogateHalf => return error.AppDataDirUnavailable,
                         error.ExpectedSecondSurrogateHalf => return error.AppDataDirUnavailable,
                         error.DanglingSurrogateHalf => return error.AppDataDirUnavailable,
@@ -56,7 +56,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
             // TODO look into directory_which
             const be_user_settings = 0xbbe;
             const rc = os.system.find_directory(be_user_settings, -1, true, dir_path_ptr, 1);
-            const settings_dir = try allocator.dupeZ(u8, mem.spanZ(dir_path_ptr));
+            const settings_dir = try allocator.dupeZ(u8, mem.sliceTo(dir_path_ptr, 0));
             defer allocator.free(settings_dir);
             switch (rc) {
                 0 => return fs.path.join(allocator, &[_][]const u8{ settings_dir, appname }),
lib/std/fs/path.zig
@@ -187,8 +187,6 @@ test "join" {
     }
 }
 
-pub const isAbsoluteC = @compileError("deprecated: renamed to isAbsoluteZ");
-
 pub fn isAbsoluteZ(path_c: [*:0]const u8) bool {
     if (native_os == .windows) {
         return isAbsoluteWindowsZ(path_c);
@@ -233,27 +231,23 @@ pub fn isAbsoluteWindows(path: []const u8) bool {
 }
 
 pub fn isAbsoluteWindowsW(path_w: [*:0]const u16) bool {
-    return isAbsoluteWindowsImpl(u16, mem.spanZ(path_w));
+    return isAbsoluteWindowsImpl(u16, mem.sliceTo(path_w, 0));
 }
 
 pub fn isAbsoluteWindowsWTF16(path: []const u16) bool {
     return isAbsoluteWindowsImpl(u16, path);
 }
 
-pub const isAbsoluteWindowsC = @compileError("deprecated: renamed to isAbsoluteWindowsZ");
-
 pub fn isAbsoluteWindowsZ(path_c: [*:0]const u8) bool {
-    return isAbsoluteWindowsImpl(u8, mem.spanZ(path_c));
+    return isAbsoluteWindowsImpl(u8, mem.sliceTo(path_c, 0));
 }
 
 pub fn isAbsolutePosix(path: []const u8) bool {
     return path.len > 0 and path[0] == sep_posix;
 }
 
-pub const isAbsolutePosixC = @compileError("deprecated: renamed to isAbsolutePosixZ");
-
 pub fn isAbsolutePosixZ(path_c: [*:0]const u8) bool {
-    return isAbsolutePosix(mem.spanZ(path_c));
+    return isAbsolutePosix(mem.sliceTo(path_c, 0));
 }
 
 test "isAbsoluteWindows" {
lib/std/hash/benchmark.zig
@@ -142,7 +142,7 @@ pub fn benchmarkHashSmallKeys(comptime H: anytype, key_size: usize, bytes: usize
 }
 
 fn usage() void {
-    std.debug.warn(
+    std.debug.print(
         \\throughput_test [options]
         \\
         \\Options:
lib/std/io/reader.zig
@@ -45,10 +45,10 @@ pub fn Reader(
             if (amt_read < buf.len) return error.EndOfStream;
         }
 
-        pub const readAllBuffer = @compileError("deprecated; use readAllArrayList()");
-
-        /// Appends to the `std.ArrayList` contents by reading from the stream until end of stream is found.
-        /// If the number of bytes appended would exceed `max_append_size`, `error.StreamTooLong` is returned
+        /// Appends to the `std.ArrayList` contents by reading from the stream
+        /// until end of stream is found.
+        /// If the number of bytes appended would exceed `max_append_size`,
+        /// `error.StreamTooLong` is returned
         /// and the `std.ArrayList` has exactly `max_append_size` bytes appended.
         pub fn readAllArrayList(self: Self, array_list: *std.ArrayList(u8), max_append_size: usize) !void {
             return self.readAllArrayListAligned(null, array_list, max_append_size);
lib/std/math/big/int.zig
@@ -185,9 +185,9 @@ pub const Mutable = struct {
 
     pub fn dump(self: Mutable) void {
         for (self.limbs[0..self.len]) |limb| {
-            std.debug.warn("{x} ", .{limb});
+            std.debug.print("{x} ", .{limb});
         }
-        std.debug.warn("capacity={} positive={}\n", .{ self.limbs.len, self.positive });
+        std.debug.print("capacity={} positive={}\n", .{ self.limbs.len, self.positive });
     }
 
     /// Clones an Mutable and returns a new Mutable with the same value. The new Mutable is a deep copy and
@@ -1685,9 +1685,9 @@ pub const Const = struct {
 
     pub fn dump(self: Const) void {
         for (self.limbs[0..self.limbs.len]) |limb| {
-            std.debug.warn("{x} ", .{limb});
+            std.debug.print("{x} ", .{limb});
         }
-        std.debug.warn("positive={}\n", .{self.positive});
+        std.debug.print("positive={}\n", .{self.positive});
     }
 
     pub fn abs(self: Const) Const {
@@ -2237,9 +2237,9 @@ pub const Managed = struct {
     /// Debugging tool: prints the state to stderr.
     pub fn dump(self: Managed) void {
         for (self.limbs[0..self.len()]) |limb| {
-            std.debug.warn("{x} ", .{limb});
+            std.debug.print("{x} ", .{limb});
         }
-        std.debug.warn("capacity={} positive={}\n", .{ self.limbs.len, self.isPositive() });
+        std.debug.print("capacity={} positive={}\n", .{ self.limbs.len, self.isPositive() });
     }
 
     /// Negate the sign.
lib/std/math/complex.zig
@@ -34,8 +34,7 @@ pub fn Complex(comptime T: type) type {
         /// Imaginary part.
         im: T,
 
-        /// Deprecated, use init()
-        pub const new = init;
+        pub const new = @compileError("deprecated; use init()");
 
         /// Create a new Complex number from the given real and imaginary parts.
         pub fn init(re: T, im: T) Self {
lib/std/mem/Allocator.zig
@@ -235,7 +235,6 @@ pub fn allocSentinel(
     return self.allocWithOptionsRetAddr(Elem, n, null, sentinel, @returnAddress());
 }
 
-/// Deprecated: use `allocAdvanced`
 pub fn alignedAlloc(
     self: *Allocator,
     comptime T: type,
lib/std/meta/trait.zig
@@ -2,7 +2,6 @@ const std = @import("../std.zig");
 const mem = std.mem;
 const debug = std.debug;
 const testing = std.testing;
-const warn = debug.warn;
 
 const meta = @import("../meta.zig");
 
lib/std/os/linux/vdso.zig
@@ -69,7 +69,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
         if (0 == (@as(u32, 1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue;
         if (0 == syms[i].st_shndx) continue;
         const sym_name = std.meta.assumeSentinel(strings + syms[i].st_name, 0);
-        if (!mem.eql(u8, name, mem.spanZ(sym_name))) continue;
+        if (!mem.eql(u8, name, mem.sliceTo(sym_name, 0))) continue;
         if (maybe_versym) |versym| {
             if (!checkver(maybe_verdef.?, versym[i], vername, strings))
                 continue;
@@ -92,5 +92,5 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
     }
     const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);
     const vda_name = std.meta.assumeSentinel(strings + aux.vda_name, 0);
-    return mem.eql(u8, vername, mem.spanZ(vda_name));
+    return mem.eql(u8, vername, mem.sliceTo(vda_name, 0));
 }
lib/std/os/windows.zig
@@ -813,7 +813,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin
             return parseReadlinkPath(path_buf[offset .. offset + len], false, out_buffer);
         },
         else => |value| {
-            std.debug.warn("unsupported symlink type: {}", .{value});
+            std.debug.print("unsupported symlink type: {}", .{value});
             return error.UnsupportedReparsePointType;
         },
     }
@@ -1862,7 +1862,7 @@ pub fn normalizePath(comptime T: type, path: []T) RemoveDotDirsError!usize {
 /// Same as `sliceToPrefixedFileW` but accepts a pointer
 /// to a null-terminated path.
 pub fn cStrToPrefixedFileW(s: [*:0]const u8) !PathSpace {
-    return sliceToPrefixedFileW(mem.spanZ(s));
+    return sliceToPrefixedFileW(mem.sliceTo(s, 0));
 }
 
 /// Converts the path `s` to WTF16, null-terminated. If the path is absolute,
@@ -1995,7 +1995,7 @@ pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
             null,
         );
         _ = std.unicode.utf16leToUtf8(&buf_utf8, buf_wstr[0..len]) catch unreachable;
-        std.debug.warn("error.Unexpected: GetLastError({}): {s}\n", .{ @enumToInt(err), buf_utf8[0..len] });
+        std.debug.print("error.Unexpected: GetLastError({}): {s}\n", .{ @enumToInt(err), buf_utf8[0..len] });
         std.debug.dumpCurrentStackTrace(null);
     }
     return error.Unexpected;
@@ -2009,7 +2009,7 @@ pub fn unexpectedWSAError(err: ws2_32.WinsockError) std.os.UnexpectedError {
 /// and you get an unexpected status.
 pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError {
     if (std.os.unexpected_error_tracing) {
-        std.debug.warn("error.Unexpected NTSTATUS=0x{x}\n", .{@enumToInt(status)});
+        std.debug.print("error.Unexpected NTSTATUS=0x{x}\n", .{@enumToInt(status)});
         std.debug.dumpCurrentStackTrace(null);
     }
     return error.Unexpected;
lib/std/special/compiler_rt/fixdfdi_test.zig
@@ -2,16 +2,13 @@ const __fixdfdi = @import("fixdfdi.zig").__fixdfdi;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixdfdi(a: f64, expected: i64) !void {
     const x = __fixdfdi(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", .{a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixdfdi" {
-    //warn("\n", .{});
     try test__fixdfdi(-math.f64_max, math.minInt(i64));
 
     try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
lib/std/special/compiler_rt/fixdfsi_test.zig
@@ -2,16 +2,13 @@ const __fixdfsi = @import("fixdfsi.zig").__fixdfsi;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixdfsi(a: f64, expected: i32) !void {
     const x = __fixdfsi(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", .{a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixdfsi" {
-    //warn("\n", .{});
     try test__fixdfsi(-math.f64_max, math.minInt(i32));
 
     try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
lib/std/special/compiler_rt/fixdfti_test.zig
@@ -2,16 +2,13 @@ const __fixdfti = @import("fixdfti.zig").__fixdfti;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixdfti(a: f64, expected: i128) !void {
     const x = __fixdfti(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", .{a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixdfti" {
-    //warn("\n", .{});
     try test__fixdfti(-math.f64_max, math.minInt(i128));
 
     try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
lib/std/special/compiler_rt/fixint_test.zig
@@ -2,13 +2,11 @@ const is_test = @import("builtin").is_test;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 const fixint = @import("fixint.zig").fixint;
 
 fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) !void {
     const x = fixint(fp_t, fixint_t, a);
-    //warn("a={} x={}:{x} expected={}:{x})\n", .{a, x, x, expected, expected});
     try testing.expect(x == expected);
 }
 
lib/std/special/compiler_rt/fixsfdi_test.zig
@@ -2,16 +2,13 @@ const __fixsfdi = @import("fixsfdi.zig").__fixsfdi;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixsfdi(a: f32, expected: i64) !void {
     const x = __fixsfdi(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", .{a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixsfdi" {
-    //warn("\n", .{});
     try test__fixsfdi(-math.f32_max, math.minInt(i64));
 
     try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
lib/std/special/compiler_rt/fixsfsi_test.zig
@@ -2,16 +2,13 @@ const __fixsfsi = @import("fixsfsi.zig").__fixsfsi;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixsfsi(a: f32, expected: i32) !void {
     const x = __fixsfsi(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", .{a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixsfsi" {
-    //warn("\n", .{});
     try test__fixsfsi(-math.f32_max, math.minInt(i32));
 
     try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
lib/std/special/compiler_rt/fixsfti_test.zig
@@ -2,16 +2,13 @@ const __fixsfti = @import("fixsfti.zig").__fixsfti;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixsfti(a: f32, expected: i128) !void {
     const x = __fixsfti(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u128, {x})\n", .{a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixsfti" {
-    //warn("\n", .{});
     try test__fixsfti(-math.f32_max, math.minInt(i128));
 
     try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
lib/std/special/compiler_rt/fixtfdi_test.zig
@@ -2,16 +2,13 @@ const __fixtfdi = @import("fixtfdi.zig").__fixtfdi;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixtfdi(a: f128, expected: i64) !void {
     const x = __fixtfdi(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", .{a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixtfdi" {
-    //warn("\n", .{});
     try test__fixtfdi(-math.f128_max, math.minInt(i64));
 
     try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
lib/std/special/compiler_rt/fixtfsi_test.zig
@@ -2,16 +2,13 @@ const __fixtfsi = @import("fixtfsi.zig").__fixtfsi;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixtfsi(a: f128, expected: i32) !void {
     const x = __fixtfsi(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", .{a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixtfsi" {
-    //warn("\n", .{});
     try test__fixtfsi(-math.f128_max, math.minInt(i32));
 
     try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
lib/std/special/compiler_rt/fixtfti_test.zig
@@ -2,16 +2,13 @@ const __fixtfti = @import("fixtfti.zig").__fixtfti;
 const std = @import("std");
 const math = std.math;
 const testing = std.testing;
-const warn = std.debug.warn;
 
 fn test__fixtfti(a: f128, expected: i128) !void {
     const x = __fixtfti(a);
-    //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u128, {x})\n", .{a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected)});
     try testing.expect(x == expected);
 }
 
 test "fixtfti" {
-    //warn("\n", .{});
     try test__fixtfti(-math.f128_max, math.minInt(i128));
 
     try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
lib/std/special/compiler_rt/truncXfYf2_test.zig
@@ -217,7 +217,7 @@ fn test__truncdfsf2(a: f64, expected: u32) void {
         }
     }
 
-    @import("std").debug.warn("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
+    @import("std").debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
 
     @panic("__trunctfsf2 test failure");
 }
@@ -248,7 +248,7 @@ fn test__trunctfhf2(a: f128, expected: u16) void {
         return;
     }
 
-    @import("std").debug.warn("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
+    @import("std").debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
 
     @panic("__trunctfhf2 test failure");
 }
lib/std/special/build_runner.zig
@@ -7,7 +7,6 @@ const Builder = std.build.Builder;
 const mem = std.mem;
 const process = std.process;
 const ArrayList = std.ArrayList;
-const warn = std.debug.warn;
 const File = std.fs.File;
 
 pub fn main() !void {
@@ -25,19 +24,19 @@ pub fn main() !void {
     var arg_idx: usize = 1;
 
     const zig_exe = nextArg(args, &arg_idx) orelse {
-        warn("Expected first argument to be path to zig compiler\n", .{});
+        std.debug.print("Expected first argument to be path to zig compiler\n", .{});
         return error.InvalidArgs;
     };
     const build_root = nextArg(args, &arg_idx) orelse {
-        warn("Expected second argument to be build root directory path\n", .{});
+        std.debug.print("Expected second argument to be build root directory path\n", .{});
         return error.InvalidArgs;
     };
     const cache_root = nextArg(args, &arg_idx) orelse {
-        warn("Expected third argument to be cache root directory path\n", .{});
+        std.debug.print("Expected third argument to be cache root directory path\n", .{});
         return error.InvalidArgs;
     };
     const global_cache_root = nextArg(args, &arg_idx) orelse {
-        warn("Expected third argument to be global cache root directory path\n", .{});
+        std.debug.print("Expected third argument to be global cache root directory path\n", .{});
         return error.InvalidArgs;
     };
 
@@ -68,7 +67,7 @@ pub fn main() !void {
         if (mem.startsWith(u8, arg, "-D")) {
             const option_contents = arg[2..];
             if (option_contents.len == 0) {
-                warn("Expected option name after '-D'\n\n", .{});
+                std.debug.print("Expected option name after '-D'\n\n", .{});
                 return usageAndErr(builder, false, stderr_stream);
             }
             if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| {
@@ -87,59 +86,59 @@ pub fn main() !void {
                 return usage(builder, false, stdout_stream);
             } else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) {
                 install_prefix = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after {s}\n\n", .{arg});
+                    std.debug.print("Expected argument after {s}\n\n", .{arg});
                     return usageAndErr(builder, false, stderr_stream);
                 };
             } else if (mem.eql(u8, arg, "--prefix-lib-dir")) {
                 dir_list.lib_dir = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after {s}\n\n", .{arg});
+                    std.debug.print("Expected argument after {s}\n\n", .{arg});
                     return usageAndErr(builder, false, stderr_stream);
                 };
             } else if (mem.eql(u8, arg, "--prefix-exe-dir")) {
                 dir_list.exe_dir = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after {s}\n\n", .{arg});
+                    std.debug.print("Expected argument after {s}\n\n", .{arg});
                     return usageAndErr(builder, false, stderr_stream);
                 };
             } else if (mem.eql(u8, arg, "--prefix-include-dir")) {
                 dir_list.include_dir = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after {s}\n\n", .{arg});
+                    std.debug.print("Expected argument after {s}\n\n", .{arg});
                     return usageAndErr(builder, false, stderr_stream);
                 };
             } else if (mem.eql(u8, arg, "--sysroot")) {
                 const sysroot = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after --sysroot\n\n", .{});
+                    std.debug.print("Expected argument after --sysroot\n\n", .{});
                     return usageAndErr(builder, false, stderr_stream);
                 };
                 builder.sysroot = sysroot;
             } else if (mem.eql(u8, arg, "--search-prefix")) {
                 const search_prefix = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after --search-prefix\n\n", .{});
+                    std.debug.print("Expected argument after --search-prefix\n\n", .{});
                     return usageAndErr(builder, false, stderr_stream);
                 };
                 builder.addSearchPrefix(search_prefix);
             } else if (mem.eql(u8, arg, "--libc")) {
                 const libc_file = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after --libc\n\n", .{});
+                    std.debug.print("Expected argument after --libc\n\n", .{});
                     return usageAndErr(builder, false, stderr_stream);
                 };
                 builder.libc_file = libc_file;
             } else if (mem.eql(u8, arg, "--color")) {
                 const next_arg = nextArg(args, &arg_idx) orelse {
-                    warn("expected [auto|on|off] after --color", .{});
+                    std.debug.print("expected [auto|on|off] after --color", .{});
                     return usageAndErr(builder, false, stderr_stream);
                 };
                 builder.color = std.meta.stringToEnum(@TypeOf(builder.color), next_arg) orelse {
-                    warn("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
+                    std.debug.print("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
                     return usageAndErr(builder, false, stderr_stream);
                 };
             } else if (mem.eql(u8, arg, "--zig-lib-dir")) {
                 builder.override_lib_dir = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after --zig-lib-dir\n\n", .{});
+                    std.debug.print("Expected argument after --zig-lib-dir\n\n", .{});
                     return usageAndErr(builder, false, stderr_stream);
                 };
             } else if (mem.eql(u8, arg, "--debug-log")) {
                 const next_arg = nextArg(args, &arg_idx) orelse {
-                    warn("Expected argument after {s}\n\n", .{arg});
+                    std.debug.print("Expected argument after {s}\n\n", .{arg});
                     return usageAndErr(builder, false, stderr_stream);
                 };
                 try debug_log_scopes.append(next_arg);
@@ -165,7 +164,7 @@ pub fn main() !void {
                 builder.args = argsRest(args, arg_idx);
                 break;
             } else {
-                warn("Unrecognized argument: {s}\n\n", .{arg});
+                std.debug.print("Unrecognized argument: {s}\n\n", .{arg});
                 return usageAndErr(builder, false, stderr_stream);
             }
         } else {
lib/std/special/c_stage1.zig
@@ -59,7 +59,7 @@ test "strcpy" {
 
     s1[0] = 0;
     _ = strcpy(&s1, "foobarbaz");
-    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.spanZ(&s1));
+    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
 }
 
 fn strncpy(dest: [*:0]u8, src: [*:0]const u8, n: usize) callconv(.C) [*:0]u8 {
@@ -79,7 +79,7 @@ test "strncpy" {
 
     s1[0] = 0;
     _ = strncpy(&s1, "foobarbaz", @sizeOf(@TypeOf(s1)));
-    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.spanZ(&s1));
+    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
 }
 
 fn strcat(dest: [*:0]u8, src: [*:0]const u8) callconv(.C) [*:0]u8 {
@@ -102,7 +102,7 @@ test "strcat" {
     _ = strcat(&s1, "foo");
     _ = strcat(&s1, "bar");
     _ = strcat(&s1, "baz");
-    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.spanZ(&s1));
+    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
 }
 
 fn strncat(dest: [*:0]u8, src: [*:0]const u8, avail: usize) callconv(.C) [*:0]u8 {
@@ -125,7 +125,7 @@ test "strncat" {
     _ = strncat(&s1, "foo1111", 3);
     _ = strncat(&s1, "bar1111", 3);
     _ = strncat(&s1, "baz1111", 3);
-    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.spanZ(&s1));
+    try std.testing.expectEqualSlices(u8, "foobarbaz", std.mem.sliceTo(&s1, 0));
 }
 
 fn strcmp(s1: [*:0]const u8, s2: [*:0]const u8) callconv(.C) c_int {
lib/std/zig/c_builtins.zig
@@ -123,7 +123,7 @@ pub inline fn __builtin_roundf(val: f32) f32 {
 }
 
 pub inline fn __builtin_strlen(s: [*c]const u8) usize {
-    return std.mem.lenZ(s);
+    return std.mem.sliceTo(s, 0).len;
 }
 pub inline fn __builtin_strcmp(s1: [*c]const u8, s2: [*c]const u8) c_int {
     return @as(c_int, std.cstr.cmp(s1, s2));
lib/std/zig/cross_target.zig
@@ -1,909 +0,0 @@
-const std = @import("../std.zig");
-const builtin = @import("builtin");
-const assert = std.debug.assert;
-const Target = std.Target;
-const mem = std.mem;
-
-/// Contains all the same data as `Target`, additionally introducing the concept of "the native target".
-/// The purpose of this abstraction is to provide meaningful and unsurprising defaults.
-/// This struct does reference any resources and it is copyable.
-pub const CrossTarget = struct {
-    /// `null` means native.
-    cpu_arch: ?Target.Cpu.Arch = null,
-
-    cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
-
-    /// Sparse set of CPU features to add to the set from `cpu_model`.
-    cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
-
-    /// Sparse set of CPU features to remove from the set from `cpu_model`.
-    cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
-
-    /// `null` means native.
-    os_tag: ?Target.Os.Tag = null,
-
-    /// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native)
-    /// then `null` for this field means native.
-    os_version_min: ?OsVersion = null,
-
-    /// When cross compiling, `null` means default (latest known OS version).
-    /// When `os_tag` is native, `null` means equal to the native OS version.
-    os_version_max: ?OsVersion = null,
-
-    /// `null` means default when cross compiling, or native when os_tag is native.
-    /// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
-    glibc_version: ?SemVer = null,
-
-    /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI.
-    abi: ?Target.Abi = null,
-
-    /// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path
-    /// based on the `os_tag`.
-    dynamic_linker: DynamicLinker = DynamicLinker{},
-
-    pub const CpuModel = union(enum) {
-        /// Always native
-        native,
-
-        /// Always baseline
-        baseline,
-
-        /// If CPU Architecture is native, then the CPU model will be native. Otherwise,
-        /// it will be baseline.
-        determined_by_cpu_arch,
-
-        explicit: *const Target.Cpu.Model,
-    };
-
-    pub const OsVersion = union(enum) {
-        none: void,
-        semver: SemVer,
-        windows: Target.Os.WindowsVersion,
-    };
-
-    pub const SemVer = std.builtin.Version;
-
-    pub const DynamicLinker = Target.DynamicLinker;
-
-    pub fn fromTarget(target: Target) CrossTarget {
-        var result: CrossTarget = .{
-            .cpu_arch = target.cpu.arch,
-            .cpu_model = .{ .explicit = target.cpu.model },
-            .os_tag = target.os.tag,
-            .os_version_min = undefined,
-            .os_version_max = undefined,
-            .abi = target.abi,
-            .glibc_version = if (target.isGnuLibC())
-                target.os.version_range.linux.glibc
-            else
-                null,
-        };
-        result.updateOsVersionRange(target.os);
-
-        const all_features = target.cpu.arch.allFeaturesList();
-        var cpu_model_set = target.cpu.model.features;
-        cpu_model_set.populateDependencies(all_features);
-        {
-            // The "add" set is the full set with the CPU Model set removed.
-            const add_set = &result.cpu_features_add;
-            add_set.* = target.cpu.features;
-            add_set.removeFeatureSet(cpu_model_set);
-        }
-        {
-            // The "sub" set is the features that are on in CPU Model set and off in the full set.
-            const sub_set = &result.cpu_features_sub;
-            sub_set.* = cpu_model_set;
-            sub_set.removeFeatureSet(target.cpu.features);
-        }
-        return result;
-    }
-
-    fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void {
-        switch (os.tag) {
-            .freestanding,
-            .ananas,
-            .cloudabi,
-            .fuchsia,
-            .kfreebsd,
-            .lv2,
-            .solaris,
-            .zos,
-            .haiku,
-            .minix,
-            .rtems,
-            .nacl,
-            .aix,
-            .cuda,
-            .nvcl,
-            .amdhsa,
-            .ps4,
-            .elfiamcu,
-            .mesa3d,
-            .contiki,
-            .amdpal,
-            .hermit,
-            .hurd,
-            .wasi,
-            .emscripten,
-            .uefi,
-            .opencl,
-            .glsl450,
-            .vulkan,
-            .plan9,
-            .other,
-            => {
-                self.os_version_min = .{ .none = {} };
-                self.os_version_max = .{ .none = {} };
-            },
-
-            .freebsd,
-            .macos,
-            .ios,
-            .tvos,
-            .watchos,
-            .netbsd,
-            .openbsd,
-            .dragonfly,
-            => {
-                self.os_version_min = .{ .semver = os.version_range.semver.min };
-                self.os_version_max = .{ .semver = os.version_range.semver.max };
-            },
-
-            .linux => {
-                self.os_version_min = .{ .semver = os.version_range.linux.range.min };
-                self.os_version_max = .{ .semver = os.version_range.linux.range.max };
-            },
-
-            .windows => {
-                self.os_version_min = .{ .windows = os.version_range.windows.min };
-                self.os_version_max = .{ .windows = os.version_range.windows.max };
-            },
-        }
-    }
-
-    /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
-    pub fn toTarget(self: CrossTarget) Target {
-        return .{
-            .cpu = self.getCpu(),
-            .os = self.getOs(),
-            .abi = self.getAbi(),
-        };
-    }
-
-    pub const ParseOptions = struct {
-        /// This is sometimes called a "triple". It looks roughly like this:
-        ///     riscv64-linux-musl
-        /// The fields are, respectively:
-        /// * CPU Architecture
-        /// * Operating System (and optional version range)
-        /// * C ABI (optional, with optional glibc version)
-        /// The string "native" can be used for CPU architecture as well as Operating System.
-        /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted.
-        arch_os_abi: []const u8 = "native",
-
-        /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
-        /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
-        /// to remove from the set.
-        /// The following special strings are recognized for CPU Model name:
-        /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set
-        ///                of features that is expected to be supported on most available hardware.
-        /// * "native"   - The native CPU model is to be detected when compiling.
-        /// If this field is not provided (`null`), then the value will depend on the
-        /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline".
-        cpu_features: ?[]const u8 = null,
-
-        /// Absolute path to dynamic linker, to override the default, which is either a natively
-        /// detected path, or a standard path.
-        dynamic_linker: ?[]const u8 = null,
-
-        /// If this is provided, the function will populate some information about parsing failures,
-        /// so that user-friendly error messages can be delivered.
-        diagnostics: ?*Diagnostics = null,
-
-        pub const Diagnostics = struct {
-            /// If the architecture was determined, this will be populated.
-            arch: ?Target.Cpu.Arch = null,
-
-            /// If the OS name was determined, this will be populated.
-            os_name: ?[]const u8 = null,
-
-            /// If the OS tag was determined, this will be populated.
-            os_tag: ?Target.Os.Tag = null,
-
-            /// If the ABI was determined, this will be populated.
-            abi: ?Target.Abi = null,
-
-            /// If the CPU name was determined, this will be populated.
-            cpu_name: ?[]const u8 = null,
-
-            /// If error.UnknownCpuFeature is returned, this will be populated.
-            unknown_feature_name: ?[]const u8 = null,
-        };
-    };
-
-    pub fn parse(args: ParseOptions) !CrossTarget {
-        var dummy_diags: ParseOptions.Diagnostics = undefined;
-        const diags = args.diagnostics orelse &dummy_diags;
-
-        var result: CrossTarget = .{
-            .dynamic_linker = DynamicLinker.init(args.dynamic_linker),
-        };
-
-        var it = mem.split(u8, args.arch_os_abi, "-");
-        const arch_name = it.next().?;
-        const arch_is_native = mem.eql(u8, arch_name, "native");
-        if (!arch_is_native) {
-            result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse
-                return error.UnknownArchitecture;
-        }
-        const arch = result.getCpuArch();
-        diags.arch = arch;
-
-        if (it.next()) |os_text| {
-            try parseOs(&result, diags, os_text);
-        } else if (!arch_is_native) {
-            return error.MissingOperatingSystem;
-        }
-
-        const opt_abi_text = it.next();
-        if (opt_abi_text) |abi_text| {
-            var abi_it = mem.split(u8, abi_text, ".");
-            const abi = std.meta.stringToEnum(Target.Abi, abi_it.next().?) orelse
-                return error.UnknownApplicationBinaryInterface;
-            result.abi = abi;
-            diags.abi = abi;
-
-            const abi_ver_text = abi_it.rest();
-            if (abi_it.next() != null) {
-                if (result.isGnuLibC()) {
-                    result.glibc_version = SemVer.parse(abi_ver_text) catch |err| switch (err) {
-                        error.Overflow => return error.InvalidAbiVersion,
-                        error.InvalidCharacter => return error.InvalidAbiVersion,
-                        error.InvalidVersion => return error.InvalidAbiVersion,
-                    };
-                } else {
-                    return error.InvalidAbiVersion;
-                }
-            }
-        }
-
-        if (it.next() != null) return error.UnexpectedExtraField;
-
-        if (args.cpu_features) |cpu_features| {
-            const all_features = arch.allFeaturesList();
-            var index: usize = 0;
-            while (index < cpu_features.len and
-                cpu_features[index] != '+' and
-                cpu_features[index] != '-')
-            {
-                index += 1;
-            }
-            const cpu_name = cpu_features[0..index];
-            diags.cpu_name = cpu_name;
-
-            const add_set = &result.cpu_features_add;
-            const sub_set = &result.cpu_features_sub;
-            if (mem.eql(u8, cpu_name, "native")) {
-                result.cpu_model = .native;
-            } else if (mem.eql(u8, cpu_name, "baseline")) {
-                result.cpu_model = .baseline;
-            } else {
-                result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
-            }
-
-            while (index < cpu_features.len) {
-                const op = cpu_features[index];
-                const set = switch (op) {
-                    '+' => add_set,
-                    '-' => sub_set,
-                    else => unreachable,
-                };
-                index += 1;
-                const start = index;
-                while (index < cpu_features.len and
-                    cpu_features[index] != '+' and
-                    cpu_features[index] != '-')
-                {
-                    index += 1;
-                }
-                const feature_name = cpu_features[start..index];
-                for (all_features) |feature, feat_index_usize| {
-                    const feat_index = @intCast(Target.Cpu.Feature.Set.Index, feat_index_usize);
-                    if (mem.eql(u8, feature_name, feature.name)) {
-                        set.addFeature(feat_index);
-                        break;
-                    }
-                } else {
-                    diags.unknown_feature_name = feature_name;
-                    return error.UnknownCpuFeature;
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /// Similar to `parse` except instead of fully parsing, it only determines the CPU
-    /// architecture and returns it if it can be determined, and returns `null` otherwise.
-    /// This is intended to be used if the API user of CrossTarget needs to learn the
-    /// target CPU architecture in order to fully populate `ParseOptions`.
-    pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
-        var it = mem.split(u8, args.arch_os_abi, "-");
-        const arch_name = it.next().?;
-        const arch_is_native = mem.eql(u8, arch_name, "native");
-        if (arch_is_native) {
-            return builtin.cpu.arch;
-        } else {
-            return std.meta.stringToEnum(Target.Cpu.Arch, arch_name);
-        }
-    }
-
-    /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
-    pub fn getCpu(self: CrossTarget) Target.Cpu {
-        switch (self.cpu_model) {
-            .native => {
-                // This works when doing `zig build` because Zig generates a build executable using
-                // native CPU model & features. However this will not be accurate otherwise, and
-                // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
-                return builtin.cpu;
-            },
-            .baseline => {
-                var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
-                self.updateCpuFeatures(&adjusted_baseline.features);
-                return adjusted_baseline;
-            },
-            .determined_by_cpu_arch => if (self.cpu_arch == null) {
-                // This works when doing `zig build` because Zig generates a build executable using
-                // native CPU model & features. However this will not be accurate otherwise, and
-                // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
-                return builtin.cpu;
-            } else {
-                var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
-                self.updateCpuFeatures(&adjusted_baseline.features);
-                return adjusted_baseline;
-            },
-            .explicit => |model| {
-                var adjusted_model = model.toCpu(self.getCpuArch());
-                self.updateCpuFeatures(&adjusted_model.features);
-                return adjusted_model;
-            },
-        }
-    }
-
-    pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch {
-        return self.cpu_arch orelse builtin.cpu.arch;
-    }
-
-    pub fn getCpuModel(self: CrossTarget) *const Target.Cpu.Model {
-        return switch (self.cpu_model) {
-            .explicit => |cpu_model| cpu_model,
-            else => self.getCpu().model,
-        };
-    }
-
-    pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set {
-        return self.getCpu().features;
-    }
-
-    /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
-    pub fn getOs(self: CrossTarget) Target.Os {
-        // `builtin.os` works when doing `zig build` because Zig generates a build executable using
-        // native OS version range. However this will not be accurate otherwise, and
-        // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
-        var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os;
-
-        if (self.os_version_min) |min| switch (min) {
-            .none => {},
-            .semver => |semver| switch (self.getOsTag()) {
-                .linux => adjusted_os.version_range.linux.range.min = semver,
-                else => adjusted_os.version_range.semver.min = semver,
-            },
-            .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver,
-        };
-
-        if (self.os_version_max) |max| switch (max) {
-            .none => {},
-            .semver => |semver| switch (self.getOsTag()) {
-                .linux => adjusted_os.version_range.linux.range.max = semver,
-                else => adjusted_os.version_range.semver.max = semver,
-            },
-            .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver,
-        };
-
-        if (self.glibc_version) |glibc| {
-            assert(self.isGnuLibC());
-            adjusted_os.version_range.linux.glibc = glibc;
-        }
-
-        return adjusted_os;
-    }
-
-    pub fn getOsTag(self: CrossTarget) Target.Os.Tag {
-        return self.os_tag orelse builtin.os.tag;
-    }
-
-    /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
-    pub fn getOsVersionMin(self: CrossTarget) OsVersion {
-        if (self.os_version_min) |version_min| return version_min;
-        var tmp: CrossTarget = undefined;
-        tmp.updateOsVersionRange(self.getOs());
-        return tmp.os_version_min.?;
-    }
-
-    /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
-    pub fn getOsVersionMax(self: CrossTarget) OsVersion {
-        if (self.os_version_max) |version_max| return version_max;
-        var tmp: CrossTarget = undefined;
-        tmp.updateOsVersionRange(self.getOs());
-        return tmp.os_version_max.?;
-    }
-
-    /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
-    pub fn getAbi(self: CrossTarget) Target.Abi {
-        if (self.abi) |abi| return abi;
-
-        if (self.os_tag == null) {
-            // This works when doing `zig build` because Zig generates a build executable using
-            // native CPU model & features. However this will not be accurate otherwise, and
-            // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
-            return builtin.abi;
-        }
-
-        return Target.Abi.default(self.getCpuArch(), self.getOs());
-    }
-
-    pub fn isFreeBSD(self: CrossTarget) bool {
-        return self.getOsTag() == .freebsd;
-    }
-
-    pub fn isDarwin(self: CrossTarget) bool {
-        return self.getOsTag().isDarwin();
-    }
-
-    pub fn isNetBSD(self: CrossTarget) bool {
-        return self.getOsTag() == .netbsd;
-    }
-
-    pub fn isOpenBSD(self: CrossTarget) bool {
-        return self.getOsTag() == .openbsd;
-    }
-
-    pub fn isUefi(self: CrossTarget) bool {
-        return self.getOsTag() == .uefi;
-    }
-
-    pub fn isDragonFlyBSD(self: CrossTarget) bool {
-        return self.getOsTag() == .dragonfly;
-    }
-
-    pub fn isLinux(self: CrossTarget) bool {
-        return self.getOsTag() == .linux;
-    }
-
-    pub fn isWindows(self: CrossTarget) bool {
-        return self.getOsTag() == .windows;
-    }
-
-    pub fn exeFileExt(self: CrossTarget) [:0]const u8 {
-        return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag());
-    }
-
-    pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 {
-        return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi());
-    }
-
-    pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 {
-        return self.getOsTag().dynamicLibSuffix();
-    }
-
-    pub fn libPrefix(self: CrossTarget) [:0]const u8 {
-        return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi());
-    }
-
-    pub fn isNativeCpu(self: CrossTarget) bool {
-        return self.cpu_arch == null and
-            (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
-            self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty();
-    }
-
-    pub fn isNativeOs(self: CrossTarget) bool {
-        return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
-            self.dynamic_linker.get() == null and self.glibc_version == null;
-    }
-
-    pub fn isNativeAbi(self: CrossTarget) bool {
-        return self.os_tag == null and self.abi == null;
-    }
-
-    pub fn isNative(self: CrossTarget) bool {
-        return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
-    }
-
-    pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![]u8 {
-        if (self.isNative()) {
-            return allocator.dupe(u8, "native");
-        }
-
-        const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
-        const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
-
-        var result = std.ArrayList(u8).init(allocator);
-        defer result.deinit();
-
-        try result.writer().print("{s}-{s}", .{ arch_name, os_name });
-
-        // The zig target syntax does not allow specifying a max os version with no min, so
-        // if either are present, we need the min.
-        if (self.os_version_min != null or self.os_version_max != null) {
-            switch (self.getOsVersionMin()) {
-                .none => {},
-                .semver => |v| try result.writer().print(".{}", .{v}),
-                .windows => |v| try result.writer().print("{s}", .{v}),
-            }
-        }
-        if (self.os_version_max) |max| {
-            switch (max) {
-                .none => {},
-                .semver => |v| try result.writer().print("...{}", .{v}),
-                .windows => |v| try result.writer().print("..{s}", .{v}),
-            }
-        }
-
-        if (self.glibc_version) |v| {
-            try result.writer().print("-{s}.{}", .{ @tagName(self.getAbi()), v });
-        } else if (self.abi) |abi| {
-            try result.writer().print("-{s}", .{@tagName(abi)});
-        }
-
-        return result.toOwnedSlice();
-    }
-
-    pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
-        // TODO is there anything else worthy of the description that is not
-        // already captured in the triple?
-        return self.zigTriple(allocator);
-    }
-
-    pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
-        return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
-    }
-
-    pub fn wantSharedLibSymLinks(self: CrossTarget) bool {
-        return self.getOsTag() != .windows;
-    }
-
-    pub const VcpkgLinkage = std.builtin.LinkMode;
-
-    /// Returned slice must be freed by the caller.
-    pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![]u8 {
-        const arch = switch (self.getCpuArch()) {
-            .i386 => "x86",
-            .x86_64 => "x64",
-
-            .arm,
-            .armeb,
-            .thumb,
-            .thumbeb,
-            .aarch64_32,
-            => "arm",
-
-            .aarch64,
-            .aarch64_be,
-            => "arm64",
-
-            else => return error.UnsupportedVcpkgArchitecture,
-        };
-
-        const os = switch (self.getOsTag()) {
-            .windows => "windows",
-            .linux => "linux",
-            .macos => "macos",
-            else => return error.UnsupportedVcpkgOperatingSystem,
-        };
-
-        const static_suffix = switch (linkage) {
-            .Static => "-static",
-            .Dynamic => "",
-        };
-
-        return std.fmt.allocPrint(allocator, "{s}-{s}{s}", .{ arch, os, static_suffix });
-    }
-
-    pub const Executor = union(enum) {
-        native,
-        qemu: []const u8,
-        wine: []const u8,
-        wasmtime: []const u8,
-        darling: []const u8,
-        unavailable,
-    };
-
-    /// Note that even a `CrossTarget` which returns `false` for `isNative` could still be natively executed.
-    /// For example `-target arm-native` running on an aarch64 host.
-    pub fn getExternalExecutor(self: CrossTarget) Executor {
-        const cpu_arch = self.getCpuArch();
-        const os_tag = self.getOsTag();
-        const os_match = os_tag == builtin.os.tag;
-
-        // If the OS and CPU arch match, the binary can be considered native.
-        // TODO additionally match the CPU features. This `getExternalExecutor` function should
-        // be moved to std.Target and match any chosen target against the native target.
-        if (os_match and cpu_arch == builtin.cpu.arch) {
-            // However, we also need to verify that the dynamic linker path is valid.
-            if (self.os_tag == null) {
-                return .native;
-            }
-            // TODO here we call toTarget, a deprecated function, because of the above TODO about moving
-            // this code to std.Target.
-            const opt_dl = self.dynamic_linker.get() orelse self.toTarget().standardDynamicLinkerPath().get();
-            if (opt_dl) |dl| blk: {
-                std.fs.cwd().access(dl, .{}) catch break :blk;
-                return .native;
-            }
-        }
-
-        // If the OS matches, we can use QEMU to emulate a foreign architecture.
-        if (os_match) {
-            return switch (cpu_arch) {
-                .aarch64 => Executor{ .qemu = "qemu-aarch64" },
-                .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
-                .arm => Executor{ .qemu = "qemu-arm" },
-                .armeb => Executor{ .qemu = "qemu-armeb" },
-                .i386 => Executor{ .qemu = "qemu-i386" },
-                .mips => Executor{ .qemu = "qemu-mips" },
-                .mipsel => Executor{ .qemu = "qemu-mipsel" },
-                .mips64 => Executor{ .qemu = "qemu-mips64" },
-                .mips64el => Executor{ .qemu = "qemu-mips64el" },
-                .powerpc => Executor{ .qemu = "qemu-ppc" },
-                .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
-                .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
-                .riscv32 => Executor{ .qemu = "qemu-riscv32" },
-                .riscv64 => Executor{ .qemu = "qemu-riscv64" },
-                .s390x => Executor{ .qemu = "qemu-s390x" },
-                .sparc => Executor{ .qemu = "qemu-sparc" },
-                .x86_64 => Executor{ .qemu = "qemu-x86_64" },
-                else => return .unavailable,
-            };
-        }
-
-        switch (os_tag) {
-            .windows => switch (cpu_arch.ptrBitWidth()) {
-                32 => return Executor{ .wine = "wine" },
-                64 => return Executor{ .wine = "wine64" },
-                else => return .unavailable,
-            },
-            .wasi => switch (cpu_arch.ptrBitWidth()) {
-                32 => return Executor{ .wasmtime = "wasmtime" },
-                else => return .unavailable,
-            },
-            .macos => {
-                // TODO loosen this check once upstream adds QEMU-based emulation
-                // layer for non-host architectures:
-                // https://github.com/darlinghq/darling/issues/863
-                if (cpu_arch != builtin.cpu.arch) {
-                    return .unavailable;
-                }
-                return Executor{ .darling = "darling" };
-            },
-            else => return .unavailable,
-        }
-    }
-
-    pub fn isGnuLibC(self: CrossTarget) bool {
-        return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi());
-    }
-
-    pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32) void {
-        assert(self.isGnuLibC());
-        self.glibc_version = SemVer{ .major = major, .minor = minor, .patch = patch };
-    }
-
-    pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat {
-        return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch());
-    }
-
-    pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
-        set.removeFeatureSet(self.cpu_features_sub);
-        set.addFeatureSet(self.cpu_features_add);
-        set.populateDependencies(self.getCpuArch().allFeaturesList());
-        set.removeFeatureSet(self.cpu_features_sub);
-    }
-
-    fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const u8) !void {
-        var it = mem.split(u8, text, ".");
-        const os_name = it.next().?;
-        diags.os_name = os_name;
-        const os_is_native = mem.eql(u8, os_name, "native");
-        if (!os_is_native) {
-            result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse
-                return error.UnknownOperatingSystem;
-        }
-        const tag = result.getOsTag();
-        diags.os_tag = tag;
-
-        const version_text = it.rest();
-        if (it.next() == null) return;
-
-        switch (tag) {
-            .freestanding,
-            .ananas,
-            .cloudabi,
-            .fuchsia,
-            .kfreebsd,
-            .lv2,
-            .solaris,
-            .zos,
-            .haiku,
-            .minix,
-            .rtems,
-            .nacl,
-            .aix,
-            .cuda,
-            .nvcl,
-            .amdhsa,
-            .ps4,
-            .elfiamcu,
-            .mesa3d,
-            .contiki,
-            .amdpal,
-            .hermit,
-            .hurd,
-            .wasi,
-            .emscripten,
-            .uefi,
-            .opencl,
-            .glsl450,
-            .vulkan,
-            .plan9,
-            .other,
-            => return error.InvalidOperatingSystemVersion,
-
-            .freebsd,
-            .macos,
-            .ios,
-            .tvos,
-            .watchos,
-            .netbsd,
-            .openbsd,
-            .linux,
-            .dragonfly,
-            => {
-                var range_it = mem.split(u8, version_text, "...");
-
-                const min_text = range_it.next().?;
-                const min_ver = SemVer.parse(min_text) catch |err| switch (err) {
-                    error.Overflow => return error.InvalidOperatingSystemVersion,
-                    error.InvalidCharacter => return error.InvalidOperatingSystemVersion,
-                    error.InvalidVersion => return error.InvalidOperatingSystemVersion,
-                };
-                result.os_version_min = .{ .semver = min_ver };
-
-                const max_text = range_it.next() orelse return;
-                const max_ver = SemVer.parse(max_text) catch |err| switch (err) {
-                    error.Overflow => return error.InvalidOperatingSystemVersion,
-                    error.InvalidCharacter => return error.InvalidOperatingSystemVersion,
-                    error.InvalidVersion => return error.InvalidOperatingSystemVersion,
-                };
-                result.os_version_max = .{ .semver = max_ver };
-            },
-
-            .windows => {
-                var range_it = mem.split(u8, version_text, "...");
-
-                const min_text = range_it.next().?;
-                const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse
-                    return error.InvalidOperatingSystemVersion;
-                result.os_version_min = .{ .windows = min_ver };
-
-                const max_text = range_it.next() orelse return;
-                const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse
-                    return error.InvalidOperatingSystemVersion;
-                result.os_version_max = .{ .windows = max_ver };
-            },
-        }
-    }
-};
-
-test "CrossTarget.parse" {
-    if (builtin.target.isGnuLibC()) {
-        var cross_target = try CrossTarget.parse(.{});
-        cross_target.setGnuLibCVersion(2, 1, 1);
-
-        const text = try cross_target.zigTriple(std.testing.allocator);
-        defer std.testing.allocator.free(text);
-
-        var buf: [256]u8 = undefined;
-        const triple = std.fmt.bufPrint(
-            buf[0..],
-            "native-native-{s}.2.1.1",
-            .{@tagName(builtin.abi)},
-        ) catch unreachable;
-
-        try std.testing.expectEqualSlices(u8, triple, text);
-    }
-    {
-        const cross_target = try CrossTarget.parse(.{
-            .arch_os_abi = "aarch64-linux",
-            .cpu_features = "native",
-        });
-
-        try std.testing.expect(cross_target.cpu_arch.? == .aarch64);
-        try std.testing.expect(cross_target.cpu_model == .native);
-    }
-    {
-        const cross_target = try CrossTarget.parse(.{ .arch_os_abi = "native" });
-
-        try std.testing.expect(cross_target.cpu_arch == null);
-        try std.testing.expect(cross_target.isNative());
-
-        const text = try cross_target.zigTriple(std.testing.allocator);
-        defer std.testing.allocator.free(text);
-        try std.testing.expectEqualSlices(u8, "native", text);
-    }
-    {
-        const cross_target = try CrossTarget.parse(.{
-            .arch_os_abi = "x86_64-linux-gnu",
-            .cpu_features = "x86_64-sse-sse2-avx-cx8",
-        });
-        const target = cross_target.toTarget();
-
-        try std.testing.expect(target.os.tag == .linux);
-        try std.testing.expect(target.abi == .gnu);
-        try std.testing.expect(target.cpu.arch == .x86_64);
-        try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
-        try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
-        try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
-        try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
-        try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
-
-        try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
-        try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
-        try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
-        try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
-
-        const text = try cross_target.zigTriple(std.testing.allocator);
-        defer std.testing.allocator.free(text);
-        try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text);
-    }
-    {
-        const cross_target = try CrossTarget.parse(.{
-            .arch_os_abi = "arm-linux-musleabihf",
-            .cpu_features = "generic+v8a",
-        });
-        const target = cross_target.toTarget();
-
-        try std.testing.expect(target.os.tag == .linux);
-        try std.testing.expect(target.abi == .musleabihf);
-        try std.testing.expect(target.cpu.arch == .arm);
-        try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
-        try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
-
-        const text = try cross_target.zigTriple(std.testing.allocator);
-        defer std.testing.allocator.free(text);
-        try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text);
-    }
-    {
-        const cross_target = try CrossTarget.parse(.{
-            .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27",
-            .cpu_features = "generic+v8a",
-        });
-        const target = cross_target.toTarget();
-
-        try std.testing.expect(target.cpu.arch == .aarch64);
-        try std.testing.expect(target.os.tag == .linux);
-        try std.testing.expect(target.os.version_range.linux.range.min.major == 3);
-        try std.testing.expect(target.os.version_range.linux.range.min.minor == 10);
-        try std.testing.expect(target.os.version_range.linux.range.min.patch == 0);
-        try std.testing.expect(target.os.version_range.linux.range.max.major == 4);
-        try std.testing.expect(target.os.version_range.linux.range.max.minor == 4);
-        try std.testing.expect(target.os.version_range.linux.range.max.patch == 1);
-        try std.testing.expect(target.os.version_range.linux.glibc.major == 2);
-        try std.testing.expect(target.os.version_range.linux.glibc.minor == 27);
-        try std.testing.expect(target.os.version_range.linux.glibc.patch == 0);
-        try std.testing.expect(target.abi == .gnu);
-
-        const text = try cross_target.zigTriple(std.testing.allocator);
-        defer std.testing.allocator.free(text);
-        try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text);
-    }
-}
lib/std/zig/CrossTarget.zig
@@ -0,0 +1,909 @@
+//! Contains all the same data as `Target`, additionally introducing the concept of "the native target".
+//! The purpose of this abstraction is to provide meaningful and unsurprising defaults.
+//! This struct does reference any resources and it is copyable.
+
+const CrossTarget = @This();
+const std = @import("../std.zig");
+const builtin = @import("builtin");
+const assert = std.debug.assert;
+const Target = std.Target;
+const mem = std.mem;
+
+/// `null` means native.
+cpu_arch: ?Target.Cpu.Arch = null,
+
+cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
+
+/// Sparse set of CPU features to add to the set from `cpu_model`.
+cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
+
+/// Sparse set of CPU features to remove from the set from `cpu_model`.
+cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
+
+/// `null` means native.
+os_tag: ?Target.Os.Tag = null,
+
+/// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native)
+/// then `null` for this field means native.
+os_version_min: ?OsVersion = null,
+
+/// When cross compiling, `null` means default (latest known OS version).
+/// When `os_tag` is native, `null` means equal to the native OS version.
+os_version_max: ?OsVersion = null,
+
+/// `null` means default when cross compiling, or native when os_tag is native.
+/// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
+glibc_version: ?SemVer = null,
+
+/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI.
+abi: ?Target.Abi = null,
+
+/// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path
+/// based on the `os_tag`.
+dynamic_linker: DynamicLinker = DynamicLinker{},
+
+pub const CpuModel = union(enum) {
+    /// Always native
+    native,
+
+    /// Always baseline
+    baseline,
+
+    /// If CPU Architecture is native, then the CPU model will be native. Otherwise,
+    /// it will be baseline.
+    determined_by_cpu_arch,
+
+    explicit: *const Target.Cpu.Model,
+};
+
+pub const OsVersion = union(enum) {
+    none: void,
+    semver: SemVer,
+    windows: Target.Os.WindowsVersion,
+};
+
+pub const SemVer = std.builtin.Version;
+
+pub const DynamicLinker = Target.DynamicLinker;
+
+pub fn fromTarget(target: Target) CrossTarget {
+    var result: CrossTarget = .{
+        .cpu_arch = target.cpu.arch,
+        .cpu_model = .{ .explicit = target.cpu.model },
+        .os_tag = target.os.tag,
+        .os_version_min = undefined,
+        .os_version_max = undefined,
+        .abi = target.abi,
+        .glibc_version = if (target.isGnuLibC())
+            target.os.version_range.linux.glibc
+        else
+            null,
+    };
+    result.updateOsVersionRange(target.os);
+
+    const all_features = target.cpu.arch.allFeaturesList();
+    var cpu_model_set = target.cpu.model.features;
+    cpu_model_set.populateDependencies(all_features);
+    {
+        // The "add" set is the full set with the CPU Model set removed.
+        const add_set = &result.cpu_features_add;
+        add_set.* = target.cpu.features;
+        add_set.removeFeatureSet(cpu_model_set);
+    }
+    {
+        // The "sub" set is the features that are on in CPU Model set and off in the full set.
+        const sub_set = &result.cpu_features_sub;
+        sub_set.* = cpu_model_set;
+        sub_set.removeFeatureSet(target.cpu.features);
+    }
+    return result;
+}
+
+fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void {
+    switch (os.tag) {
+        .freestanding,
+        .ananas,
+        .cloudabi,
+        .fuchsia,
+        .kfreebsd,
+        .lv2,
+        .solaris,
+        .zos,
+        .haiku,
+        .minix,
+        .rtems,
+        .nacl,
+        .aix,
+        .cuda,
+        .nvcl,
+        .amdhsa,
+        .ps4,
+        .elfiamcu,
+        .mesa3d,
+        .contiki,
+        .amdpal,
+        .hermit,
+        .hurd,
+        .wasi,
+        .emscripten,
+        .uefi,
+        .opencl,
+        .glsl450,
+        .vulkan,
+        .plan9,
+        .other,
+        => {
+            self.os_version_min = .{ .none = {} };
+            self.os_version_max = .{ .none = {} };
+        },
+
+        .freebsd,
+        .macos,
+        .ios,
+        .tvos,
+        .watchos,
+        .netbsd,
+        .openbsd,
+        .dragonfly,
+        => {
+            self.os_version_min = .{ .semver = os.version_range.semver.min };
+            self.os_version_max = .{ .semver = os.version_range.semver.max };
+        },
+
+        .linux => {
+            self.os_version_min = .{ .semver = os.version_range.linux.range.min };
+            self.os_version_max = .{ .semver = os.version_range.linux.range.max };
+        },
+
+        .windows => {
+            self.os_version_min = .{ .windows = os.version_range.windows.min };
+            self.os_version_max = .{ .windows = os.version_range.windows.max };
+        },
+    }
+}
+
+/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
+pub fn toTarget(self: CrossTarget) Target {
+    return .{
+        .cpu = self.getCpu(),
+        .os = self.getOs(),
+        .abi = self.getAbi(),
+    };
+}
+
+pub const ParseOptions = struct {
+    /// This is sometimes called a "triple". It looks roughly like this:
+    ///     riscv64-linux-musl
+    /// The fields are, respectively:
+    /// * CPU Architecture
+    /// * Operating System (and optional version range)
+    /// * C ABI (optional, with optional glibc version)
+    /// The string "native" can be used for CPU architecture as well as Operating System.
+    /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted.
+    arch_os_abi: []const u8 = "native",
+
+    /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
+    /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
+    /// to remove from the set.
+    /// The following special strings are recognized for CPU Model name:
+    /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set
+    ///                of features that is expected to be supported on most available hardware.
+    /// * "native"   - The native CPU model is to be detected when compiling.
+    /// If this field is not provided (`null`), then the value will depend on the
+    /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline".
+    cpu_features: ?[]const u8 = null,
+
+    /// Absolute path to dynamic linker, to override the default, which is either a natively
+    /// detected path, or a standard path.
+    dynamic_linker: ?[]const u8 = null,
+
+    /// If this is provided, the function will populate some information about parsing failures,
+    /// so that user-friendly error messages can be delivered.
+    diagnostics: ?*Diagnostics = null,
+
+    pub const Diagnostics = struct {
+        /// If the architecture was determined, this will be populated.
+        arch: ?Target.Cpu.Arch = null,
+
+        /// If the OS name was determined, this will be populated.
+        os_name: ?[]const u8 = null,
+
+        /// If the OS tag was determined, this will be populated.
+        os_tag: ?Target.Os.Tag = null,
+
+        /// If the ABI was determined, this will be populated.
+        abi: ?Target.Abi = null,
+
+        /// If the CPU name was determined, this will be populated.
+        cpu_name: ?[]const u8 = null,
+
+        /// If error.UnknownCpuFeature is returned, this will be populated.
+        unknown_feature_name: ?[]const u8 = null,
+    };
+};
+
+pub fn parse(args: ParseOptions) !CrossTarget {
+    var dummy_diags: ParseOptions.Diagnostics = undefined;
+    const diags = args.diagnostics orelse &dummy_diags;
+
+    var result: CrossTarget = .{
+        .dynamic_linker = DynamicLinker.init(args.dynamic_linker),
+    };
+
+    var it = mem.split(u8, args.arch_os_abi, "-");
+    const arch_name = it.next().?;
+    const arch_is_native = mem.eql(u8, arch_name, "native");
+    if (!arch_is_native) {
+        result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse
+            return error.UnknownArchitecture;
+    }
+    const arch = result.getCpuArch();
+    diags.arch = arch;
+
+    if (it.next()) |os_text| {
+        try parseOs(&result, diags, os_text);
+    } else if (!arch_is_native) {
+        return error.MissingOperatingSystem;
+    }
+
+    const opt_abi_text = it.next();
+    if (opt_abi_text) |abi_text| {
+        var abi_it = mem.split(u8, abi_text, ".");
+        const abi = std.meta.stringToEnum(Target.Abi, abi_it.next().?) orelse
+            return error.UnknownApplicationBinaryInterface;
+        result.abi = abi;
+        diags.abi = abi;
+
+        const abi_ver_text = abi_it.rest();
+        if (abi_it.next() != null) {
+            if (result.isGnuLibC()) {
+                result.glibc_version = SemVer.parse(abi_ver_text) catch |err| switch (err) {
+                    error.Overflow => return error.InvalidAbiVersion,
+                    error.InvalidCharacter => return error.InvalidAbiVersion,
+                    error.InvalidVersion => return error.InvalidAbiVersion,
+                };
+            } else {
+                return error.InvalidAbiVersion;
+            }
+        }
+    }
+
+    if (it.next() != null) return error.UnexpectedExtraField;
+
+    if (args.cpu_features) |cpu_features| {
+        const all_features = arch.allFeaturesList();
+        var index: usize = 0;
+        while (index < cpu_features.len and
+            cpu_features[index] != '+' and
+            cpu_features[index] != '-')
+        {
+            index += 1;
+        }
+        const cpu_name = cpu_features[0..index];
+        diags.cpu_name = cpu_name;
+
+        const add_set = &result.cpu_features_add;
+        const sub_set = &result.cpu_features_sub;
+        if (mem.eql(u8, cpu_name, "native")) {
+            result.cpu_model = .native;
+        } else if (mem.eql(u8, cpu_name, "baseline")) {
+            result.cpu_model = .baseline;
+        } else {
+            result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
+        }
+
+        while (index < cpu_features.len) {
+            const op = cpu_features[index];
+            const set = switch (op) {
+                '+' => add_set,
+                '-' => sub_set,
+                else => unreachable,
+            };
+            index += 1;
+            const start = index;
+            while (index < cpu_features.len and
+                cpu_features[index] != '+' and
+                cpu_features[index] != '-')
+            {
+                index += 1;
+            }
+            const feature_name = cpu_features[start..index];
+            for (all_features) |feature, feat_index_usize| {
+                const feat_index = @intCast(Target.Cpu.Feature.Set.Index, feat_index_usize);
+                if (mem.eql(u8, feature_name, feature.name)) {
+                    set.addFeature(feat_index);
+                    break;
+                }
+            } else {
+                diags.unknown_feature_name = feature_name;
+                return error.UnknownCpuFeature;
+            }
+        }
+    }
+
+    return result;
+}
+
+/// Similar to `parse` except instead of fully parsing, it only determines the CPU
+/// architecture and returns it if it can be determined, and returns `null` otherwise.
+/// This is intended to be used if the API user of CrossTarget needs to learn the
+/// target CPU architecture in order to fully populate `ParseOptions`.
+pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
+    var it = mem.split(u8, args.arch_os_abi, "-");
+    const arch_name = it.next().?;
+    const arch_is_native = mem.eql(u8, arch_name, "native");
+    if (arch_is_native) {
+        return builtin.cpu.arch;
+    } else {
+        return std.meta.stringToEnum(Target.Cpu.Arch, arch_name);
+    }
+}
+
+/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
+pub fn getCpu(self: CrossTarget) Target.Cpu {
+    switch (self.cpu_model) {
+        .native => {
+            // This works when doing `zig build` because Zig generates a build executable using
+            // native CPU model & features. However this will not be accurate otherwise, and
+            // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
+            return builtin.cpu;
+        },
+        .baseline => {
+            var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
+            self.updateCpuFeatures(&adjusted_baseline.features);
+            return adjusted_baseline;
+        },
+        .determined_by_cpu_arch => if (self.cpu_arch == null) {
+            // This works when doing `zig build` because Zig generates a build executable using
+            // native CPU model & features. However this will not be accurate otherwise, and
+            // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
+            return builtin.cpu;
+        } else {
+            var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
+            self.updateCpuFeatures(&adjusted_baseline.features);
+            return adjusted_baseline;
+        },
+        .explicit => |model| {
+            var adjusted_model = model.toCpu(self.getCpuArch());
+            self.updateCpuFeatures(&adjusted_model.features);
+            return adjusted_model;
+        },
+    }
+}
+
+pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch {
+    return self.cpu_arch orelse builtin.cpu.arch;
+}
+
+pub fn getCpuModel(self: CrossTarget) *const Target.Cpu.Model {
+    return switch (self.cpu_model) {
+        .explicit => |cpu_model| cpu_model,
+        else => self.getCpu().model,
+    };
+}
+
+pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set {
+    return self.getCpu().features;
+}
+
+/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
+pub fn getOs(self: CrossTarget) Target.Os {
+    // `builtin.os` works when doing `zig build` because Zig generates a build executable using
+    // native OS version range. However this will not be accurate otherwise, and
+    // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
+    var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os;
+
+    if (self.os_version_min) |min| switch (min) {
+        .none => {},
+        .semver => |semver| switch (self.getOsTag()) {
+            .linux => adjusted_os.version_range.linux.range.min = semver,
+            else => adjusted_os.version_range.semver.min = semver,
+        },
+        .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver,
+    };
+
+    if (self.os_version_max) |max| switch (max) {
+        .none => {},
+        .semver => |semver| switch (self.getOsTag()) {
+            .linux => adjusted_os.version_range.linux.range.max = semver,
+            else => adjusted_os.version_range.semver.max = semver,
+        },
+        .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver,
+    };
+
+    if (self.glibc_version) |glibc| {
+        assert(self.isGnuLibC());
+        adjusted_os.version_range.linux.glibc = glibc;
+    }
+
+    return adjusted_os;
+}
+
+pub fn getOsTag(self: CrossTarget) Target.Os.Tag {
+    return self.os_tag orelse builtin.os.tag;
+}
+
+/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
+pub fn getOsVersionMin(self: CrossTarget) OsVersion {
+    if (self.os_version_min) |version_min| return version_min;
+    var tmp: CrossTarget = undefined;
+    tmp.updateOsVersionRange(self.getOs());
+    return tmp.os_version_min.?;
+}
+
+/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
+pub fn getOsVersionMax(self: CrossTarget) OsVersion {
+    if (self.os_version_max) |version_max| return version_max;
+    var tmp: CrossTarget = undefined;
+    tmp.updateOsVersionRange(self.getOs());
+    return tmp.os_version_max.?;
+}
+
+/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
+pub fn getAbi(self: CrossTarget) Target.Abi {
+    if (self.abi) |abi| return abi;
+
+    if (self.os_tag == null) {
+        // This works when doing `zig build` because Zig generates a build executable using
+        // native CPU model & features. However this will not be accurate otherwise, and
+        // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
+        return builtin.abi;
+    }
+
+    return Target.Abi.default(self.getCpuArch(), self.getOs());
+}
+
+pub fn isFreeBSD(self: CrossTarget) bool {
+    return self.getOsTag() == .freebsd;
+}
+
+pub fn isDarwin(self: CrossTarget) bool {
+    return self.getOsTag().isDarwin();
+}
+
+pub fn isNetBSD(self: CrossTarget) bool {
+    return self.getOsTag() == .netbsd;
+}
+
+pub fn isOpenBSD(self: CrossTarget) bool {
+    return self.getOsTag() == .openbsd;
+}
+
+pub fn isUefi(self: CrossTarget) bool {
+    return self.getOsTag() == .uefi;
+}
+
+pub fn isDragonFlyBSD(self: CrossTarget) bool {
+    return self.getOsTag() == .dragonfly;
+}
+
+pub fn isLinux(self: CrossTarget) bool {
+    return self.getOsTag() == .linux;
+}
+
+pub fn isWindows(self: CrossTarget) bool {
+    return self.getOsTag() == .windows;
+}
+
+pub fn exeFileExt(self: CrossTarget) [:0]const u8 {
+    return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag());
+}
+
+pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 {
+    return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi());
+}
+
+pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 {
+    return self.getOsTag().dynamicLibSuffix();
+}
+
+pub fn libPrefix(self: CrossTarget) [:0]const u8 {
+    return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi());
+}
+
+pub fn isNativeCpu(self: CrossTarget) bool {
+    return self.cpu_arch == null and
+        (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
+        self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty();
+}
+
+pub fn isNativeOs(self: CrossTarget) bool {
+    return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
+        self.dynamic_linker.get() == null and self.glibc_version == null;
+}
+
+pub fn isNativeAbi(self: CrossTarget) bool {
+    return self.os_tag == null and self.abi == null;
+}
+
+pub fn isNative(self: CrossTarget) bool {
+    return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
+}
+
+pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![]u8 {
+    if (self.isNative()) {
+        return allocator.dupe(u8, "native");
+    }
+
+    const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
+    const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
+
+    var result = std.ArrayList(u8).init(allocator);
+    defer result.deinit();
+
+    try result.writer().print("{s}-{s}", .{ arch_name, os_name });
+
+    // The zig target syntax does not allow specifying a max os version with no min, so
+    // if either are present, we need the min.
+    if (self.os_version_min != null or self.os_version_max != null) {
+        switch (self.getOsVersionMin()) {
+            .none => {},
+            .semver => |v| try result.writer().print(".{}", .{v}),
+            .windows => |v| try result.writer().print("{s}", .{v}),
+        }
+    }
+    if (self.os_version_max) |max| {
+        switch (max) {
+            .none => {},
+            .semver => |v| try result.writer().print("...{}", .{v}),
+            .windows => |v| try result.writer().print("..{s}", .{v}),
+        }
+    }
+
+    if (self.glibc_version) |v| {
+        try result.writer().print("-{s}.{}", .{ @tagName(self.getAbi()), v });
+    } else if (self.abi) |abi| {
+        try result.writer().print("-{s}", .{@tagName(abi)});
+    }
+
+    return result.toOwnedSlice();
+}
+
+pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
+    // TODO is there anything else worthy of the description that is not
+    // already captured in the triple?
+    return self.zigTriple(allocator);
+}
+
+pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![]u8 {
+    return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
+}
+
+pub fn wantSharedLibSymLinks(self: CrossTarget) bool {
+    return self.getOsTag() != .windows;
+}
+
+pub const VcpkgLinkage = std.builtin.LinkMode;
+
+/// Returned slice must be freed by the caller.
+pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![]u8 {
+    const arch = switch (self.getCpuArch()) {
+        .i386 => "x86",
+        .x86_64 => "x64",
+
+        .arm,
+        .armeb,
+        .thumb,
+        .thumbeb,
+        .aarch64_32,
+        => "arm",
+
+        .aarch64,
+        .aarch64_be,
+        => "arm64",
+
+        else => return error.UnsupportedVcpkgArchitecture,
+    };
+
+    const os = switch (self.getOsTag()) {
+        .windows => "windows",
+        .linux => "linux",
+        .macos => "macos",
+        else => return error.UnsupportedVcpkgOperatingSystem,
+    };
+
+    const static_suffix = switch (linkage) {
+        .Static => "-static",
+        .Dynamic => "",
+    };
+
+    return std.fmt.allocPrint(allocator, "{s}-{s}{s}", .{ arch, os, static_suffix });
+}
+
+pub const Executor = union(enum) {
+    native,
+    qemu: []const u8,
+    wine: []const u8,
+    wasmtime: []const u8,
+    darling: []const u8,
+    unavailable,
+};
+
+/// Note that even a `CrossTarget` which returns `false` for `isNative` could still be natively executed.
+/// For example `-target arm-native` running on an aarch64 host.
+pub fn getExternalExecutor(self: CrossTarget) Executor {
+    const cpu_arch = self.getCpuArch();
+    const os_tag = self.getOsTag();
+    const os_match = os_tag == builtin.os.tag;
+
+    // If the OS and CPU arch match, the binary can be considered native.
+    // TODO additionally match the CPU features. This `getExternalExecutor` function should
+    // be moved to std.Target and match any chosen target against the native target.
+    if (os_match and cpu_arch == builtin.cpu.arch) {
+        // However, we also need to verify that the dynamic linker path is valid.
+        if (self.os_tag == null) {
+            return .native;
+        }
+        // TODO here we call toTarget, a deprecated function, because of the above TODO about moving
+        // this code to std.Target.
+        const opt_dl = self.dynamic_linker.get() orelse self.toTarget().standardDynamicLinkerPath().get();
+        if (opt_dl) |dl| blk: {
+            std.fs.cwd().access(dl, .{}) catch break :blk;
+            return .native;
+        }
+    }
+
+    // If the OS matches, we can use QEMU to emulate a foreign architecture.
+    if (os_match) {
+        return switch (cpu_arch) {
+            .aarch64 => Executor{ .qemu = "qemu-aarch64" },
+            .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
+            .arm => Executor{ .qemu = "qemu-arm" },
+            .armeb => Executor{ .qemu = "qemu-armeb" },
+            .i386 => Executor{ .qemu = "qemu-i386" },
+            .mips => Executor{ .qemu = "qemu-mips" },
+            .mipsel => Executor{ .qemu = "qemu-mipsel" },
+            .mips64 => Executor{ .qemu = "qemu-mips64" },
+            .mips64el => Executor{ .qemu = "qemu-mips64el" },
+            .powerpc => Executor{ .qemu = "qemu-ppc" },
+            .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
+            .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
+            .riscv32 => Executor{ .qemu = "qemu-riscv32" },
+            .riscv64 => Executor{ .qemu = "qemu-riscv64" },
+            .s390x => Executor{ .qemu = "qemu-s390x" },
+            .sparc => Executor{ .qemu = "qemu-sparc" },
+            .x86_64 => Executor{ .qemu = "qemu-x86_64" },
+            else => return .unavailable,
+        };
+    }
+
+    switch (os_tag) {
+        .windows => switch (cpu_arch.ptrBitWidth()) {
+            32 => return Executor{ .wine = "wine" },
+            64 => return Executor{ .wine = "wine64" },
+            else => return .unavailable,
+        },
+        .wasi => switch (cpu_arch.ptrBitWidth()) {
+            32 => return Executor{ .wasmtime = "wasmtime" },
+            else => return .unavailable,
+        },
+        .macos => {
+            // TODO loosen this check once upstream adds QEMU-based emulation
+            // layer for non-host architectures:
+            // https://github.com/darlinghq/darling/issues/863
+            if (cpu_arch != builtin.cpu.arch) {
+                return .unavailable;
+            }
+            return Executor{ .darling = "darling" };
+        },
+        else => return .unavailable,
+    }
+}
+
+pub fn isGnuLibC(self: CrossTarget) bool {
+    return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi());
+}
+
+pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32) void {
+    assert(self.isGnuLibC());
+    self.glibc_version = SemVer{ .major = major, .minor = minor, .patch = patch };
+}
+
+pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat {
+    return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch());
+}
+
+pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
+    set.removeFeatureSet(self.cpu_features_sub);
+    set.addFeatureSet(self.cpu_features_add);
+    set.populateDependencies(self.getCpuArch().allFeaturesList());
+    set.removeFeatureSet(self.cpu_features_sub);
+}
+
+fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const u8) !void {
+    var it = mem.split(u8, text, ".");
+    const os_name = it.next().?;
+    diags.os_name = os_name;
+    const os_is_native = mem.eql(u8, os_name, "native");
+    if (!os_is_native) {
+        result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse
+            return error.UnknownOperatingSystem;
+    }
+    const tag = result.getOsTag();
+    diags.os_tag = tag;
+
+    const version_text = it.rest();
+    if (it.next() == null) return;
+
+    switch (tag) {
+        .freestanding,
+        .ananas,
+        .cloudabi,
+        .fuchsia,
+        .kfreebsd,
+        .lv2,
+        .solaris,
+        .zos,
+        .haiku,
+        .minix,
+        .rtems,
+        .nacl,
+        .aix,
+        .cuda,
+        .nvcl,
+        .amdhsa,
+        .ps4,
+        .elfiamcu,
+        .mesa3d,
+        .contiki,
+        .amdpal,
+        .hermit,
+        .hurd,
+        .wasi,
+        .emscripten,
+        .uefi,
+        .opencl,
+        .glsl450,
+        .vulkan,
+        .plan9,
+        .other,
+        => return error.InvalidOperatingSystemVersion,
+
+        .freebsd,
+        .macos,
+        .ios,
+        .tvos,
+        .watchos,
+        .netbsd,
+        .openbsd,
+        .linux,
+        .dragonfly,
+        => {
+            var range_it = mem.split(u8, version_text, "...");
+
+            const min_text = range_it.next().?;
+            const min_ver = SemVer.parse(min_text) catch |err| switch (err) {
+                error.Overflow => return error.InvalidOperatingSystemVersion,
+                error.InvalidCharacter => return error.InvalidOperatingSystemVersion,
+                error.InvalidVersion => return error.InvalidOperatingSystemVersion,
+            };
+            result.os_version_min = .{ .semver = min_ver };
+
+            const max_text = range_it.next() orelse return;
+            const max_ver = SemVer.parse(max_text) catch |err| switch (err) {
+                error.Overflow => return error.InvalidOperatingSystemVersion,
+                error.InvalidCharacter => return error.InvalidOperatingSystemVersion,
+                error.InvalidVersion => return error.InvalidOperatingSystemVersion,
+            };
+            result.os_version_max = .{ .semver = max_ver };
+        },
+
+        .windows => {
+            var range_it = mem.split(u8, version_text, "...");
+
+            const min_text = range_it.next().?;
+            const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse
+                return error.InvalidOperatingSystemVersion;
+            result.os_version_min = .{ .windows = min_ver };
+
+            const max_text = range_it.next() orelse return;
+            const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse
+                return error.InvalidOperatingSystemVersion;
+            result.os_version_max = .{ .windows = max_ver };
+        },
+    }
+}
+
+test "CrossTarget.parse" {
+    if (builtin.target.isGnuLibC()) {
+        var cross_target = try CrossTarget.parse(.{});
+        cross_target.setGnuLibCVersion(2, 1, 1);
+
+        const text = try cross_target.zigTriple(std.testing.allocator);
+        defer std.testing.allocator.free(text);
+
+        var buf: [256]u8 = undefined;
+        const triple = std.fmt.bufPrint(
+            buf[0..],
+            "native-native-{s}.2.1.1",
+            .{@tagName(builtin.abi)},
+        ) catch unreachable;
+
+        try std.testing.expectEqualSlices(u8, triple, text);
+    }
+    {
+        const cross_target = try CrossTarget.parse(.{
+            .arch_os_abi = "aarch64-linux",
+            .cpu_features = "native",
+        });
+
+        try std.testing.expect(cross_target.cpu_arch.? == .aarch64);
+        try std.testing.expect(cross_target.cpu_model == .native);
+    }
+    {
+        const cross_target = try CrossTarget.parse(.{ .arch_os_abi = "native" });
+
+        try std.testing.expect(cross_target.cpu_arch == null);
+        try std.testing.expect(cross_target.isNative());
+
+        const text = try cross_target.zigTriple(std.testing.allocator);
+        defer std.testing.allocator.free(text);
+        try std.testing.expectEqualSlices(u8, "native", text);
+    }
+    {
+        const cross_target = try CrossTarget.parse(.{
+            .arch_os_abi = "x86_64-linux-gnu",
+            .cpu_features = "x86_64-sse-sse2-avx-cx8",
+        });
+        const target = cross_target.toTarget();
+
+        try std.testing.expect(target.os.tag == .linux);
+        try std.testing.expect(target.abi == .gnu);
+        try std.testing.expect(target.cpu.arch == .x86_64);
+        try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
+        try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
+        try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
+        try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
+        try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
+
+        try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
+        try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
+        try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
+        try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
+
+        const text = try cross_target.zigTriple(std.testing.allocator);
+        defer std.testing.allocator.free(text);
+        try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text);
+    }
+    {
+        const cross_target = try CrossTarget.parse(.{
+            .arch_os_abi = "arm-linux-musleabihf",
+            .cpu_features = "generic+v8a",
+        });
+        const target = cross_target.toTarget();
+
+        try std.testing.expect(target.os.tag == .linux);
+        try std.testing.expect(target.abi == .musleabihf);
+        try std.testing.expect(target.cpu.arch == .arm);
+        try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
+        try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
+
+        const text = try cross_target.zigTriple(std.testing.allocator);
+        defer std.testing.allocator.free(text);
+        try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text);
+    }
+    {
+        const cross_target = try CrossTarget.parse(.{
+            .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27",
+            .cpu_features = "generic+v8a",
+        });
+        const target = cross_target.toTarget();
+
+        try std.testing.expect(target.cpu.arch == .aarch64);
+        try std.testing.expect(target.os.tag == .linux);
+        try std.testing.expect(target.os.version_range.linux.range.min.major == 3);
+        try std.testing.expect(target.os.version_range.linux.range.min.minor == 10);
+        try std.testing.expect(target.os.version_range.linux.range.min.patch == 0);
+        try std.testing.expect(target.os.version_range.linux.range.max.major == 4);
+        try std.testing.expect(target.os.version_range.linux.range.max.minor == 4);
+        try std.testing.expect(target.os.version_range.linux.range.max.patch == 1);
+        try std.testing.expect(target.os.version_range.linux.glibc.major == 2);
+        try std.testing.expect(target.os.version_range.linux.glibc.minor == 27);
+        try std.testing.expect(target.os.version_range.linux.glibc.patch == 0);
+        try std.testing.expect(target.abi == .gnu);
+
+        const text = try cross_target.zigTriple(std.testing.allocator);
+        defer std.testing.allocator.free(text);
+        try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text);
+    }
+}
lib/std/zig/perf_test.zig
@@ -1,6 +1,5 @@
 const std = @import("std");
 const mem = std.mem;
-const warn = std.debug.warn;
 const Tokenizer = std.zig.Tokenizer;
 const Parser = std.zig.Parser;
 const io = std.io;
lib/std/zig/system.zig
@@ -165,7 +165,7 @@ pub const NativePaths = struct {
     }
 
     pub fn addIncludeDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void {
-        const item = try std.fmt.allocPrint0(self.include_dirs.allocator, fmt, args);
+        const item = try std.fmt.allocPrintZ(self.include_dirs.allocator, fmt, args);
         errdefer self.include_dirs.allocator.free(item);
         try self.include_dirs.append(item);
     }
@@ -175,7 +175,7 @@ pub const NativePaths = struct {
     }
 
     pub fn addLibDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void {
-        const item = try std.fmt.allocPrint0(self.lib_dirs.allocator, fmt, args);
+        const item = try std.fmt.allocPrintZ(self.lib_dirs.allocator, fmt, args);
         errdefer self.lib_dirs.allocator.free(item);
         try self.lib_dirs.append(item);
     }
@@ -189,13 +189,13 @@ pub const NativePaths = struct {
     }
 
     pub fn addFrameworkDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void {
-        const item = try std.fmt.allocPrint0(self.framework_dirs.allocator, fmt, args);
+        const item = try std.fmt.allocPrintZ(self.framework_dirs.allocator, fmt, args);
         errdefer self.framework_dirs.allocator.free(item);
         try self.framework_dirs.append(item);
     }
 
     pub fn addWarningFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void {
-        const item = try std.fmt.allocPrint0(self.warnings.allocator, fmt, args);
+        const item = try std.fmt.allocPrintZ(self.warnings.allocator, fmt, args);
         errdefer self.warnings.allocator.free(item);
         try self.warnings.append(item);
     }
@@ -243,7 +243,7 @@ pub const NativeTargetInfo = struct {
             switch (builtin.target.os.tag) {
                 .linux => {
                     const uts = std.os.uname();
-                    const release = mem.spanZ(&uts.release);
+                    const release = mem.sliceTo(&uts.release, 0);
                     // The release field sometimes has a weird format,
                     // `Version.parse` will attempt to find some meaningful interpretation.
                     if (std.builtin.Version.parse(release)) |ver| {
@@ -257,7 +257,7 @@ pub const NativeTargetInfo = struct {
                 },
                 .solaris => {
                     const uts = std.os.uname();
-                    const release = mem.spanZ(&uts.release);
+                    const release = mem.sliceTo(&uts.release, 0);
                     if (std.builtin.Version.parse(release)) |ver| {
                         os.version_range.semver.min = ver;
                         os.version_range.semver.max = ver;
@@ -838,7 +838,7 @@ pub const NativeTargetInfo = struct {
                         );
                         const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name);
                         // TODO this pointer cast should not be necessary
-                        const sh_name = mem.spanZ(std.meta.assumeSentinel(shstrtab[sh_name_off..].ptr, 0));
+                        const sh_name = mem.sliceTo(std.meta.assumeSentinel(shstrtab[sh_name_off..].ptr, 0), 0);
                         if (mem.eql(u8, sh_name, ".dynstr")) {
                             break :find_dyn_str .{
                                 .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset),
@@ -856,7 +856,7 @@ pub const NativeTargetInfo = struct {
                     const rpoff_usize = std.math.cast(usize, rpoff) catch |err| switch (err) {
                         error.Overflow => return error.InvalidElfFile,
                     };
-                    const rpath_list = mem.spanZ(std.meta.assumeSentinel(strtab[rpoff_usize..].ptr, 0));
+                    const rpath_list = mem.sliceTo(std.meta.assumeSentinel(strtab[rpoff_usize..].ptr, 0), 0);
                     var it = mem.tokenize(u8, rpath_list, ":");
                     while (it.next()) |rpath| {
                         var dir = fs.cwd().openDir(rpath, .{}) catch |err| switch (err) {
lib/std/zig/tokenizer.zig
@@ -334,7 +334,7 @@ pub const Tokenizer = struct {
 
     /// For debugging purposes
     pub fn dump(self: *Tokenizer, token: *const Token) void {
-        std.debug.warn("{s} \"{s}\"\n", .{ @tagName(token.tag), self.buffer[token.start..token.end] });
+        std.debug.print("{s} \"{s}\"\n", .{ @tagName(token.tag), self.buffer[token.start..token.end] });
     }
 
     pub fn init(buffer: [:0]const u8) Tokenizer {
lib/std/array_hash_map.zig
@@ -201,8 +201,7 @@ pub fn ArrayHashMap(
             return self.unmanaged.getOrPutValueContext(self.allocator, key, value, self.ctx);
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Increases capacity, guaranteeing that insertions up until the
         /// `expected_count` will not cause an allocation, and therefore cannot fail.
@@ -746,8 +745,7 @@ pub fn ArrayHashMapUnmanaged(
             return res;
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Increases capacity, guaranteeing that insertions up until the
         /// `expected_count` will not cause an allocation, and therefore cannot fail.
@@ -2217,17 +2215,6 @@ test "auto store_hash" {
     try testing.expect(meta.fieldInfo(HasExpensiveEqlUn.Data, .hash).field_type != void);
 }
 
-test "compile everything" {
-    std.testing.refAllDecls(AutoArrayHashMap(i32, i32));
-    std.testing.refAllDecls(StringArrayHashMap([]const u8));
-    std.testing.refAllDecls(AutoArrayHashMap(i32, void));
-    std.testing.refAllDecls(StringArrayHashMap(u0));
-    std.testing.refAllDecls(AutoArrayHashMapUnmanaged(i32, i32));
-    std.testing.refAllDecls(StringArrayHashMapUnmanaged([]const u8));
-    std.testing.refAllDecls(AutoArrayHashMapUnmanaged(i32, void));
-    std.testing.refAllDecls(StringArrayHashMapUnmanaged(u0));
-}
-
 pub fn getHashPtrAddrFn(comptime K: type, comptime Context: type) (fn (Context, K) u32) {
     return struct {
         fn hash(ctx: Context, key: K) u32 {
lib/std/array_list.zig
@@ -71,15 +71,6 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
             }
         }
 
-        pub const span = @compileError("deprecated: use `items` field directly");
-        pub const toSlice = @compileError("deprecated: use `items` field directly");
-        pub const toSliceConst = @compileError("deprecated: use `items` field directly");
-        pub const at = @compileError("deprecated: use `list.items[i]`");
-        pub const ptrAt = @compileError("deprecated: use `&list.items[i]`");
-        pub const setOrError = @compileError("deprecated: use `if (i >= list.items.len) return error.OutOfBounds else list.items[i] = item`");
-        pub const set = @compileError("deprecated: use `list.items[i] = item`");
-        pub const swapRemoveOrError = @compileError("deprecated: use `if (i >= list.items.len) return error.OutOfBounds else list.swapRemove(i)`");
-
         /// ArrayList takes ownership of the passed in slice. The slice must have been
         /// allocated with `allocator`.
         /// Deinitialize with `deinit` or use `toOwnedSlice`.
@@ -91,12 +82,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
             };
         }
 
-        /// Initializes an ArrayListUnmanaged with the `items` and `capacity` fields
-        /// of this ArrayList. This ArrayList retains ownership of underlying memory.
-        /// Deprecated: use `moveToUnmanaged` which has different semantics.
-        pub fn toUnmanaged(self: Self) ArrayListAlignedUnmanaged(T, alignment) {
-            return .{ .items = self.items, .capacity = self.capacity };
-        }
+        pub const toUnmanaged = @compileError("deprecated; use `moveToUnmanaged` which has different semantics.");
 
         /// Initializes an ArrayListUnmanaged with the `items` and `capacity` fields
         /// of this ArrayList. Empties this ArrayList.
@@ -307,8 +293,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
             self.capacity = 0;
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Modify the array so that it can hold at least `new_capacity` items.
         /// Invalidates pointers if additional memory is needed.
@@ -533,7 +518,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
         pub fn replaceRange(self: *Self, allocator: *Allocator, start: usize, len: usize, new_items: []const T) !void {
             var managed = self.toManaged(allocator);
             try managed.replaceRange(start, len, new_items);
-            self.* = managed.toUnmanaged();
+            self.* = managed.moveToUnmanaged();
         }
 
         /// Extend the list by 1 element. Allocates more memory as necessary.
@@ -674,8 +659,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
             self.capacity = 0;
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Modify the array so that it can hold at least `new_capacity` items.
         /// Invalidates pointers if additional memory is needed.
@@ -1337,7 +1321,7 @@ test "std.ArrayList/ArrayListUnmanaged.toOwnedSliceSentinel" {
 
         const result = try list.toOwnedSliceSentinel(0);
         defer a.free(result);
-        try testing.expectEqualStrings(result, mem.spanZ(result.ptr));
+        try testing.expectEqualStrings(result, mem.sliceTo(result.ptr, 0));
     }
     {
         var list = ArrayListUnmanaged(u8){};
@@ -1347,7 +1331,7 @@ test "std.ArrayList/ArrayListUnmanaged.toOwnedSliceSentinel" {
 
         const result = try list.toOwnedSliceSentinel(a, 0);
         defer a.free(result);
-        try testing.expectEqualStrings(result, mem.spanZ(result.ptr));
+        try testing.expectEqualStrings(result, mem.sliceTo(result.ptr, 0));
     }
 }
 
lib/std/base64.zig
@@ -64,14 +64,9 @@ pub const url_safe_no_pad = Codecs{
     .Decoder = Base64Decoder.init(url_safe_alphabet_chars, null),
 };
 
-// Backwards compatibility
-
-/// Deprecated - Use `standard.pad_char`
-pub const standard_pad_char = standard.pad_char;
-/// Deprecated - Use `standard.Encoder`
-pub const standard_encoder = standard.Encoder;
-/// Deprecated - Use `standard.Decoder`
-pub const standard_decoder = standard.Decoder;
+pub const standard_pad_char = @compileError("deprecated; use standard.pad_char");
+pub const standard_encoder = @compileError("deprecated; use standard.Encoder");
+pub const standard_decoder = @compileError("deprecated; use standard.Decoder");
 
 pub const Base64Encoder = struct {
     alphabet_chars: [64]u8,
lib/std/build.zig
@@ -6,7 +6,7 @@ const mem = std.mem;
 const debug = std.debug;
 const panic = std.debug.panic;
 const assert = debug.assert;
-const warn = std.debug.warn;
+const warn = std.debug.print; // TODO use the log system instead of this
 const ArrayList = std.ArrayList;
 const StringHashMap = std.StringHashMap;
 const Allocator = mem.Allocator;
@@ -1295,11 +1295,12 @@ test "builder.findProgram compiles" {
     _ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null;
 }
 
-/// Deprecated. Use `std.builtin.Version`.
-pub const Version = std.builtin.Version;
-
-/// Deprecated. Use `std.zig.CrossTarget`.
-pub const Target = std.zig.CrossTarget;
+/// TODO: propose some kind of `@deprecate` builtin so that we can deprecate
+/// this while still having somewhat non-lazy decls. In this file we wanted to do
+/// refAllDecls for example which makes it trigger `@compileError` if you try
+/// to use that strategy.
+pub const Version = @compileError("deprecated; Use `std.builtin.Version`");
+pub const Target = @compileError("deprecated; Use `std.zig.CrossTarget`");
 
 pub const Pkg = struct {
     name: []const u8,
@@ -3277,16 +3278,3 @@ test "LibExeObjStep.addPackage" {
     const dupe = exe.packages.items[0];
     try std.testing.expectEqualStrings(pkg_top.name, dupe.name);
 }
-
-test {
-    // The only purpose of this test is to get all these untested functions
-    // to be referenced to avoid regression so it is okay to skip some targets.
-    if (comptime builtin.cpu.arch.ptrBitWidth() == 64) {
-        std.testing.refAllDecls(@This());
-        std.testing.refAllDecls(Builder);
-
-        inline for (std.meta.declarations(@This())) |decl|
-            if (comptime mem.endsWith(u8, decl.name, "Step"))
-                std.testing.refAllDecls(decl.data.Type);
-    }
-}
lib/std/builtin.zig
@@ -707,7 +707,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
             }
         },
         .wasi => {
-            std.debug.warn("{s}", .{msg});
+            std.debug.print("{s}", .{msg});
             std.os.abort();
         },
         .uefi => {
lib/std/child_process.zig
@@ -181,8 +181,6 @@ pub const ChildProcess = struct {
         stderr: []u8,
     };
 
-    pub const exec2 = @compileError("deprecated: exec2 is renamed to exec");
-
     fn collectOutputPosix(
         child: *const ChildProcess,
         stdout: *std.ArrayList(u8),
lib/std/debug.zig
@@ -55,9 +55,7 @@ const PdbOrDwarf = union(enum) {
 
 var stderr_mutex = std.Thread.Mutex{};
 
-/// Deprecated. Use `std.log` functions for logging or `std.debug.print` for
-/// "printf debugging".
-pub const warn = print;
+pub const warn = @compileError("deprecated; use `std.log` functions for logging or `std.debug.print` for 'printf debugging'");
 
 /// Print to stderr, unbuffered, and silently returning on failure. Intended
 /// for use in "printf debugging." Use `std.log` functions for proper logging.
@@ -1052,7 +1050,7 @@ pub const DebugInfo = struct {
                     const obj_di = try self.allocator.create(ModuleDebugInfo);
                     errdefer self.allocator.destroy(obj_di);
 
-                    const macho_path = mem.spanZ(std.c._dyld_get_image_name(i));
+                    const macho_path = mem.sliceTo(std.c._dyld_get_image_name(i), 0);
                     const macho_file = fs.cwd().openFile(macho_path, .{ .intended_io_mode = .blocking }) catch |err| switch (err) {
                         error.FileNotFound => return error.MissingDebugInfo,
                         else => return err,
@@ -1178,7 +1176,7 @@ pub const DebugInfo = struct {
                     if (context.address >= seg_start and context.address < seg_end) {
                         // Android libc uses NULL instead of an empty string to mark the
                         // main program
-                        context.name = mem.spanZ(info.dlpi_name) orelse "";
+                        context.name = mem.sliceTo(info.dlpi_name, 0) orelse "";
                         context.base_address = info.dlpi_addr;
                         // Stop the iteration
                         return error.Found;
@@ -1341,12 +1339,12 @@ pub const ModuleDebugInfo = switch (native_os) {
 
                 // Take the symbol name from the N_FUN STAB entry, we're going to
                 // use it if we fail to find the DWARF infos
-                const stab_symbol = mem.spanZ(self.strings[symbol.nlist.n_strx..]);
+                const stab_symbol = mem.sliceTo(self.strings[symbol.nlist.n_strx..], 0);
 
                 if (symbol.ofile == null)
                     return SymbolInfo{ .symbol_name = stab_symbol };
 
-                const o_file_path = mem.spanZ(self.strings[symbol.ofile.?.n_strx..]);
+                const o_file_path = mem.sliceTo(self.strings[symbol.ofile.?.n_strx..], 0);
 
                 // Check if its debug infos are already in the cache
                 var o_file_di = self.ofiles.get(o_file_path) orelse
@@ -1668,5 +1666,5 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
     const sp = asm (""
         : [argc] "={rsp}" (-> usize),
     );
-    std.debug.warn("{} sp = 0x{x}\n", .{ prefix, sp });
+    std.debug.print("{} sp = 0x{x}\n", .{ prefix, sp });
 }
lib/std/dynamic_library.zig
@@ -248,11 +248,9 @@ pub const ElfDynLib = struct {
         };
     }
 
-    pub const openC = @compileError("deprecated: renamed to openZ");
-
     /// Trusts the file. Malicious file will be able to execute arbitrary code.
     pub fn openZ(path_c: [*:0]const u8) !ElfDynLib {
-        return open(mem.spanZ(path_c));
+        return open(mem.sliceTo(path_c, 0));
     }
 
     /// Trusts the file
@@ -281,7 +279,7 @@ pub const ElfDynLib = struct {
             if (0 == (@as(u32, 1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue;
             if (0 == (@as(u32, 1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue;
             if (0 == self.syms[i].st_shndx) continue;
-            if (!mem.eql(u8, name, mem.spanZ(self.strings + self.syms[i].st_name))) continue;
+            if (!mem.eql(u8, name, mem.sliceTo(self.strings + self.syms[i].st_name, 0))) continue;
             if (maybe_versym) |versym| {
                 if (!checkver(self.verdef.?, versym[i], vername, self.strings))
                     continue;
@@ -312,7 +310,7 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
         def = @intToPtr(*elf.Verdef, @ptrToInt(def) + def.vd_next);
     }
     const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);
-    return mem.eql(u8, vername, mem.spanZ(strings + aux.vda_name));
+    return mem.eql(u8, vername, mem.sliceTo(strings + aux.vda_name, 0));
 }
 
 pub const WindowsDynLib = struct {
@@ -325,8 +323,6 @@ pub const WindowsDynLib = struct {
         return openW(path_w.span().ptr);
     }
 
-    pub const openC = @compileError("deprecated: renamed to openZ");
-
     pub fn openZ(path_c: [*:0]const u8) !WindowsDynLib {
         const path_w = try windows.cStrToPrefixedFileW(path_c);
         return openW(path_w.span().ptr);
@@ -368,8 +364,6 @@ pub const DlDynlib = struct {
         return openZ(&path_c);
     }
 
-    pub const openC = @compileError("deprecated: renamed to openZ");
-
     pub fn openZ(path_c: [*:0]const u8) !DlDynlib {
         return DlDynlib{
             .handle = system.dlopen(path_c, system.RTLD.LAZY) orelse {
lib/std/fifo.zig
@@ -119,8 +119,7 @@ pub fn LinearFifo(
             }
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Ensure that the buffer can fit at least `size` items
         pub fn ensureTotalCapacity(self: *Self, size: usize) !void {
lib/std/fmt.zig
@@ -1814,8 +1814,7 @@ pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: any
     };
 }
 
-/// Deprecated, use allocPrintZ
-pub const allocPrint0 = allocPrintZ;
+pub const allocPrint0 = @compileError("deprecated; use allocPrintZ");
 
 pub fn allocPrintZ(allocator: *mem.Allocator, comptime fmt: []const u8, args: anytype) AllocPrintError![:0]u8 {
     const result = try allocPrint(allocator, fmt ++ "\x00", args);
@@ -2367,9 +2366,6 @@ test "bytes.hex" {
     try expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{fmtSliceHexLower(bytes_with_zeros)});
 }
 
-pub const trim = @compileError("deprecated; use std.mem.trim with std.ascii.spaces instead");
-pub const isWhiteSpace = @compileError("deprecated; use std.ascii.isSpace instead");
-
 /// Decodes the sequence of bytes represented by the specified string of
 /// hexadecimal characters.
 /// Returns a slice of the output buffer containing the decoded bytes.
lib/std/fs.zig
@@ -19,7 +19,6 @@ pub const wasi = @import("fs/wasi.zig");
 
 pub const realpath = os.realpath;
 pub const realpathZ = os.realpathZ;
-pub const realpathC = @compileError("deprecated: renamed to realpathZ");
 pub const realpathW = os.realpathW;
 
 pub const getAppDataDir = @import("fs/get_app_data_dir.zig").getAppDataDir;
@@ -227,10 +226,6 @@ pub fn makeDirAbsoluteW(absolute_path_w: [*:0]const u16) !void {
     return os.mkdirW(absolute_path_w, default_new_dir_mode);
 }
 
-pub const deleteDir = @compileError("deprecated; use dir.deleteDir or deleteDirAbsolute");
-pub const deleteDirC = @compileError("deprecated; use dir.deleteDirZ or deleteDirAbsoluteZ");
-pub const deleteDirW = @compileError("deprecated; use dir.deleteDirW or deleteDirAbsoluteW");
-
 /// Same as `Dir.deleteDir` except the path is absolute.
 pub fn deleteDirAbsolute(dir_path: []const u8) !void {
     assert(path.isAbsolute(dir_path));
@@ -249,8 +244,6 @@ pub fn deleteDirAbsoluteW(dir_path: [*:0]const u16) !void {
     return os.rmdirW(dir_path);
 }
 
-pub const renameC = @compileError("deprecated: use renameZ, dir.renameZ, or renameAbsoluteZ");
-
 /// Same as `Dir.rename` except the paths are absolute.
 pub fn renameAbsolute(old_path: []const u8, new_path: []const u8) !void {
     assert(path.isAbsolute(old_path));
@@ -393,7 +386,7 @@ pub const Dir = struct {
                     const next_index = self.index + entry.reclen();
                     self.index = next_index;
 
-                    const name = mem.spanZ(@ptrCast([*:0]u8, &entry.d_name));
+                    const name = mem.sliceTo(@ptrCast([*:0]u8, &entry.d_name), 0);
                     if (mem.eql(u8, name, ".") or mem.eql(u8, name, ".."))
                         continue :start_over;
 
@@ -520,7 +513,7 @@ pub const Dir = struct {
                     const haiku_entry = @ptrCast(*align(1) os.system.dirent, &self.buf[self.index]);
                     const next_index = self.index + haiku_entry.reclen();
                     self.index = next_index;
-                    const name = mem.spanZ(@ptrCast([*:0]u8, &haiku_entry.d_name));
+                    const name = mem.sliceTo(@ptrCast([*:0]u8, &haiku_entry.d_name), 0);
 
                     if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..") or (haiku_entry.d_ino == 0)) {
                         continue :start_over;
@@ -598,7 +591,7 @@ pub const Dir = struct {
                     const next_index = self.index + linux_entry.reclen();
                     self.index = next_index;
 
-                    const name = mem.spanZ(@ptrCast([*:0]u8, &linux_entry.d_name));
+                    const name = mem.sliceTo(@ptrCast([*:0]u8, &linux_entry.d_name), 0);
 
                     // skip . and .. entries
                     if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) {
@@ -965,8 +958,6 @@ pub const Dir = struct {
         return File{ .handle = fd };
     }
 
-    pub const openFileC = @compileError("deprecated: renamed to openFileZ");
-
     /// Same as `openFile` but the path parameter is null-terminated.
     pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
         if (builtin.os.tag == .windows) {
@@ -1100,8 +1091,6 @@ pub const Dir = struct {
         return self.createFileZ(&path_c, flags);
     }
 
-    pub const createFileC = @compileError("deprecated: renamed to createFileZ");
-
     /// Same as `createFile` but WASI only.
     pub fn createFileWasi(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
         const w = os.wasi;
@@ -1243,10 +1232,6 @@ pub const Dir = struct {
         return file;
     }
 
-    pub const openRead = @compileError("deprecated in favor of openFile");
-    pub const openReadC = @compileError("deprecated in favor of openFileZ");
-    pub const openReadW = @compileError("deprecated in favor of openFileW");
-
     pub fn makeDir(self: Dir, sub_path: []const u8) !void {
         try os.mkdirat(self.fd, sub_path, default_new_dir_mode);
     }
@@ -1463,8 +1448,6 @@ pub const Dir = struct {
         }
     }
 
-    pub const openDirC = @compileError("deprecated: renamed to openDirZ");
-
     /// Same as `openDir` except only WASI.
     pub fn openDirWasi(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir {
         const w = os.wasi;
@@ -1554,7 +1537,7 @@ pub const Dir = struct {
             .fd = undefined,
         };
 
-        const path_len_bytes = @intCast(u16, mem.lenZ(sub_path_w) * 2);
+        const path_len_bytes = @intCast(u16, mem.sliceTo(sub_path_w, 0).len * 2);
         var nt_name = w.UNICODE_STRING{
             .Length = path_len_bytes,
             .MaximumLength = path_len_bytes,
@@ -1613,8 +1596,6 @@ pub const Dir = struct {
         }
     }
 
-    pub const deleteFileC = @compileError("deprecated: renamed to deleteFileZ");
-
     /// Same as `deleteFile` except the parameter is null-terminated.
     pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {
         os.unlinkatZ(self.fd, sub_path_c, 0) catch |err| switch (err) {
@@ -1788,8 +1769,6 @@ pub const Dir = struct {
         return self.readLinkZ(&sub_path_c, buffer);
     }
 
-    pub const readLinkC = @compileError("deprecated: renamed to readLinkZ");
-
     /// WASI-only. Same as `readLink` except targeting WASI.
     pub fn readLinkWasi(self: Dir, sub_path: []const u8, buffer: []u8) ![]u8 {
         return os.readlinkatWasi(self.fd, sub_path, buffer);
@@ -2275,8 +2254,6 @@ pub fn openFileAbsolute(absolute_path: []const u8, flags: File.OpenFlags) File.O
     return cwd().openFile(absolute_path, flags);
 }
 
-pub const openFileAbsoluteC = @compileError("deprecated: renamed to openFileAbsoluteZ");
-
 /// Same as `openFileAbsolute` but the path parameter is null-terminated.
 pub fn openFileAbsoluteZ(absolute_path_c: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
     assert(path.isAbsoluteZ(absolute_path_c));
@@ -2330,8 +2307,6 @@ pub fn createFileAbsolute(absolute_path: []const u8, flags: File.CreateFlags) Fi
     return cwd().createFile(absolute_path, flags);
 }
 
-pub const createFileAbsoluteC = @compileError("deprecated: renamed to createFileAbsoluteZ");
-
 /// Same as `createFileAbsolute` but the path parameter is null-terminated.
 pub fn createFileAbsoluteZ(absolute_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File {
     assert(path.isAbsoluteZ(absolute_path_c));
@@ -2353,8 +2328,6 @@ pub fn deleteFileAbsolute(absolute_path: []const u8) Dir.DeleteFileError!void {
     return cwd().deleteFile(absolute_path);
 }
 
-pub const deleteFileAbsoluteC = @compileError("deprecated: renamed to deleteFileAbsoluteZ");
-
 /// Same as `deleteFileAbsolute` except the parameter is null-terminated.
 pub fn deleteFileAbsoluteZ(absolute_path_c: [*:0]const u8) Dir.DeleteFileError!void {
     assert(path.isAbsoluteZ(absolute_path_c));
@@ -2405,9 +2378,6 @@ pub fn readLinkAbsoluteZ(pathname_c: [*:0]const u8, buffer: *[MAX_PATH_BYTES]u8)
     return os.readlinkZ(pathname_c, buffer);
 }
 
-pub const readLink = @compileError("deprecated; use Dir.readLink or readLinkAbsolute");
-pub const readLinkC = @compileError("deprecated; use Dir.readLinkZ or readLinkAbsoluteZ");
-
 /// Use with `Dir.symLink` and `symLinkAbsolute` to specify whether the symlink
 /// will point to a file or a directory. This value is ignored on all hosts
 /// except Windows where creating symlinks to different resource types, requires
@@ -2458,11 +2428,6 @@ pub fn symLinkAbsoluteZ(target_path_c: [*:0]const u8, sym_link_path_c: [*:0]cons
     return os.symlinkZ(target_path_c, sym_link_path_c);
 }
 
-pub const symLink = @compileError("deprecated: use Dir.symLink or symLinkAbsolute");
-pub const symLinkC = @compileError("deprecated: use Dir.symLinkZ or symLinkAbsoluteZ");
-
-pub const walkPath = @compileError("deprecated: use Dir.walk");
-
 pub const OpenSelfExeError = error{
     SharingViolation,
     PathAlreadyExists,
@@ -2544,14 +2509,14 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
             var out_len: usize = out_buffer.len;
             try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
             // TODO could this slice from 0 to out_len instead?
-            return mem.spanZ(std.meta.assumeSentinel(out_buffer.ptr, 0));
+            return mem.sliceTo(std.meta.assumeSentinel(out_buffer.ptr, 0), 0);
         },
         .netbsd => {
             var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC_ARGS, -1, os.KERN.PROC_PATHNAME };
             var out_len: usize = out_buffer.len;
             try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0);
             // TODO could this slice from 0 to out_len instead?
-            return mem.spanZ(std.meta.assumeSentinel(out_buffer.ptr, 0));
+            return mem.sliceTo(std.meta.assumeSentinel(out_buffer.ptr, 0), 0);
         },
         .openbsd, .haiku => {
             // OpenBSD doesn't support getting the path of a running process, so try to guess it
@@ -2603,7 +2568,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
 /// The result is UTF16LE-encoded.
 pub fn selfExePathW() [:0]const u16 {
     const image_path_name = &os.windows.peb().ProcessParameters.ImagePathName;
-    return mem.spanZ(std.meta.assumeSentinel(image_path_name.Buffer, 0));
+    return mem.sliceTo(std.meta.assumeSentinel(image_path_name.Buffer, 0), 0);
 }
 
 /// `selfExeDirPath` except allocates the result on the heap.
lib/std/hash_map.zig
@@ -2,7 +2,6 @@ const std = @import("std.zig");
 const assert = debug.assert;
 const autoHash = std.hash.autoHash;
 const debug = std.debug;
-const warn = debug.warn;
 const math = std.math;
 const mem = std.mem;
 const meta = std.meta;
@@ -101,7 +100,7 @@ pub const StringIndexContext = struct {
     }
 
     pub fn hash(self: @This(), x: u32) u64 {
-        const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + x);
+        const x_slice = mem.sliceTo(@ptrCast([*:0]const u8, self.bytes.items.ptr) + x, 0);
         return hashString(x_slice);
     }
 };
@@ -110,7 +109,7 @@ pub const StringIndexAdapter = struct {
     bytes: *std.ArrayListUnmanaged(u8),
 
     pub fn eql(self: @This(), a_slice: []const u8, b: u32) bool {
-        const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + b);
+        const b_slice = mem.sliceTo(@ptrCast([*:0]const u8, self.bytes.items.ptr) + b, 0);
         return mem.eql(u8, a_slice, b_slice);
     }
 
@@ -120,8 +119,7 @@ pub const StringIndexAdapter = struct {
     }
 };
 
-/// Deprecated use `default_max_load_percentage`
-pub const DefaultMaxLoadPercentage = default_max_load_percentage;
+pub const DefaultMaxLoadPercentage = @compileError("deprecated; use `default_max_load_percentage`");
 
 pub const default_max_load_percentage = 80;
 
@@ -506,8 +504,7 @@ pub fn HashMap(
             return self.unmanaged.getOrPutValueContext(self.allocator, key, value, self.ctx);
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Increases capacity, guaranteeing that insertions up until the
         /// `expected_count` will not cause an allocation, and therefore cannot fail.
@@ -873,8 +870,7 @@ pub fn HashMapUnmanaged(
             return new_cap;
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         pub fn ensureTotalCapacity(self: *Self, allocator: *Allocator, new_size: Size) !void {
             if (@sizeOf(Context) != 0)
@@ -2045,14 +2041,3 @@ test "std.hash_map ensureUnusedCapacity" {
     // should not change the capacity.
     try testing.expectEqual(capacity, map.capacity());
 }
-
-test "compile everything" {
-    std.testing.refAllDecls(AutoHashMap(i32, i32));
-    std.testing.refAllDecls(StringHashMap([]const u8));
-    std.testing.refAllDecls(AutoHashMap(i32, void));
-    std.testing.refAllDecls(StringHashMap(u0));
-    std.testing.refAllDecls(AutoHashMapUnmanaged(i32, i32));
-    std.testing.refAllDecls(StringHashMapUnmanaged([]const u8));
-    std.testing.refAllDecls(AutoHashMapUnmanaged(i32, void));
-    std.testing.refAllDecls(StringHashMapUnmanaged(u0));
-}
lib/std/io.zig
@@ -142,10 +142,9 @@ pub const changeDetectionStream = @import("io/change_detection_stream.zig").chan
 
 pub const FindByteWriter = @import("io/find_byte_writer.zig").FindByteWriter;
 pub const findByteWriter = @import("io/find_byte_writer.zig").findByteWriter;
-/// Deprecated: use `FindByteWriter`.
-pub const FindByteOutStream = FindByteWriter;
-/// Deprecated: use `findByteWriter`.
-pub const findByteOutStream = findByteWriter;
+
+pub const FindByteOutStream = @compileError("deprecated; use `FindByteWriter`");
+pub const findByteOutStream = @compileError("deprecated; use `findByteWriter`");
 
 pub const BufferedAtomicFile = @import("io/buffered_atomic_file.zig").BufferedAtomicFile;
 
@@ -181,6 +180,3 @@ test {
     _ = @import("io/stream_source.zig");
     _ = @import("io/test.zig");
 }
-
-pub const writeFile = @compileError("deprecated: use std.fs.Dir.writeFile with math.maxInt(usize)");
-pub const readFileAlloc = @compileError("deprecated: use std.fs.Dir.readFileAlloc");
lib/std/json.zig
@@ -3135,7 +3135,7 @@ fn teststringify(expected: []const u8, value: anytype, options: StringifyOptions
 
         fn write(self: *Self, bytes: []const u8) Error!usize {
             if (self.expected_remaining.len < bytes.len) {
-                std.debug.warn(
+                std.debug.print(
                     \\====== expected this output: =========
                     \\{s}
                     \\======== instead found this: =========
@@ -3148,7 +3148,7 @@ fn teststringify(expected: []const u8, value: anytype, options: StringifyOptions
                 return error.TooMuchData;
             }
             if (!mem.eql(u8, self.expected_remaining[0..bytes.len], bytes)) {
-                std.debug.warn(
+                std.debug.print(
                     \\====== expected this output: =========
                     \\{s}
                     \\======== instead found this: =========
lib/std/log.zig
@@ -174,14 +174,9 @@ pub fn defaultLog(
 /// provided here.
 pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {
     return struct {
-        /// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-        pub const emerg = @This().err;
-
-        /// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-        pub const alert = @This().err;
-
-        /// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-        pub const crit = @This().err;
+        pub const emerg = @compileError("deprecated; use err instead of emerg");
+        pub const alert = @compileError("deprecated; use err instead of alert");
+        pub const crit = @compileError("deprecated; use err instead of crit");
 
         /// Log an error message. This log level is intended to be used
         /// when something has gone wrong. This might be recoverable or might
@@ -204,8 +199,7 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {
             log(.warn, scope, format, args);
         }
 
-        /// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-        pub const notice = @This().info;
+        pub const notice = @compileError("deprecated; use info instead of notice");
 
         /// Log an info message. This log level is intended to be used for
         /// general messages about the state of the program.
@@ -230,14 +224,9 @@ pub fn scoped(comptime scope: @Type(.EnumLiteral)) type {
 /// The default scoped logging namespace.
 pub const default = scoped(.default);
 
-/// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-pub const emerg = default.err;
-
-/// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-pub const alert = default.err;
-
-/// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-pub const crit = default.err;
+pub const emerg = @compileError("deprecated; use err instead of emerg");
+pub const alert = @compileError("deprecated; use err instead of alert");
+pub const crit = @compileError("deprecated; use err instead of crit");
 
 /// Log an error message using the default scope. This log level is intended to
 /// be used when something has gone wrong. This might be recoverable or might
@@ -249,8 +238,7 @@ pub const err = default.err;
 /// the circumstances would be worth investigating.
 pub const warn = default.warn;
 
-/// Deprecated. TODO: replace with @compileError() after 0.9.0 is released
-pub const notice = default.info;
+pub const notice = @compileError("deprecated; use info instead of notice");
 
 /// Log an info message using the default scope. This log level is intended to
 /// be used for general messages about the state of the program.
lib/std/math.zig
@@ -158,8 +158,13 @@ pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool {
     return fabs(x - y) <= max(fabs(x), fabs(y)) * tolerance;
 }
 
-/// Deprecated, use `approxEqAbs` or `approxEqRel`.
-pub const approxEq = approxEqAbs;
+pub fn approxEq(comptime T: type, x: T, y: T, tolerance: T) bool {
+    _ = T;
+    _ = x;
+    _ = y;
+    _ = tolerance;
+    @compileError("deprecated; use `approxEqAbs` or `approxEqRel`");
+}
 
 test "approxEqAbs and approxEqRel" {
     inline for ([_]type{ f16, f32, f64, f128 }) |T| {
lib/std/mem.zig
@@ -553,9 +553,6 @@ test "indexOfDiff" {
     try testing.expectEqual(indexOfDiff(u8, "xne", "one"), 0);
 }
 
-pub const toSliceConst = @compileError("deprecated; use std.mem.spanZ");
-pub const toSlice = @compileError("deprecated; use std.mem.spanZ");
-
 /// Takes a pointer to an array, a sentinel-terminated pointer, or a slice, and
 /// returns a slice. If there is a sentinel on the input type, there will be a
 /// sentinel on the output type. The constness of the output type matches
@@ -644,34 +641,7 @@ test "span" {
     try testing.expectEqual(@as(?[:0]u16, null), span(@as(?[*:0]u16, null)));
 }
 
-/// Deprecated: use std.mem.span() or std.mem.sliceTo()
-/// Same as `span`, except when there is both a sentinel and an array
-/// length or slice length, scans the memory for the sentinel value
-/// rather than using the length.
-pub fn spanZ(ptr: anytype) Span(@TypeOf(ptr)) {
-    if (@typeInfo(@TypeOf(ptr)) == .Optional) {
-        if (ptr) |non_null| {
-            return spanZ(non_null);
-        } else {
-            return null;
-        }
-    }
-    const Result = Span(@TypeOf(ptr));
-    const l = lenZ(ptr);
-    if (@typeInfo(Result).Pointer.sentinel) |s| {
-        return ptr[0..l :s];
-    } else {
-        return ptr[0..l];
-    }
-}
-
-test "spanZ" {
-    var array: [5]u16 = [_]u16{ 1, 2, 3, 4, 5 };
-    const ptr = @as([*:3]u16, array[0..2 :3]);
-    try testing.expect(eql(u16, spanZ(ptr), &[_]u16{ 1, 2 }));
-    try testing.expect(eql(u16, spanZ(&array), &[_]u16{ 1, 2, 3, 4, 5 }));
-    try testing.expectEqual(@as(?[:0]u16, null), spanZ(@as(?[*:0]u16, null)));
-}
+pub const spanZ = @compileError("deprecated; use use std.mem.span() or std.mem.sliceTo()");
 
 /// Helper for the return type of sliceTo()
 fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
@@ -917,61 +887,7 @@ test "len" {
     }
 }
 
-/// Deprecated: use std.mem.len() or std.mem.sliceTo().len
-/// Takes a pointer to an array, an array, a sentinel-terminated pointer,
-/// or a slice, and returns the length.
-/// In the case of a sentinel-terminated array, it scans the array
-/// for a sentinel and uses that for the length, rather than using the array length.
-/// For C pointers it assumes it is a pointer-to-many with a 0 sentinel.
-pub fn lenZ(ptr: anytype) usize {
-    return switch (@typeInfo(@TypeOf(ptr))) {
-        .Array => |info| if (info.sentinel) |sentinel|
-            indexOfSentinel(info.child, sentinel, &ptr)
-        else
-            info.len,
-        .Pointer => |info| switch (info.size) {
-            .One => switch (@typeInfo(info.child)) {
-                .Array => |x| if (x.sentinel) |sentinel|
-                    indexOfSentinel(x.child, sentinel, ptr)
-                else
-                    ptr.len,
-                else => @compileError("invalid type given to std.mem.lenZ"),
-            },
-            .Many => if (info.sentinel) |sentinel|
-                indexOfSentinel(info.child, sentinel, ptr)
-            else
-                @compileError("length of pointer with no sentinel"),
-            .C => {
-                assert(ptr != null);
-                return indexOfSentinel(info.child, 0, ptr);
-            },
-            .Slice => if (info.sentinel) |sentinel|
-                indexOfSentinel(info.child, sentinel, ptr.ptr)
-            else
-                ptr.len,
-        },
-        else => @compileError("invalid type given to std.mem.lenZ"),
-    };
-}
-
-test "lenZ" {
-    try testing.expect(lenZ("aoeu") == 4);
-
-    {
-        var array: [5]u16 = [_]u16{ 1, 2, 3, 4, 5 };
-        try testing.expect(lenZ(&array) == 5);
-        try testing.expect(lenZ(array[0..3]) == 3);
-        array[2] = 0;
-        const ptr = @as([*:0]u16, array[0..2 :0]);
-        try testing.expect(lenZ(ptr) == 2);
-    }
-    {
-        var array: [5:0]u16 = [_:0]u16{ 1, 2, 3, 4, 5 };
-        try testing.expect(lenZ(&array) == 5);
-        array[2] = 0;
-        try testing.expect(lenZ(&array) == 2);
-    }
-}
+pub const lenZ = @compileError("deprecated; use std.mem.len() or std.mem.sliceTo().len");
 
 pub fn indexOfSentinel(comptime Elem: type, comptime sentinel: Elem, ptr: [*:sentinel]const Elem) usize {
     var i: usize = 0;
@@ -989,15 +905,8 @@ pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool {
     return true;
 }
 
-/// Deprecated, use `Allocator.dupe`.
-pub fn dupe(allocator: *Allocator, comptime T: type, m: []const T) ![]T {
-    return allocator.dupe(T, m);
-}
-
-/// Deprecated, use `Allocator.dupeZ`.
-pub fn dupeZ(allocator: *Allocator, comptime T: type, m: []const T) ![:0]T {
-    return allocator.dupeZ(T, m);
-}
+pub const dupe = @compileError("deprecated; use `Allocator.dupe`");
+pub const dupeZ = @compileError("deprecated; use `Allocator.dupeZ`");
 
 /// Remove values from the beginning of a slice.
 pub fn trimLeft(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {
@@ -1727,8 +1636,6 @@ pub fn split(comptime T: type, buffer: []const T, delimiter: []const T) SplitIte
     };
 }
 
-pub const separate = @compileError("deprecated: renamed to split (behavior remains unchanged)");
-
 test "mem.split" {
     var it = split(u8, "abc|def||ghi", "|");
     try testing.expect(eql(u8, it.next().?, "abc"));
@@ -3024,7 +2931,7 @@ test "isAligned" {
 }
 
 test "freeing empty string with null-terminated sentinel" {
-    const empty_string = try dupeZ(testing.allocator, u8, "");
+    const empty_string = try testing.allocator.dupeZ(u8, "");
     testing.allocator.free(empty_string);
 }
 
lib/std/meta.zig
@@ -594,8 +594,7 @@ test "std.meta.FieldEnum" {
     try expectEqualEnum(enum { a, b, c }, FieldEnum(union { a: u8, b: void, c: f32 }));
 }
 
-// Deprecated: use Tag
-pub const TagType = Tag;
+pub const TagType = @compileError("deprecated; use Tag");
 
 pub fn Tag(comptime T: type) type {
     return switch (@typeInfo(T)) {
lib/std/multi_array_list.zig
@@ -309,8 +309,7 @@ pub fn MultiArrayList(comptime S: type) type {
             self.len = new_len;
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Modify the array so that it can hold at least `new_capacity` items.
         /// Implements super-linear growth to achieve amortized O(1) append operations.
lib/std/net.zig
@@ -785,7 +785,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
 
             if (info.canonname) |n| {
                 if (result.canon_name == null) {
-                    result.canon_name = try arena.dupe(u8, mem.spanZ(n));
+                    result.canon_name = try arena.dupe(u8, mem.sliceTo(n, 0));
                 }
             }
             i += 1;
@@ -1588,7 +1588,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
             var tmp: [256]u8 = undefined;
             // Returns len of compressed name. strlen to get canon name.
             _ = try os.dn_expand(packet, data, &tmp);
-            const canon_name = mem.spanZ(std.meta.assumeSentinel(&tmp, 0));
+            const canon_name = mem.sliceTo(std.meta.assumeSentinel(&tmp, 0), 0);
             if (isValidHostName(canon_name)) {
                 ctx.canon.items.len = 0;
                 try ctx.canon.appendSlice(canon_name);
lib/std/os.zig
@@ -1289,8 +1289,6 @@ pub fn open(file_path: []const u8, flags: u32, perm: mode_t) OpenError!fd_t {
     return openZ(&file_path_c, flags, perm);
 }
 
-pub const openC = @compileError("deprecated: renamed to openZ");
-
 /// Open and possibly create a file. Keeps trying if it gets interrupted.
 /// See also `open`.
 pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t {
@@ -1429,8 +1427,6 @@ pub fn openatWasi(dir_fd: fd_t, file_path: []const u8, lookup_flags: lookupflags
     }
 }
 
-pub const openatC = @compileError("deprecated: renamed to openatZ");
-
 /// Open and possibly create a file. Keeps trying if it gets interrupted.
 /// `file_path` is relative to the open directory handle `dir_fd`.
 /// See also `openat`.
@@ -1529,8 +1525,6 @@ pub const ExecveError = error{
     NameTooLong,
 } || UnexpectedError;
 
-pub const execveC = @compileError("deprecated: use execveZ");
-
 /// Like `execve` except the parameters are null-terminated,
 /// matching the syscall API on all targets. This removes the need for an allocator.
 /// This function ignores PATH environment variable. See `execvpeZ` for that.
@@ -1561,8 +1555,6 @@ pub fn execveZ(
     }
 }
 
-pub const execvpeC = @compileError("deprecated in favor of execvpeZ");
-
 pub const Arg0Expand = enum {
     expand,
     no_expand,
@@ -1580,7 +1572,7 @@ pub fn execvpeZ_expandArg0(
     },
     envp: [*:null]const ?[*:0]const u8,
 ) ExecveError {
-    const file_slice = mem.spanZ(file);
+    const file_slice = mem.sliceTo(file, 0);
     if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveZ(file, child_argv, envp);
 
     const PATH = getenvZ("PATH") orelse "/usr/local/bin:/bin/:/usr/bin";
@@ -1680,19 +1672,17 @@ pub fn getenv(key: []const u8) ?[]const u8 {
     return null;
 }
 
-pub const getenvC = @compileError("Deprecated in favor of `getenvZ`");
-
 /// Get an environment variable with a null-terminated name.
 /// See also `getenv`.
 pub fn getenvZ(key: [*:0]const u8) ?[]const u8 {
     if (builtin.link_libc) {
         const value = system.getenv(key) orelse return null;
-        return mem.spanZ(value);
+        return mem.sliceTo(value, 0);
     }
     if (builtin.os.tag == .windows) {
         @compileError("std.os.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");
     }
-    return getenv(mem.spanZ(key));
+    return getenv(mem.sliceTo(key, 0));
 }
 
 /// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name.
@@ -1703,7 +1693,7 @@ pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 {
     if (builtin.os.tag != .windows) {
         @compileError("std.os.getenvW is a Windows-only API");
     }
-    const key_slice = mem.spanZ(key);
+    const key_slice = mem.sliceTo(key, 0);
     const ptr = windows.peb().ProcessParameters.Environment;
     var ascii_match: ?[:0]const u16 = null;
     var i: usize = 0;
@@ -1758,7 +1748,7 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
         break :blk errno(system.getcwd(out_buffer.ptr, out_buffer.len));
     };
     switch (err) {
-        .SUCCESS => return mem.spanZ(std.meta.assumeSentinel(out_buffer.ptr, 0)),
+        .SUCCESS => return mem.sliceTo(std.meta.assumeSentinel(out_buffer.ptr, 0), 0),
         .FAULT => unreachable,
         .INVAL => unreachable,
         .NOENT => return error.CurrentWorkingDirectoryUnlinked,
@@ -1802,8 +1792,6 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!
     return symlinkZ(&target_path_c, &sym_link_path_c);
 }
 
-pub const symlinkC = @compileError("deprecated: renamed to symlinkZ");
-
 /// This is the same as `symlink` except the parameters are null-terminated pointers.
 /// See also `symlink`.
 pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLinkError!void {
@@ -1848,8 +1836,6 @@ pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const
     return symlinkatZ(&target_path_c, newdirfd, &sym_link_path_c);
 }
 
-pub const symlinkatC = @compileError("deprecated: renamed to symlinkatZ");
-
 /// WASI-only. The same as `symlinkat` but targeting WASI.
 /// See also `symlinkat`.
 pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const u8) SymLinkError!void {
@@ -2023,8 +2009,6 @@ pub fn unlink(file_path: []const u8) UnlinkError!void {
     }
 }
 
-pub const unlinkC = @compileError("deprecated: renamed to unlinkZ");
-
 /// Same as `unlink` except the parameter is a null terminated UTF8-encoded string.
 pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {
     if (builtin.os.tag == .windows) {
@@ -2074,8 +2058,6 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo
     }
 }
 
-pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ");
-
 /// WASI-only. Same as `unlinkat` but targeting WASI.
 /// See also `unlinkat`.
 pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
@@ -2183,8 +2165,6 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
     }
 }
 
-pub const renameC = @compileError("deprecated: renamed to renameZ");
-
 /// Same as `rename` except the parameters are null-terminated byte arrays.
 pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!void {
     if (builtin.os.tag == .windows) {
@@ -2378,8 +2358,6 @@ pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!v
     }
 }
 
-pub const mkdiratC = @compileError("deprecated: renamed to mkdiratZ");
-
 pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void {
     _ = mode;
     switch (wasi.path_create_directory(dir_fd, sub_dir_path.ptr, sub_dir_path.len)) {
@@ -2548,8 +2526,6 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
     }
 }
 
-pub const rmdirC = @compileError("deprecated: renamed to rmdirZ");
-
 /// Same as `rmdir` except the parameter is null-terminated.
 pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {
     if (builtin.os.tag == .windows) {
@@ -2613,8 +2589,6 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
     }
 }
 
-pub const chdirC = @compileError("deprecated: renamed to chdirZ");
-
 /// Same as `chdir` except the parameter is null-terminated.
 pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void {
     if (builtin.os.tag == .windows) {
@@ -2697,8 +2671,6 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
     }
 }
 
-pub const readlinkC = @compileError("deprecated: renamed to readlinkZ");
-
 /// Windows-only. Same as `readlink` except `file_path` is WTF16 encoded.
 /// See also `readlinkZ`.
 pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
@@ -2742,8 +2714,6 @@ pub fn readlinkat(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLink
     return readlinkatZ(dirfd, &file_path_c, out_buffer);
 }
 
-pub const readlinkatC = @compileError("deprecated: renamed to readlinkatZ");
-
 /// WASI-only. Same as `readlinkat` but targets WASI.
 /// See also `readlinkat`.
 pub fn readlinkatWasi(dirfd: fd_t, file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
@@ -3737,8 +3707,6 @@ pub fn fstatat(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat
     }
 }
 
-pub const fstatatC = @compileError("deprecated: renamed to fstatatZ");
-
 /// WASI-only. Same as `fstatat` but targeting WASI.
 /// See also `fstatat`.
 pub fn fstatatWasi(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!Stat {
@@ -3883,8 +3851,6 @@ pub fn inotify_add_watch(inotify_fd: i32, pathname: []const u8, mask: u32) INoti
     return inotify_add_watchZ(inotify_fd, &pathname_c, mask);
 }
 
-pub const inotify_add_watchC = @compileError("deprecated: renamed to inotify_add_watchZ");
-
 /// Same as `inotify_add_watch` except pathname is null-terminated.
 pub fn inotify_add_watchZ(inotify_fd: i32, pathname: [*:0]const u8, mask: u32) INotifyAddWatchError!i32 {
     const rc = system.inotify_add_watch(inotify_fd, pathname, mask);
@@ -4053,8 +4019,6 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {
     return accessZ(&path_c, mode);
 }
 
-pub const accessC = @compileError("Deprecated in favor of `accessZ`");
-
 /// Same as `access` except `path` is null-terminated.
 pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
     if (builtin.os.tag == .windows) {
@@ -4143,7 +4107,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32
         return;
     }
 
-    const path_len_bytes = math.cast(u16, mem.lenZ(sub_path_w) * 2) catch |err| switch (err) {
+    const path_len_bytes = math.cast(u16, mem.sliceTo(sub_path_w, 0).len * 2) catch |err| switch (err) {
         error.Overflow => return error.NameTooLong,
     };
     var nt_name = windows.UNICODE_STRING{
@@ -4273,8 +4237,6 @@ pub fn sysctl(
     }
 }
 
-pub const sysctlbynameC = @compileError("deprecated: renamed to sysctlbynameZ");
-
 pub fn sysctlbynameZ(
     name: [*:0]const u8,
     oldp: ?*c_void,
@@ -4651,8 +4613,6 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE
     return realpathZ(&pathname_c, out_buffer);
 }
 
-pub const realpathC = @compileError("deprecated: renamed realpathZ");
-
 /// Same as `realpath` except `pathname` is null-terminated.
 pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
     if (builtin.os.tag == .windows) {
@@ -4684,7 +4644,7 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP
         .IO => return error.InputOutput,
         else => |err| return unexpectedErrno(err),
     };
-    return mem.spanZ(result_path);
+    return mem.sliceTo(result_path, 0);
 }
 
 /// Same as `realpath` except `pathname` is UTF16LE-encoded.
@@ -4997,7 +4957,7 @@ pub const UnexpectedError = error{
 /// and you get an unexpected error.
 pub fn unexpectedErrno(err: E) UnexpectedError {
     if (unexpected_error_tracing) {
-        std.debug.warn("unexpected errno: {d}\n", .{@enumToInt(err)});
+        std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)});
         std.debug.dumpCurrentStackTrace(null);
     }
     return error.Unexpected;
@@ -5092,7 +5052,7 @@ pub const GetHostNameError = error{PermissionDenied} || UnexpectedError;
 pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
     if (builtin.link_libc) {
         switch (errno(system.gethostname(name_buffer, name_buffer.len))) {
-            .SUCCESS => return mem.spanZ(std.meta.assumeSentinel(name_buffer, 0)),
+            .SUCCESS => return mem.sliceTo(std.meta.assumeSentinel(name_buffer, 0), 0),
             .FAULT => unreachable,
             .NAMETOOLONG => unreachable, // HOST_NAME_MAX prevents this
             .PERM => return error.PermissionDenied,
@@ -5101,7 +5061,7 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
     }
     if (builtin.os.tag == .linux) {
         const uts = uname();
-        const hostname = mem.spanZ(std.meta.assumeSentinel(&uts.nodename, 0));
+        const hostname = mem.sliceTo(std.meta.assumeSentinel(&uts.nodename, 0), 0);
         mem.copy(u8, name_buffer, hostname);
         return name_buffer[0..hostname.len];
     }
@@ -6130,8 +6090,6 @@ pub const MemFdCreateError = error{
     SystemOutdated,
 } || UnexpectedError;
 
-pub const memfd_createC = @compileError("deprecated: renamed to memfd_createZ");
-
 pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
     // memfd_create is available only in glibc versions starting with 2.27.
     const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok;
lib/std/pdb.zig
@@ -3,7 +3,6 @@ const io = std.io;
 const math = std.math;
 const mem = std.mem;
 const os = std.os;
-const warn = std.debug.warn;
 const coff = std.coff;
 const fs = std.fs;
 const File = std.fs.File;
@@ -656,7 +655,7 @@ pub const Pdb = struct {
                 const name_index = try reader.readIntLittle(u32);
                 if (name_offset > name_bytes.len)
                     return error.InvalidDebugInfo;
-                const name = mem.spanZ(std.meta.assumeSentinel(name_bytes.ptr + name_offset, 0));
+                const name = mem.sliceTo(std.meta.assumeSentinel(name_bytes.ptr + name_offset, 0), 0);
                 if (mem.eql(u8, name, "/names")) {
                     break :str_tab_index name_index;
                 }
@@ -681,7 +680,7 @@ pub const Pdb = struct {
                 .S_LPROC32, .S_GPROC32 => {
                     const proc_sym = @ptrCast(*ProcSym, &module.symbols[symbol_i + @sizeOf(RecordPrefix)]);
                     if (address >= proc_sym.CodeOffset and address < proc_sym.CodeOffset + proc_sym.CodeSize) {
-                        return mem.spanZ(@ptrCast([*:0]u8, proc_sym) + @sizeOf(ProcSym));
+                        return mem.sliceTo(@ptrCast([*:0]u8, proc_sym) + @sizeOf(ProcSym), 0);
                     }
                 },
                 else => {},
lib/std/priority_dequeue.zig
@@ -1,7 +1,6 @@
 const std = @import("std.zig");
 const Allocator = std.mem.Allocator;
 const assert = std.debug.assert;
-const warn = std.debug.warn;
 const Order = std.math.Order;
 const testing = std.testing;
 const expect = testing.expect;
@@ -355,8 +354,7 @@ pub fn PriorityDequeue(comptime T: type, comptime compareFn: fn (T, T) Order) ty
             return queue;
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
 
         /// Ensure that the dequeue can fit at least `new_capacity` items.
         pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) !void {
@@ -421,19 +419,20 @@ pub fn PriorityDequeue(comptime T: type, comptime compareFn: fn (T, T) Order) ty
         }
 
         fn dump(self: *Self) void {
-            warn("{{ ", .{});
-            warn("items: ", .{});
+            const print = std.debug.print;
+            print("{{ ", .{});
+            print("items: ", .{});
             for (self.items) |e, i| {
                 if (i >= self.len) break;
-                warn("{}, ", .{e});
+                print("{}, ", .{e});
             }
-            warn("array: ", .{});
+            print("array: ", .{});
             for (self.items) |e| {
-                warn("{}, ", .{e});
+                print("{}, ", .{e});
             }
-            warn("len: {} ", .{self.len});
-            warn("capacity: {}", .{self.capacity()});
-            warn(" }}\n", .{});
+            print("len: {} ", .{self.len});
+            print("capacity: {}", .{self.capacity()});
+            print(" }}\n", .{});
         }
 
         fn parentIndex(index: usize) usize {
lib/std/priority_queue.zig
@@ -1,7 +1,6 @@
 const std = @import("std.zig");
 const Allocator = std.mem.Allocator;
 const assert = std.debug.assert;
-const warn = std.debug.warn;
 const Order = std.math.Order;
 const testing = std.testing;
 const expect = testing.expect;
@@ -171,8 +170,7 @@ pub fn PriorityQueue(comptime T: type, comptime compareFn: fn (a: T, b: T) Order
             return queue;
         }
 
-        /// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
-        pub const ensureCapacity = ensureTotalCapacity;
+        pub const ensureCapacity = @compileError("deprecated; use ensureUnusedCapacity or ensureTotalCapacity");
 
         /// Ensure that the queue can fit at least `new_capacity` items.
         pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) !void {
@@ -242,19 +240,20 @@ pub fn PriorityQueue(comptime T: type, comptime compareFn: fn (a: T, b: T) Order
         }
 
         fn dump(self: *Self) void {
-            warn("{{ ", .{});
-            warn("items: ", .{});
+            const print = std.debug.print;
+            print("{{ ", .{});
+            print("items: ", .{});
             for (self.items) |e, i| {
                 if (i >= self.len) break;
-                warn("{}, ", .{e});
+                print("{}, ", .{e});
             }
-            warn("array: ", .{});
+            print("array: ", .{});
             for (self.items) |e| {
-                warn("{}, ", .{e});
+                print("{}, ", .{e});
             }
-            warn("len: {} ", .{self.len});
-            warn("capacity: {}", .{self.capacity()});
-            warn(" }}\n", .{});
+            print("len: {} ", .{self.len});
+            print("capacity: {}", .{self.capacity()});
+            print(" }}\n", .{});
         }
     };
 }
lib/std/process.zig
@@ -103,7 +103,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
         }
 
         for (environ) |env| {
-            const pair = mem.spanZ(env);
+            const pair = mem.sliceTo(env, 0);
             var parts = mem.split(u8, pair, "=");
             const key = parts.next().?;
             const value = parts.next().?;
@@ -215,7 +215,7 @@ pub const ArgIteratorPosix = struct {
 
         const s = os.argv[self.index];
         self.index += 1;
-        return mem.spanZ(s);
+        return mem.sliceTo(s, 0);
     }
 
     pub fn skip(self: *ArgIteratorPosix) bool {
@@ -267,7 +267,7 @@ pub const ArgIteratorWasi = struct {
         var result_args = try allocator.alloc([:0]u8, count);
         var i: usize = 0;
         while (i < count) : (i += 1) {
-            result_args[i] = mem.spanZ(argv[i]);
+            result_args[i] = mem.sliceTo(argv[i], 0);
         }
 
         return result_args;
@@ -768,7 +768,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
                     _ = size;
                     const name = info.dlpi_name orelse return;
                     if (name[0] == '/') {
-                        const item = try list.allocator.dupeZ(u8, mem.spanZ(name));
+                        const item = try list.allocator.dupeZ(u8, mem.sliceTo(name, 0));
                         errdefer list.allocator.free(item);
                         try list.append(item);
                     }
@@ -789,7 +789,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
             var i: u32 = 0;
             while (i < img_count) : (i += 1) {
                 const name = std.c._dyld_get_image_name(i);
-                const item = try allocator.dupeZ(u8, mem.spanZ(name));
+                const item = try allocator.dupeZ(u8, mem.sliceTo(name, 0));
                 errdefer allocator.free(item);
                 try paths.append(item);
             }
@@ -807,7 +807,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
             }
 
             var b = "/boot/system/runtime_loader";
-            const item = try allocator.dupeZ(u8, mem.spanZ(b));
+            const item = try allocator.dupeZ(u8, mem.sliceTo(b, 0));
             errdefer allocator.free(item);
             try paths.append(item);
 
lib/std/rand.zig
@@ -245,10 +245,6 @@ pub const Random = struct {
         }
     }
 
-    pub const scalar = @compileError("deprecated; use boolean() or int() instead");
-
-    pub const range = @compileError("deprecated; use intRangeLessThan()");
-
     /// Return a floating point value evenly distributed in the range [0, 1).
     pub fn float(r: Random, comptime T: type) T {
         // Generate a uniform value between [1, 2) and scale down to [0, 1).
lib/std/testing.zig
@@ -208,9 +208,6 @@ pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anyt
     return error.TestExpectedFmt;
 }
 
-pub const expectWithinMargin = @compileError("expectWithinMargin is deprecated, use expectApproxEqAbs or expectApproxEqRel");
-pub const expectWithinEpsilon = @compileError("expectWithinEpsilon is deprecated, use expectApproxEqAbs or expectApproxEqRel");
-
 /// This function is intended to be used only in tests. When the actual value is
 /// not approximately equal to the expected value, prints diagnostics to stderr
 /// to show exactly how they are not equal, then aborts.
lib/std/Thread.zig
@@ -17,8 +17,6 @@ pub const Mutex = @import("Thread/Mutex.zig");
 pub const Semaphore = @import("Thread/Semaphore.zig");
 pub const Condition = @import("Thread/Condition.zig");
 
-pub const spinLoopHint = @compileError("deprecated: use std.atomic.spinLoopHint");
-
 pub const use_pthreads = target.os.tag != .windows and target.os.tag != .wasi and builtin.link_libc;
 const is_gnu = target.abi.isGnu();
 
@@ -361,7 +359,7 @@ fn callFn(comptime f: anytype, args: anytype) switch (Impl) {
             }
 
             @call(.{}, f, args) catch |err| {
-                std.debug.warn("error: {s}\n", .{@errorName(err)});
+                std.debug.print("error: {s}\n", .{@errorName(err)});
                 if (@errorReturnTrace()) |trace| {
                     std.debug.dumpStackTrace(trace.*);
                 }
lib/std/unicode.zig
@@ -216,7 +216,7 @@ pub fn utf8ValidateSlice(s: []const u8) bool {
 /// ```
 /// var utf8 = (try std.unicode.Utf8View.init("hi there")).iterator();
 /// while (utf8.nextCodepointSlice()) |codepoint| {
-///   std.debug.warn("got codepoint {}\n", .{codepoint});
+///   std.debug.print("got codepoint {}\n", .{codepoint});
 /// }
 /// ```
 pub const Utf8View = struct {
lib/std/zig.zig
@@ -12,7 +12,7 @@ pub const parse = @import("zig/parse.zig").parse;
 pub const string_literal = @import("zig/string_literal.zig");
 pub const Ast = @import("zig/Ast.zig");
 pub const system = @import("zig/system.zig");
-pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;
+pub const CrossTarget = @import("zig/CrossTarget.zig");
 
 // Files needed by translate-c.
 pub const c_builtins = @import("zig/c_builtins.zig");
src/arch/aarch64/CodeGen.zig
@@ -1501,7 +1501,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
                 });
             } else if (func_value.castTag(.extern_fn)) |func_payload| {
                 const decl = func_payload.data;
-                const n_strx = try macho_file.addExternFn(mem.spanZ(decl.name));
+                const n_strx = try macho_file.addExternFn(mem.sliceTo(decl.name, 0));
 
                 _ = try self.addInst(.{
                     .tag = .call_extern,
src/arch/x86_64/CodeGen.zig
@@ -1966,7 +1966,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
                 });
             } else if (func_value.castTag(.extern_fn)) |func_payload| {
                 const decl = func_payload.data;
-                const n_strx = try macho_file.addExternFn(mem.spanZ(decl.name));
+                const n_strx = try macho_file.addExternFn(mem.sliceTo(decl.name, 0));
                 _ = try self.addInst(.{
                     .tag = .call_extern,
                     .ops = undefined,
src/codegen/c.zig
@@ -981,7 +981,7 @@ pub const DeclGen = struct {
         if (dg.module.decl_exports.get(decl)) |exports| {
             return writer.writeAll(exports[0].options.name);
         } else if (decl.val.tag() == .extern_fn) {
-            return writer.writeAll(mem.spanZ(decl.name));
+            return writer.writeAll(mem.sliceTo(decl.name, 0));
         } else {
             const gpa = dg.module.gpa;
             const name = try decl.getFullyQualifiedName(gpa);
src/link/MachO/Archive.zig
@@ -175,7 +175,7 @@ fn parseTableOfContents(self: *Archive, allocator: *Allocator, reader: anytype)
         };
         const object_offset = try symtab_reader.readIntLittle(u32);
 
-        const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + n_strx));
+        const sym_name = mem.sliceTo(@ptrCast([*:0]const u8, strtab.ptr + n_strx), 0);
         const owned_name = try allocator.dupe(u8, sym_name);
         const res = try self.toc.getOrPut(allocator, owned_name);
         defer if (res.found_existing) allocator.free(owned_name);
src/link/MachO/DebugSymbols.zig
@@ -884,7 +884,7 @@ pub fn initDeclDebugBuffers(
             dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);
 
             // .debug_info subprogram
-            const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];
+            const decl_name_with_null = decl.name[0 .. mem.sliceTo(decl.name, 0).len + 1];
             try dbg_info_buffer.ensureUnusedCapacity(27 + decl_name_with_null.len);
 
             const fn_ret_type = decl.ty.fnReturnType();
src/link/MachO/Dylib.zig
@@ -56,7 +56,7 @@ pub const Id = struct {
     pub fn fromLoadCommand(allocator: *Allocator, lc: commands.GenericCommandWithData(macho.dylib_command)) !Id {
         const dylib = lc.inner.dylib;
         const dylib_name = @ptrCast([*:0]const u8, lc.data[dylib.name - @sizeOf(macho.dylib_command) ..]);
-        const name = try allocator.dupe(u8, mem.spanZ(dylib_name));
+        const name = try allocator.dupe(u8, mem.sliceTo(dylib_name, 0));
 
         return Id{
             .name = name,
@@ -230,7 +230,7 @@ fn parseSymbols(self: *Dylib, allocator: *Allocator) !void {
 
         if (!add_to_symtab) continue;
 
-        const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx));
+        const sym_name = mem.sliceTo(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx), 0);
         const name = try allocator.dupe(u8, sym_name);
         try self.symbols.putNoClobber(allocator, name, {});
     }
src/link/MachO/Object.zig
@@ -633,5 +633,5 @@ fn readSection(self: Object, allocator: *Allocator, index: u16) ![]u8 {
 
 pub fn getString(self: Object, off: u32) []const u8 {
     assert(off < self.strtab.items.len);
-    return mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr + off));
+    return mem.sliceTo(@ptrCast([*:0]const u8, self.strtab.items.ptr + off), 0);
 }
src/link/Coff.zig
@@ -752,7 +752,7 @@ fn finishUpdateDecl(self: *Coff, module: *Module, decl: *Module.Decl, code: []co
     } else {
         const vaddr = try self.allocateTextBlock(&decl.link.coff, code.len, required_alignment);
         log.debug("allocated text block for {s} at 0x{x} (size: {Bi})\n", .{
-            mem.spanZ(decl.name),
+            mem.sliceTo(decl.name, 0),
             vaddr,
             std.fmt.fmtIntSizeDec(code.len),
         });
src/link/Elf.zig
@@ -429,7 +429,7 @@ fn makeDebugString(self: *Elf, bytes: []const u8) !u32 {
 
 fn getString(self: *Elf, str_off: u32) []const u8 {
     assert(str_off < self.shstrtab.items.len);
-    return mem.spanZ(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off));
+    return mem.sliceTo(@ptrCast([*:0]const u8, self.shstrtab.items.ptr + str_off), 0);
 }
 
 fn updateString(self: *Elf, old_str_off: u32, new_name: []const u8) !u32 {
@@ -2236,14 +2236,14 @@ fn updateDeclCode(self: *Elf, decl: *Module.Decl, code: []const u8, stt_bits: u8
             self.shrinkTextBlock(&decl.link.elf, code.len);
         }
         local_sym.st_size = code.len;
-        local_sym.st_name = try self.updateString(local_sym.st_name, mem.spanZ(decl.name));
+        local_sym.st_name = try self.updateString(local_sym.st_name, mem.sliceTo(decl.name, 0));
         local_sym.st_info = (elf.STB_LOCAL << 4) | stt_bits;
         local_sym.st_other = 0;
         local_sym.st_shndx = self.text_section_index.?;
         // TODO this write could be avoided if no fields of the symbol were changed.
         try self.writeSymbol(decl.link.elf.local_sym_index);
     } else {
-        const decl_name = mem.spanZ(decl.name);
+        const decl_name = mem.sliceTo(decl.name, 0);
         const name_str_index = try self.makeString(decl_name);
         const vaddr = try self.allocateTextBlock(&decl.link.elf, code.len, required_alignment);
         log.debug("allocated text block for {s} at 0x{x}", .{ decl_name, vaddr });
@@ -2371,7 +2371,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
     dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);
 
     // .debug_info subprogram
-    const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];
+    const decl_name_with_null = decl.name[0 .. mem.sliceTo(decl.name, 0).len + 1];
     try dbg_info_buffer.ensureUnusedCapacity(25 + decl_name_with_null.len);
 
     const fn_ret_type = decl.ty.fnReturnType();
src/link/MachO.zig
@@ -3439,7 +3439,9 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
         decl.link.macho.size = code_len;
         decl.link.macho.dirty = true;
 
-        const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
+        const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{
+            mem.sliceTo(decl.name, 0),
+        });
         defer self.base.allocator.free(new_name);
 
         symbol.n_strx = try self.makeString(new_name);
@@ -3447,7 +3449,9 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
         symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
         symbol.n_desc = 0;
     } else {
-        const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)});
+        const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{
+            mem.sliceTo(decl.name, 0),
+        });
         defer self.base.allocator.free(decl_name);
 
         const name_str_index = try self.makeString(decl_name);
@@ -4045,7 +4049,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
         self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len);
         const cmdsize = @intCast(u32, mem.alignForwardGeneric(
             u64,
-            @sizeOf(macho.dylinker_command) + mem.lenZ(default_dyld_path),
+            @sizeOf(macho.dylinker_command) + mem.sliceTo(default_dyld_path, 0).len,
             @sizeOf(u64),
         ));
         var dylinker_cmd = commands.emptyGenericCommandWithData(macho.dylinker_command{
@@ -4055,7 +4059,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
         });
         dylinker_cmd.data = try self.base.allocator.alloc(u8, cmdsize - dylinker_cmd.inner.name);
         mem.set(u8, dylinker_cmd.data, 0);
-        mem.copy(u8, dylinker_cmd.data, mem.spanZ(default_dyld_path));
+        mem.copy(u8, dylinker_cmd.data, mem.sliceTo(default_dyld_path, 0));
         try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd });
         self.load_commands_dirty = true;
     }
@@ -5292,7 +5296,7 @@ pub fn makeString(self: *MachO, string: []const u8) !u32 {
 
 pub fn getString(self: *MachO, off: u32) []const u8 {
     assert(off < self.strtab.items.len);
-    return mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr + off));
+    return mem.sliceTo(@ptrCast([*:0]const u8, self.strtab.items.ptr + off), 0);
 }
 
 pub fn symbolIsStab(sym: macho.nlist_64) bool {
src/link/Plan9.zig
@@ -299,7 +299,7 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {
             return;
         },
     };
-    var duped_code = try std.mem.dupe(self.base.allocator, u8, code);
+    var duped_code = try self.base.allocator.dupe(u8, code);
     errdefer self.base.allocator.free(duped_code);
     try self.data_decl_table.put(self.base.allocator, decl, duped_code);
     return self.updateFinish(decl);
src/AstGen.zig
@@ -8399,7 +8399,7 @@ fn parseStrLit(
     const raw_string = bytes[offset..];
     var buf_managed = buf.toManaged(astgen.gpa);
     const result = std.zig.string_literal.parseAppend(&buf_managed, raw_string);
-    buf.* = buf_managed.toUnmanaged();
+    buf.* = buf_managed.moveToUnmanaged();
     switch (try result) {
         .success => return,
         .invalid_character => |bad_index| {
@@ -8472,11 +8472,7 @@ fn failNodeNotes(
     @setCold(true);
     const string_bytes = &astgen.string_bytes;
     const msg = @intCast(u32, string_bytes.items.len);
-    {
-        var managed = string_bytes.toManaged(astgen.gpa);
-        defer string_bytes.* = managed.toUnmanaged();
-        try managed.writer().print(format ++ "\x00", args);
-    }
+    try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
     const notes_index: u32 = if (notes.len != 0) blk: {
         const notes_start = astgen.extra.items.len;
         try astgen.extra.ensureTotalCapacity(astgen.gpa, notes_start + 1 + notes.len);
@@ -8513,11 +8509,7 @@ fn failTokNotes(
     @setCold(true);
     const string_bytes = &astgen.string_bytes;
     const msg = @intCast(u32, string_bytes.items.len);
-    {
-        var managed = string_bytes.toManaged(astgen.gpa);
-        defer string_bytes.* = managed.toUnmanaged();
-        try managed.writer().print(format ++ "\x00", args);
-    }
+    try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
     const notes_index: u32 = if (notes.len != 0) blk: {
         const notes_start = astgen.extra.items.len;
         try astgen.extra.ensureTotalCapacity(astgen.gpa, notes_start + 1 + notes.len);
@@ -8546,11 +8538,7 @@ fn failOff(
     @setCold(true);
     const string_bytes = &astgen.string_bytes;
     const msg = @intCast(u32, string_bytes.items.len);
-    {
-        var managed = string_bytes.toManaged(astgen.gpa);
-        defer string_bytes.* = managed.toUnmanaged();
-        try managed.writer().print(format ++ "\x00", args);
-    }
+    try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
     try astgen.compile_errors.append(astgen.gpa, .{
         .msg = msg,
         .node = 0,
@@ -8570,11 +8558,7 @@ fn errNoteTok(
     @setCold(true);
     const string_bytes = &astgen.string_bytes;
     const msg = @intCast(u32, string_bytes.items.len);
-    {
-        var managed = string_bytes.toManaged(astgen.gpa);
-        defer string_bytes.* = managed.toUnmanaged();
-        try managed.writer().print(format ++ "\x00", args);
-    }
+    try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
     return astgen.addExtra(Zir.Inst.CompileErrors.Item{
         .msg = msg,
         .node = 0,
@@ -8593,11 +8577,7 @@ fn errNoteNode(
     @setCold(true);
     const string_bytes = &astgen.string_bytes;
     const msg = @intCast(u32, string_bytes.items.len);
-    {
-        var managed = string_bytes.toManaged(astgen.gpa);
-        defer string_bytes.* = managed.toUnmanaged();
-        try managed.writer().print(format ++ "\x00", args);
-    }
+    try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
     return astgen.addExtra(Zir.Inst.CompileErrors.Item{
         .msg = msg,
         .node = node,
src/libc_installation.zig
@@ -76,7 +76,7 @@ pub const LibCInstallation = struct {
                     if (value.len == 0) {
                         @field(self, field.name) = null;
                     } else {
-                        found_keys[i].allocated = try std.mem.dupeZ(allocator, u8, value);
+                        found_keys[i].allocated = try allocator.dupeZ(u8, value);
                         @field(self, field.name) = found_keys[i].allocated;
                     }
                     break;
@@ -213,7 +213,7 @@ pub const LibCInstallation = struct {
                 errdefer batch.wait() catch {};
                 batch.add(&async self.findNativeIncludeDirPosix(args));
                 batch.add(&async self.findNativeCrtBeginDirHaiku(args));
-                self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib");
+                self.crt_dir = try args.allocator.dupeZ(u8, "/system/develop/lib");
                 break :blk batch.wait();
             };
         } else {
@@ -222,8 +222,8 @@ pub const LibCInstallation = struct {
                 errdefer batch.wait() catch {};
                 batch.add(&async self.findNativeIncludeDirPosix(args));
                 switch (builtin.target.os.tag) {
-                    .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
-                    .solaris => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib/64"),
+                    .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try args.allocator.dupeZ(u8, "/usr/lib"),
+                    .solaris => self.crt_dir = try args.allocator.dupeZ(u8, "/usr/lib/64"),
                     .linux => batch.add(&async self.findNativeCrtDirPosix(args)),
                     else => {},
                 }
@@ -344,7 +344,7 @@ pub const LibCInstallation = struct {
 
             if (self.include_dir == null) {
                 if (search_dir.accessZ(include_dir_example_file, .{})) |_| {
-                    self.include_dir = try std.mem.dupeZ(allocator, u8, search_path);
+                    self.include_dir = try allocator.dupeZ(u8, search_path);
                 } else |err| switch (err) {
                     error.FileNotFound => {},
                     else => return error.FileSystem,
@@ -353,7 +353,7 @@ pub const LibCInstallation = struct {
 
             if (self.sys_include_dir == null) {
                 if (search_dir.accessZ(sys_include_dir_example_file, .{})) |_| {
-                    self.sys_include_dir = try std.mem.dupeZ(allocator, u8, search_path);
+                    self.sys_include_dir = try allocator.dupeZ(u8, search_path);
                 } else |err| switch (err) {
                     error.FileNotFound => {},
                     else => return error.FileSystem,
@@ -557,7 +557,7 @@ pub const LibCInstallation = struct {
     ) FindError!void {
         const allocator = args.allocator;
         const msvc_lib_dir_ptr = sdk.msvc_lib_dir_ptr orelse return error.LibCRuntimeNotFound;
-        self.msvc_lib_dir = try std.mem.dupeZ(allocator, u8, msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]);
+        self.msvc_lib_dir = try allocator.dupeZ(u8, msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]);
     }
 };
 
@@ -631,10 +631,10 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
     // So we detect failure by checking if the output matches exactly the input.
     if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound;
     switch (args.want_dirname) {
-        .full_path => return std.mem.dupeZ(allocator, u8, line),
+        .full_path => return allocator.dupeZ(u8, line),
         .only_dir => {
             const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
-            return std.mem.dupeZ(allocator, u8, dirname);
+            return allocator.dupeZ(u8, dirname);
         },
     }
 }
@@ -648,17 +648,17 @@ fn printVerboseInvocation(
     if (!verbose) return;
 
     if (search_basename) |s| {
-        std.debug.warn("Zig attempted to find the file '{s}' by executing this command:\n", .{s});
+        std.debug.print("Zig attempted to find the file '{s}' by executing this command:\n", .{s});
     } else {
-        std.debug.warn("Zig attempted to find the path to native system libc headers by executing this command:\n", .{});
+        std.debug.print("Zig attempted to find the path to native system libc headers by executing this command:\n", .{});
     }
     for (argv) |arg, i| {
-        if (i != 0) std.debug.warn(" ", .{});
-        std.debug.warn("{s}", .{arg});
+        if (i != 0) std.debug.print(" ", .{});
+        std.debug.print("{s}", .{arg});
     }
-    std.debug.warn("\n", .{});
+    std.debug.print("\n", .{});
     if (stderr) |s| {
-        std.debug.warn("Output:\n==========\n{s}\n==========\n", .{s});
+        std.debug.print("Output:\n==========\n{s}\n==========\n", .{s});
     }
 }
 
src/main.zig
@@ -1282,7 +1282,7 @@ fn buildOutputType(
                         try clang_argv.appendSlice(it.other_args);
                     },
                     .positional => {
-                        const file_ext = Compilation.classifyFileExt(mem.spanZ(it.only_arg));
+                        const file_ext = Compilation.classifyFileExt(mem.sliceTo(it.only_arg, 0));
                         switch (file_ext) {
                             .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm => try c_source_files.append(.{ .src_path = it.only_arg }),
                             .unknown, .shared_library, .object, .static_library => {
@@ -4117,7 +4117,7 @@ pub const ClangArgIterator = struct {
                     }
                 }
                 while (it.next()) |token| {
-                    const dupe_token = try mem.dupeZ(allocator, u8, token);
+                    const dupe_token = try allocator.dupeZ(u8, token);
                     errdefer allocator.free(dupe_token);
                     try resp_arg_list.append(dupe_token);
                 }
src/Module.zig
@@ -470,7 +470,7 @@ pub const Decl = struct {
     pub const DepsTable = std.AutoArrayHashMapUnmanaged(*Decl, void);
 
     pub fn clearName(decl: *Decl, gpa: *Allocator) void {
-        gpa.free(mem.spanZ(decl.name));
+        gpa.free(mem.sliceTo(decl.name, 0));
         decl.name = undefined;
     }
 
@@ -627,12 +627,12 @@ pub const Decl = struct {
     }
 
     pub fn renderFullyQualifiedName(decl: Decl, writer: anytype) !void {
-        const unqualified_name = mem.spanZ(decl.name);
+        const unqualified_name = mem.sliceTo(decl.name, 0);
         return decl.src_namespace.renderFullyQualifiedName(unqualified_name, writer);
     }
 
     pub fn renderFullyQualifiedDebugName(decl: Decl, writer: anytype) !void {
-        const unqualified_name = mem.spanZ(decl.name);
+        const unqualified_name = mem.sliceTo(decl.name, 0);
         return decl.src_namespace.renderFullyQualifiedDebugName(unqualified_name, writer);
     }
 
@@ -737,7 +737,7 @@ pub const Decl = struct {
             decl.scope.sub_file_path,
             loc.line + 1,
             loc.column + 1,
-            mem.spanZ(decl.name),
+            mem.sliceTo(decl.name, 0),
             @tagName(decl.analysis),
         });
         if (decl.has_tv) {
@@ -1342,7 +1342,7 @@ pub const Namespace = struct {
     ) @TypeOf(writer).Error!void {
         if (ns.parent) |parent| {
             const decl = ns.getDecl();
-            try parent.renderFullyQualifiedName(mem.spanZ(decl.name), writer);
+            try parent.renderFullyQualifiedName(mem.sliceTo(decl.name, 0), writer);
         } else {
             try ns.file_scope.renderFullyQualifiedName(writer);
         }
@@ -1361,7 +1361,7 @@ pub const Namespace = struct {
         var separator_char: u8 = '.';
         if (ns.parent) |parent| {
             const decl = ns.getDecl();
-            try parent.renderFullyQualifiedDebugName(mem.spanZ(decl.name), writer);
+            try parent.renderFullyQualifiedDebugName(mem.sliceTo(decl.name, 0), writer);
         } else {
             try ns.file_scope.renderFullyQualifiedDebugName(writer);
             separator_char = ':';
@@ -3432,7 +3432,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
                     return sema.fail(&block_scope, export_src, "export of inline function", .{});
                 }
                 // The scope needs to have the decl in it.
-                const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
+                const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
                 try sema.analyzeExport(&block_scope, export_src, options, decl);
             }
             return type_changed or is_inline != prev_is_inline;
@@ -3501,7 +3501,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
     if (decl.is_exported) {
         const export_src = src; // TODO point to the export token
         // The scope needs to have the decl in it.
-        const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
+        const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
         try sema.analyzeExport(&block_scope, export_src, options, decl);
     }
 
@@ -4675,7 +4675,7 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
 
             // Remove from the namespace it resides in, preserving declaration order.
             assert(decl.zir_decl_index != 0);
-            _ = decl.src_namespace.decls.orderedRemove(mem.spanZ(decl.name));
+            _ = decl.src_namespace.decls.orderedRemove(mem.sliceTo(decl.name, 0));
 
             try mod.clearDecl(decl, &outdated_decls);
             decl.destroy(mod);
src/Package.zig
@@ -115,7 +115,7 @@ pub fn deinitTable(pkg: *Package, gpa: *Allocator) void {
 
 pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {
     try pkg.table.ensureUnusedCapacity(gpa, 1);
-    const name_dupe = try mem.dupe(gpa, u8, name);
+    const name_dupe = try gpa.dupe(u8, name);
     pkg.table.putAssumeCapacityNoClobber(name_dupe, package);
 }
 
src/Sema.zig
@@ -1639,7 +1639,7 @@ fn createTypeName(sema: *Sema, block: *Block, name_strategy: Zir.Inst.NameStrate
                 block.src_decl.name, name_index,
             });
         },
-        .parent => return sema.gpa.dupeZ(u8, mem.spanZ(block.src_decl.name)),
+        .parent => return sema.gpa.dupeZ(u8, mem.sliceTo(block.src_decl.name, 0)),
         .func => {
             const name_index = sema.mod.getNextAnonNameIndex();
             const name = try std.fmt.allocPrintZ(sema.gpa, "{s}__anon_{d}", .{
src/stage1.zig
@@ -42,7 +42,7 @@ pub fn main(argc: c_int, argv: [*][*:0]u8) callconv(.C) c_int {
 
     const args = arena.alloc([]const u8, @intCast(usize, argc)) catch fatal("{s}", .{"OutOfMemory"});
     for (args) |*arg, i| {
-        arg.* = mem.spanZ(argv[i]);
+        arg.* = mem.sliceTo(argv[i], 0);
     }
     if (builtin.mode == .Debug) {
         stage2.mainArgs(gpa, arena, args) catch unreachable;
@@ -434,14 +434,14 @@ export fn stage2_add_link_lib(
         return null;
     }
     if (!target.isWasm() and !comp.bin_file.options.pic) {
-        return std.fmt.allocPrint0(
+        return std.fmt.allocPrintZ(
             comp.gpa,
             "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",
             .{ lib_name, lib_name },
         ) catch "out of memory";
     }
     comp.stage1AddLinkLib(lib_name) catch |err| {
-        return std.fmt.allocPrint0(comp.gpa, "unable to add link lib '{s}': {s}", .{
+        return std.fmt.allocPrintZ(comp.gpa, "unable to add link lib '{s}': {s}", .{
             lib_name, @errorName(err),
         }) catch "out of memory";
     };
src/translate_c.zig
@@ -335,7 +335,7 @@ pub const Context = struct {
 
     /// Convert a null-terminated C string to a slice allocated in the arena
     fn str(c: *Context, s: [*:0]const u8) ![]u8 {
-        return mem.dupe(c.arena, u8, mem.spanZ(s));
+        return c.arena.dupe(u8, mem.sliceTo(s, 0));
     }
 
     /// Convert a clang source location to a file:line:column string
@@ -2553,7 +2553,7 @@ fn transInitListExprRecord(
         var raw_name = try c.str(@ptrCast(*const clang.NamedDecl, field_decl).getName_bytes_begin());
         if (field_decl.isAnonymousStructOrUnion()) {
             const name = c.decl_table.get(@ptrToInt(field_decl.getCanonicalDecl())).?;
-            raw_name = try mem.dupe(c.arena, u8, name);
+            raw_name = try c.arena.dupe(u8, name);
         }
 
         var init_expr = try transExpr(c, scope, elem_expr, .used);
@@ -3318,7 +3318,7 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re
             const field_decl = @ptrCast(*const clang.FieldDecl, member_decl);
             if (field_decl.isAnonymousStructOrUnion()) {
                 const name = c.decl_table.get(@ptrToInt(field_decl.getCanonicalDecl())).?;
-                break :blk try mem.dupe(c.arena, u8, name);
+                break :blk try c.arena.dupe(u8, name);
             }
         }
         const decl = @ptrCast(*const clang.NamedDecl, member_decl);
src/type.zig
@@ -1179,7 +1179,7 @@ pub const Type = extern union {
                 },
                 .error_set => {
                     const error_set = ty.castTag(.error_set).?.data;
-                    return writer.writeAll(std.mem.spanZ(error_set.owner_decl.name));
+                    return writer.writeAll(std.mem.sliceTo(error_set.owner_decl.name, 0));
                 },
                 .error_set_inferred => {
                     const func = ty.castTag(.error_set_inferred).?.data.func;
src/value.zig
@@ -753,9 +753,9 @@ pub const Value = extern union {
                 const bytes = val.castTag(.bytes).?.data;
                 const adjusted_len = bytes.len - @boolToInt(ty.sentinel() != null);
                 const adjusted_bytes = bytes[0..adjusted_len];
-                return std.mem.dupe(allocator, u8, adjusted_bytes);
+                return allocator.dupe(u8, adjusted_bytes);
             },
-            .enum_literal => return std.mem.dupe(allocator, u8, val.castTag(.enum_literal).?.data),
+            .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),
             .repeated => @panic("TODO implement toAllocatedBytes for this Value tag"),
             .decl_ref => {
                 const decl = val.castTag(.decl_ref).?.data;
test/behavior/async_fn.zig
@@ -715,7 +715,7 @@ fn testAsyncAwaitTypicalUsage(
         var global_download_frame: anyframe = undefined;
         fn fetchUrl(allocator: *std.mem.Allocator, url: []const u8) anyerror![]u8 {
             _ = url;
-            const result = try std.mem.dupe(allocator, u8, "expected download text");
+            const result = try allocator.dupe(u8, "expected download text");
             errdefer allocator.free(result);
             if (suspend_download) {
                 suspend {
@@ -729,7 +729,7 @@ fn testAsyncAwaitTypicalUsage(
         var global_file_frame: anyframe = undefined;
         fn readFile(allocator: *std.mem.Allocator, filename: []const u8) anyerror![]u8 {
             _ = filename;
-            const result = try std.mem.dupe(allocator, u8, "expected file text");
+            const result = try allocator.dupe(u8, "expected file text");
             errdefer allocator.free(result);
             if (suspend_file) {
                 suspend {
test/behavior/cast_stage1.zig
@@ -171,7 +171,7 @@ fn testCastPtrOfArrayToSliceAndPtr() !void {
 test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
     const window_name = [1][*]const u8{"window name"};
     const x: [*]const ?[*]const u8 = &window_name;
-    try expect(mem.eql(u8, std.mem.spanZ(@ptrCast([*:0]const u8, x[0].?)), "window name"));
+    try expect(mem.eql(u8, std.mem.sliceTo(@ptrCast([*:0]const u8, x[0].?), 0), "window name"));
 }
 
 test "cast f16 to wider types" {
test/behavior/pointers_stage1.zig
@@ -142,7 +142,7 @@ test "null terminated pointer" {
             var zero_ptr: [*:0]const u8 = @ptrCast([*:0]const u8, &array_with_zero);
             var no_zero_ptr: [*]const u8 = zero_ptr;
             var zero_ptr_again = @ptrCast([*:0]const u8, no_zero_ptr);
-            try expect(std.mem.eql(u8, std.mem.spanZ(zero_ptr_again), "hello"));
+            try expect(std.mem.eql(u8, std.mem.sliceTo(zero_ptr_again, 0), "hello"));
         }
     };
     try S.doTheTest();
test/src/compare_output.zig
@@ -6,7 +6,6 @@ const ArrayList = std.ArrayList;
 const fmt = std.fmt;
 const mem = std.mem;
 const fs = std.fs;
-const warn = std.debug.warn;
 const Mode = std.builtin.Mode;
 
 pub const CompareOutputContext = struct {
test/src/run_translated_c.zig
@@ -6,7 +6,6 @@ const ArrayList = std.ArrayList;
 const fmt = std.fmt;
 const mem = std.mem;
 const fs = std.fs;
-const warn = std.debug.warn;
 
 pub const RunTranslatedCContext = struct {
     b: *build.Builder,
test/src/translate_c.zig
@@ -6,7 +6,6 @@ const ArrayList = std.ArrayList;
 const fmt = std.fmt;
 const mem = std.mem;
 const fs = std.fs;
-const warn = std.debug.warn;
 const CrossTarget = std.zig.CrossTarget;
 
 pub const TranslateCContext = struct {
test/cli.zig
@@ -19,11 +19,11 @@ pub fn main() !void {
     a = &arena.allocator;
 
     const zig_exe_rel = try (arg_it.next(a) orelse {
-        std.debug.warn("Expected first argument to be path to zig compiler\n", .{});
+        std.debug.print("Expected first argument to be path to zig compiler\n", .{});
         return error.InvalidArgs;
     });
     const cache_root = try (arg_it.next(a) orelse {
-        std.debug.warn("Expected second argument to be cache root directory path\n", .{});
+        std.debug.print("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});
@@ -47,11 +47,11 @@ pub fn main() !void {
 }
 
 fn printCmd(cwd: []const u8, argv: []const []const u8) void {
-    std.debug.warn("cd {s} && ", .{cwd});
+    std.debug.print("cd {s} && ", .{cwd});
     for (argv) |arg| {
-        std.debug.warn("{s} ", .{arg});
+        std.debug.print("{s} ", .{arg});
     }
-    std.debug.warn("\n", .{});
+    std.debug.print("\n", .{});
 }
 
 fn exec(cwd: []const u8, expect_0: bool, argv: []const []const u8) !ChildProcess.ExecResult {
@@ -62,23 +62,23 @@ fn exec(cwd: []const u8, expect_0: bool, argv: []const []const u8) !ChildProcess
         .cwd = cwd,
         .max_output_bytes = max_output_size,
     }) catch |err| {
-        std.debug.warn("The following command failed:\n", .{});
+        std.debug.print("The following command failed:\n", .{});
         printCmd(cwd, argv);
         return err;
     };
     switch (result.term) {
         .Exited => |code| {
             if ((code != 0) == expect_0) {
-                std.debug.warn("The following command exited with error code {}:\n", .{code});
+                std.debug.print("The following command exited with error code {}:\n", .{code});
                 printCmd(cwd, argv);
-                std.debug.warn("stderr:\n{s}\n", .{result.stderr});
+                std.debug.print("stderr:\n{s}\n", .{result.stderr});
                 return error.CommandFailed;
             }
         },
         else => {
-            std.debug.warn("The following command terminated unexpectedly:\n", .{});
+            std.debug.print("The following command terminated unexpectedly:\n", .{});
             printCmd(cwd, argv);
-            std.debug.warn("stderr:\n{s}\n", .{result.stderr});
+            std.debug.print("stderr:\n{s}\n", .{result.stderr});
             return error.CommandFailed;
         },
     }
test/tests.zig
@@ -1,7 +1,6 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const debug = std.debug;
-const warn = debug.warn;
 const build = std.build;
 const CrossTarget = std.zig.CrossTarget;
 const io = std.io;
@@ -716,7 +715,7 @@ pub const StackTracesContext = struct {
             defer args.deinit();
             args.append(full_exe_path) catch unreachable;
 
-            warn("Test {d}/{d} {s}...", .{ self.test_index + 1, self.context.test_index, self.name });
+            std.debug.print("Test {d}/{d} {s}...", .{ self.test_index + 1, self.context.test_index, self.name });
 
             const child = std.ChildProcess.init(args.items, b.allocator) catch unreachable;
             defer child.deinit();
@@ -745,7 +744,7 @@ pub const StackTracesContext = struct {
                 .Exited => |code| {
                     const expect_code: u32 = 1;
                     if (code != expect_code) {
-                        warn("Process {s} exited with error code {d} but expected code {d}\n", .{
+                        std.debug.print("Process {s} exited with error code {d} but expected code {d}\n", .{
                             full_exe_path,
                             code,
                             expect_code,
@@ -755,17 +754,17 @@ pub const StackTracesContext = struct {
                     }
                 },
                 .Signal => |signum| {
-                    warn("Process {s} terminated on signal {d}\n", .{ full_exe_path, signum });
+                    std.debug.print("Process {s} terminated on signal {d}\n", .{ full_exe_path, signum });
                     printInvocation(args.items);
                     return error.TestFailed;
                 },
                 .Stopped => |signum| {
-                    warn("Process {s} stopped on signal {d}\n", .{ full_exe_path, signum });
+                    std.debug.print("Process {s} stopped on signal {d}\n", .{ full_exe_path, signum });
                     printInvocation(args.items);
                     return error.TestFailed;
                 },
                 .Unknown => |code| {
-                    warn("Process {s} terminated unexpectedly with error code {d}\n", .{ full_exe_path, code });
+                    std.debug.print("Process {s} terminated unexpectedly with error code {d}\n", .{ full_exe_path, code });
                     printInvocation(args.items);
                     return error.TestFailed;
                 },
@@ -829,7 +828,7 @@ pub const StackTracesContext = struct {
             };
 
             if (!mem.eql(u8, self.expect_output, got)) {
-                warn(
+                std.debug.print(
                     \\
                     \\========= Expected this output: =========
                     \\{s}
@@ -839,7 +838,7 @@ pub const StackTracesContext = struct {
                 , .{ self.expect_output, got });
                 return error.TestFailed;
             }
-            warn("OK\n", .{});
+            std.debug.print("OK\n", .{});
         }
     };
 };
@@ -1003,14 +1002,14 @@ pub const GenHContext = struct {
             const self = @fieldParentPtr(GenHCmpOutputStep, "step", step);
             const b = self.context.b;
 
-            warn("Test {d}/{d} {s}...", .{ self.test_index + 1, self.context.test_index, self.name });
+            std.debug.print("Test {d}/{d} {s}...", .{ self.test_index + 1, self.context.test_index, self.name });
 
             const full_h_path = self.obj.getOutputHPath();
             const actual_h = try io.readFileAlloc(b.allocator, full_h_path);
 
             for (self.case.expected_lines.items) |expected_line| {
                 if (mem.indexOf(u8, actual_h, expected_line) == null) {
-                    warn(
+                    std.debug.print(
                         \\
                         \\========= Expected this output: ================
                         \\{s}
@@ -1021,7 +1020,7 @@ pub const GenHContext = struct {
                     return error.TestFailed;
                 }
             }
-            warn("OK\n", .{});
+            std.debug.print("OK\n", .{});
         }
     };
 
@@ -1077,7 +1076,7 @@ pub const GenHContext = struct {
 
 fn printInvocation(args: []const []const u8) void {
     for (args) |arg| {
-        warn("{s} ", .{arg});
+        std.debug.print("{s} ", .{arg});
     }
-    warn("\n", .{});
+    std.debug.print("\n", .{});
 }
tools/process_headers.zig
@@ -295,7 +295,7 @@ pub fn main() !void {
         if (std.mem.eql(u8, args[arg_i], "--help"))
             usageAndExit(args[0]);
         if (arg_i + 1 >= args.len) {
-            std.debug.warn("expected argument after '{s}'\n", .{args[arg_i]});
+            std.debug.print("expected argument after '{s}'\n", .{args[arg_i]});
             usageAndExit(args[0]);
         }
 
@@ -308,7 +308,7 @@ pub fn main() !void {
             assert(opt_abi == null);
             opt_abi = args[arg_i + 1];
         } else {
-            std.debug.warn("unrecognized argument: {s}\n", .{args[arg_i]});
+            std.debug.print("unrecognized argument: {s}\n", .{args[arg_i]});
             usageAndExit(args[0]);
         }
 
@@ -322,7 +322,7 @@ pub fn main() !void {
     else if (std.mem.eql(u8, abi_name, "glibc"))
         LibCVendor.glibc
     else {
-        std.debug.warn("unrecognized C ABI: {s}\n", .{abi_name});
+        std.debug.print("unrecognized C ABI: {s}\n", .{abi_name});
         usageAndExit(args[0]);
     };
     const generic_name = try std.fmt.allocPrint(allocator, "generic-{s}", .{abi_name});
@@ -393,7 +393,7 @@ pub fn main() !void {
                             if (gop.found_existing) {
                                 max_bytes_saved += raw_bytes.len;
                                 gop.value_ptr.hit_count += 1;
-                                std.debug.warn("duplicate: {s} {s} ({:2})\n", .{
+                                std.debug.print("duplicate: {s} {s} ({:2})\n", .{
                                     libc_target.name,
                                     rel_path,
                                     std.fmt.fmtIntSizeDec(raw_bytes.len),
@@ -415,16 +415,16 @@ pub fn main() !void {
                             };
                             try target_to_hash.putNoClobber(dest_target, hash);
                         },
-                        else => std.debug.warn("warning: weird file: {s}\n", .{full_path}),
+                        else => std.debug.print("warning: weird file: {s}\n", .{full_path}),
                     }
                 }
             }
             break;
         } else {
-            std.debug.warn("warning: libc target not found: {s}\n", .{libc_target.name});
+            std.debug.print("warning: libc target not found: {s}\n", .{libc_target.name});
         }
     }
-    std.debug.warn("summary: {:2} could be reduced to {:2}\n", .{
+    std.debug.print("summary: {:2} could be reduced to {:2}\n", .{
         std.fmt.fmtIntSizeDec(total_bytes),
         std.fmt.fmtIntSizeDec(total_bytes - max_bytes_saved),
     });
@@ -456,7 +456,7 @@ pub fn main() !void {
                 if (contender.hit_count > 1) {
                     const this_missed_bytes = contender.hit_count * contender.bytes.len;
                     missed_opportunity_bytes += this_missed_bytes;
-                    std.debug.warn("Missed opportunity ({:2}): {s}\n", .{
+                    std.debug.print("Missed opportunity ({:2}): {s}\n", .{
                         std.fmt.fmtIntSizeDec(this_missed_bytes),
                         path_kv.key_ptr.*,
                     });
@@ -486,10 +486,10 @@ pub fn main() !void {
 }
 
 fn usageAndExit(arg0: []const u8) noreturn {
-    std.debug.warn("Usage: {s} [--search-path <dir>] --out <dir> --abi <name>\n", .{arg0});
-    std.debug.warn("--search-path can be used any number of times.\n", .{});
-    std.debug.warn("    subdirectories of search paths look like, e.g. x86_64-linux-gnu\n", .{});
-    std.debug.warn("--out is a dir that will be created, and populated with the results\n", .{});
-    std.debug.warn("--abi is either musl or glibc\n", .{});
+    std.debug.print("Usage: {s} [--search-path <dir>] --out <dir> --abi <name>\n", .{arg0});
+    std.debug.print("--search-path can be used any number of times.\n", .{});
+    std.debug.print("    subdirectories of search paths look like, e.g. x86_64-linux-gnu\n", .{});
+    std.debug.print("--out is a dir that will be created, and populated with the results\n", .{});
+    std.debug.print("--abi is either musl or glibc\n", .{});
     std.process.exit(1);
 }
tools/update-linux-headers.zig
@@ -141,7 +141,7 @@ pub fn main() !void {
         if (std.mem.eql(u8, args[arg_i], "--help"))
             usageAndExit(args[0]);
         if (arg_i + 1 >= args.len) {
-            std.debug.warn("expected argument after '{s}'\n", .{args[arg_i]});
+            std.debug.print("expected argument after '{s}'\n", .{args[arg_i]});
             usageAndExit(args[0]);
         }
 
@@ -151,7 +151,7 @@ pub fn main() !void {
             assert(opt_out_dir == null);
             opt_out_dir = args[arg_i + 1];
         } else {
-            std.debug.warn("unrecognized argument: {s}\n", .{args[arg_i]});
+            std.debug.print("unrecognized argument: {s}\n", .{args[arg_i]});
             usageAndExit(args[0]);
         }
 
@@ -208,7 +208,7 @@ pub fn main() !void {
                             if (gop.found_existing) {
                                 max_bytes_saved += raw_bytes.len;
                                 gop.value_ptr.hit_count += 1;
-                                std.debug.warn("duplicate: {s} {s} ({:2})\n", .{
+                                std.debug.print("duplicate: {s} {s} ({:2})\n", .{
                                     linux_target.name,
                                     rel_path,
                                     std.fmt.fmtIntSizeDec(raw_bytes.len),
@@ -230,16 +230,16 @@ pub fn main() !void {
                             };
                             try target_to_hash.putNoClobber(dest_target, hash);
                         },
-                        else => std.debug.warn("warning: weird file: {s}\n", .{full_path}),
+                        else => std.debug.print("warning: weird file: {s}\n", .{full_path}),
                     }
                 }
             }
             break;
         } else {
-            std.debug.warn("warning: libc target not found: {s}\n", .{linux_target.name});
+            std.debug.print("warning: libc target not found: {s}\n", .{linux_target.name});
         }
     }
-    std.debug.warn("summary: {:2} could be reduced to {:2}\n", .{
+    std.debug.print("summary: {:2} could be reduced to {:2}\n", .{
         std.fmt.fmtIntSizeDec(total_bytes),
         std.fmt.fmtIntSizeDec(total_bytes - max_bytes_saved),
     });
@@ -271,7 +271,7 @@ pub fn main() !void {
                 if (contender.hit_count > 1) {
                     const this_missed_bytes = contender.hit_count * contender.bytes.len;
                     missed_opportunity_bytes += this_missed_bytes;
-                    std.debug.warn("Missed opportunity ({:2}): {s}\n", .{
+                    std.debug.print("Missed opportunity ({:2}): {s}\n", .{
                         std.fmt.fmtIntSizeDec(this_missed_bytes),
                         path_kv.key_ptr.*,
                     });
@@ -297,9 +297,9 @@ pub fn main() !void {
 }
 
 fn usageAndExit(arg0: []const u8) noreturn {
-    std.debug.warn("Usage: {s} [--search-path <dir>] --out <dir> --abi <name>\n", .{arg0});
-    std.debug.warn("--search-path can be used any number of times.\n", .{});
-    std.debug.warn("    subdirectories of search paths look like, e.g. x86_64-linux-gnu\n", .{});
-    std.debug.warn("--out is a dir that will be created, and populated with the results\n", .{});
+    std.debug.print("Usage: {s} [--search-path <dir>] --out <dir> --abi <name>\n", .{arg0});
+    std.debug.print("--search-path can be used any number of times.\n", .{});
+    std.debug.print("    subdirectories of search paths look like, e.g. x86_64-linux-gnu\n", .{});
+    std.debug.print("--out is a dir that will be created, and populated with the results\n", .{});
     std.process.exit(1);
 }
tools/update_cpu_features.zig
@@ -875,16 +875,16 @@ fn processOneTarget(job: Job) anyerror!void {
     });
     tblgen_progress.end();
     if (child_result.stderr.len != 0) {
-        std.debug.warn("{s}\n", .{child_result.stderr});
+        std.debug.print("{s}\n", .{child_result.stderr});
     }
 
     const json_text = switch (child_result.term) {
         .Exited => |code| if (code == 0) child_result.stdout else {
-            std.debug.warn("llvm-tblgen exited with code {d}\n", .{code});
+            std.debug.print("llvm-tblgen exited with code {d}\n", .{code});
             std.process.exit(1);
         },
         else => {
-            std.debug.warn("llvm-tblgen crashed\n", .{});
+            std.debug.print("llvm-tblgen crashed\n", .{});
             std.process.exit(1);
         },
     };
tools/update_glibc.zig
@@ -185,7 +185,7 @@ pub fn main() !void {
             };
             const max_bytes = 10 * 1024 * 1024;
             const contents = std.fs.cwd().readFileAlloc(allocator, abi_list_filename, max_bytes) catch |err| {
-                std.debug.warn("unable to open {s}: {}\n", .{ abi_list_filename, err });
+                std.debug.print("unable to open {s}: {}\n", .{ abi_list_filename, err });
                 std.process.exit(1);
             };
             var lines_it = std.mem.tokenize(u8, contents, "\n");
build.zig
@@ -3,7 +3,6 @@ const builtin = std.builtin;
 const Builder = std.build.Builder;
 const tests = @import("test/tests.zig");
 const BufMap = std.BufMap;
-const warn = std.debug.warn;
 const mem = std.mem;
 const ArrayList = std.ArrayList;
 const io = std.io;
@@ -558,9 +557,9 @@ fn addCxxKnownPath(
     const path_unpadded = mem.tokenize(u8, path_padded, "\r\n").next().?;
     if (mem.eql(u8, path_unpadded, objname)) {
         if (errtxt) |msg| {
-            warn("{s}", .{msg});
+            std.debug.print("{s}", .{msg});
         } else {
-            warn("Unable to determine path to {s}\n", .{objname});
+            std.debug.print("Unable to determine path to {s}\n", .{objname});
         }
         return error.RequiredLibraryNotFound;
     }
@@ -687,7 +686,7 @@ fn findAndParseConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?CMakeCon
 }
 
 fn toNativePathSep(b: *Builder, s: []const u8) []u8 {
-    const duplicated = mem.dupe(b.allocator, u8, s) catch unreachable;
+    const duplicated = b.allocator.dupe(u8, s) catch unreachable;
     for (duplicated) |*byte| switch (byte.*) {
         '/' => byte.* = fs.path.sep,
         else => {},
CMakeLists.txt
@@ -534,7 +534,7 @@ set(ZIG_STAGE2_SOURCES
     "${CMAKE_SOURCE_DIR}/lib/std/unicode.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"
-    "${CMAKE_SOURCE_DIR}/lib/std/zig/cross_target.zig"
+    "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/zig/parse.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
     "${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig"