Commit 2b42e910bf

Andrew Kelley <andrew@ziglang.org>
2019-05-27 01:56:37
behavior tests passing on Linux
1 parent 44a049e
std/io/c_out_stream.zig
@@ -37,7 +37,7 @@ pub const COutStream = struct {
             os.ENOSPC => return error.NoSpaceLeft,
             os.EPERM => return error.AccessDenied,
             os.EPIPE => return error.BrokenPipe,
-            else => return os.unexpectedErrno(@intCast(usize, errno)),
+            else => |err| return os.unexpectedErrno(@intCast(usize, err)),
         }
     }
 };
std/os/bits/linux.zig
@@ -1,4 +1,5 @@
 const std = @import("../../std.zig");
+const maxInt = std.math.maxInt;
 
 pub use @import("linux/errno.zig");
 pub use switch (builtin.arch) {
@@ -39,7 +40,7 @@ pub const PROT_EXEC = 4;
 pub const PROT_GROWSDOWN = 0x01000000;
 pub const PROT_GROWSUP = 0x02000000;
 
-pub const MAP_FAILED = maxInt(usize);
+pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
 pub const MAP_SHARED = 0x01;
 pub const MAP_PRIVATE = 0x02;
 pub const MAP_TYPE = 0x0f;
std/os/linux/tls.zig
@@ -237,7 +237,7 @@ pub fn allocateTLS(size: usize) usize {
         return @ptrToInt(&main_thread_tls_buffer);
     }
 
-    const addr = os.mmap(
+    const slice = os.mmap(
         null,
         size,
         os.PROT_READ | os.PROT_WRITE,
@@ -246,5 +246,5 @@ pub fn allocateTLS(size: usize) usize {
         0,
     ) catch @panic("out of memory");
 
-    return addr;
+    return @ptrToInt(slice.ptr);
 }
std/os/linux.zig
@@ -173,12 +173,12 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
     return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @bitCast(usize, isize(fd)), @bitCast(usize, offset));
 }
 
-pub fn mprotect(address: usize, length: usize, protection: usize) usize {
-    return syscall3(SYS_mprotect, address, length, protection);
+pub fn mprotect(address: [*]const u8, length: usize, protection: usize) usize {
+    return syscall3(SYS_mprotect, @ptrToInt(address), length, protection);
 }
 
-pub fn munmap(address: usize, length: usize) usize {
-    return syscall2(SYS_munmap, address, length);
+pub fn munmap(address: [*]const u8, length: usize) usize {
+    return syscall2(SYS_munmap, @ptrToInt(address), length);
 }
 
 pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
std/c.zig
@@ -1,4 +1,6 @@
 const builtin = @import("builtin");
+const std = @import("std");
+const page_size = std.mem.page_size;
 
 pub use @import("os/bits.zig");
 
@@ -33,7 +35,7 @@ pub extern "c" fn close(fd: fd_t) c_int;
 pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
 pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;
 pub extern "c" fn lseek(fd: fd_t, offset: isize, whence: c_int) isize;
-pub extern "c" fn open(path: [*]const u8, oflag: c_int, ...) c_int;
+pub extern "c" fn open(path: [*]const u8, oflag: c_uint, ...) c_int;
 pub extern "c" fn raise(sig: c_int) c_int;
 pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
 pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;
@@ -42,8 +44,9 @@ pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec, iovcnt: c_int, offset:
 pub extern "c" fn stat(noalias path: [*]const u8, noalias buf: *Stat) c_int;
 pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;
 pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;
-pub extern "c" fn mmap(addr: ?*c_void, len: usize, prot: c_int, flags: c_int, fd: fd_t, offset: isize) usize;
-pub extern "c" fn munmap(addr: ?*c_void, len: usize) c_int;
+pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: isize) *c_void;
+pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;
+pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
 pub extern "c" fn unlink(path: [*]const u8) c_int;
 pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
 pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_int, options: c_int) c_int;
std/debug.zig
@@ -1011,7 +1011,7 @@ fn openSelfDebugInfoPosix(allocator: *mem.Allocator) !DwarfInfo {
     S.self_exe_file = try fs.openSelfExe();
     errdefer S.self_exe_file.close();
 
-    const self_exe_mmap_len = try S.self_exe_file.getEndPos();
+    const self_exe_mmap_len = mem.alignForward(try S.self_exe_file.getEndPos(), mem.page_size);
     const self_exe_mmap = try os.mmap(
         null,
         self_exe_mmap_len,
@@ -1020,10 +1020,9 @@ fn openSelfDebugInfoPosix(allocator: *mem.Allocator) !DwarfInfo {
         S.self_exe_file.handle,
         0,
     );
-    errdefer os.munmap(self_exe_mmap, self_exe_mmap_len);
+    errdefer os.munmap(self_exe_mmap);
 
-    const file_mmap_slice = @intToPtr([*]const u8, self_exe_mmap)[0..self_exe_mmap_len];
-    S.self_exe_mmap_seekable = io.SliceSeekableInStream.init(file_mmap_slice);
+    S.self_exe_mmap_seekable = io.SliceSeekableInStream.init(self_exe_mmap);
 
     return openElfDebugInfo(
         allocator,
std/fs.zig
@@ -595,8 +595,8 @@ pub const Dir = struct {
                 }
 
                 while (true) {
-                    const rc = os.system.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len);
-                    switch (os.errno(rc)) {
+                    const rc = os.linux.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len);
+                    switch (os.linux.getErrno(rc)) {
                         0 => {},
                         os.EBADF => unreachable,
                         os.EFAULT => unreachable,
std/heap.zig
@@ -104,35 +104,36 @@ pub const DirectAllocator = struct {
         }
 
         const alloc_size = if (alignment <= mem.page_size) n else n + alignment;
-        const addr = os.mmap(
+        const slice = os.mmap(
             null,
-            alloc_size,
+            mem.alignForward(alloc_size, mem.page_size),
             os.PROT_READ | os.PROT_WRITE,
             os.MAP_PRIVATE | os.MAP_ANONYMOUS,
             -1,
             0,
         ) catch return error.OutOfMemory;
-        if (alloc_size == n) return @intToPtr([*]u8, addr)[0..n];
+        if (alloc_size == n) return slice;
 
-        const aligned_addr = mem.alignForward(addr, alignment);
+        const aligned_addr = mem.alignForward(@ptrToInt(slice.ptr), alignment);
 
         // Unmap the extra bytes that were only requested in order to guarantee
         // that the range of memory we were provided had a proper alignment in
         // it somewhere. The extra bytes could be at the beginning, or end, or both.
-        const unused_start_len = aligned_addr - addr;
+        const unused_start_len = aligned_addr - @ptrToInt(slice.ptr);
         if (unused_start_len != 0) {
-            os.munmap(addr, unused_start_len);
+            os.munmap(slice[0..unused_start_len]);
         }
-        const aligned_end_addr = std.mem.alignForward(aligned_addr + n, mem.page_size);
-        const unused_end_len = addr + alloc_size - aligned_end_addr;
+        const aligned_end_addr = mem.alignForward(aligned_addr + n, mem.page_size);
+        const unused_end_len = @ptrToInt(slice.ptr) + slice.len - aligned_end_addr;
         if (unused_end_len != 0) {
-            os.munmap(aligned_end_addr, unused_end_len);
+            os.munmap(@intToPtr([*]align(mem.page_size) u8, aligned_end_addr)[0..unused_end_len]);
         }
 
         return @intToPtr([*]u8, aligned_addr)[0..n];
     }
 
-    fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
+    fn shrink(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
+        const old_mem = @alignCast(mem.page_size, old_mem_unaligned);
         if (os.windows.is_the_target) {
             const w = os.windows;
             if (new_size == 0) {
@@ -165,12 +166,14 @@ pub const DirectAllocator = struct {
         const new_addr_end = base_addr + new_size;
         const new_addr_end_rounded = mem.alignForward(new_addr_end, mem.page_size);
         if (old_addr_end > new_addr_end_rounded) {
-            os.munmap(new_addr_end_rounded, old_addr_end - new_addr_end_rounded);
+            const ptr = @intToPtr([*]align(mem.page_size) u8, new_addr_end_rounded);
+            os.munmap(ptr[0 .. old_addr_end - new_addr_end_rounded]);
         }
         return old_mem[0..new_size];
     }
 
-    fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
+    fn realloc(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
+        const old_mem = @alignCast(mem.page_size, old_mem_unaligned);
         if (os.windows.is_the_target) {
             if (old_mem.len == 0) {
                 return alloc(allocator, new_size, new_align);
@@ -231,7 +234,7 @@ pub const DirectAllocator = struct {
         const result = try alloc(allocator, new_size, new_align);
         if (old_mem.len != 0) {
             @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
-            os.munmap(@ptrToInt(old_mem.ptr), old_mem.len);
+            os.munmap(old_mem);
         }
         return result;
     }
std/io.zig
@@ -1,12 +1,12 @@
 const std = @import("std.zig");
 const builtin = @import("builtin");
-const Os = builtin.Os;
 const c = std.c;
 
 const math = std.math;
 const debug = std.debug;
 const assert = debug.assert;
 const os = std.os;
+const fs = std.fs;
 const mem = std.mem;
 const meta = std.meta;
 const trait = meta.trait;
@@ -985,7 +985,7 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type {
 }
 
 pub const BufferedAtomicFile = struct {
-    atomic_file: os.AtomicFile,
+    atomic_file: fs.AtomicFile,
     file_stream: File.OutStream,
     buffered_stream: BufferedOutStream(File.WriteError),
     allocator: *mem.Allocator,
@@ -1001,7 +1001,7 @@ pub const BufferedAtomicFile = struct {
         };
         errdefer allocator.destroy(self);
 
-        self.atomic_file = try os.AtomicFile.init(dest_path, File.default_mode);
+        self.atomic_file = try fs.AtomicFile.init(dest_path, File.default_mode);
         errdefer self.atomic_file.deinit();
 
         self.file_stream = self.atomic_file.file.outStream();
std/mem.zig
@@ -585,14 +585,14 @@ pub fn readIntSlice(comptime T: type, bytes: []const u8, endian: builtin.Endian)
 test "comptime read/write int" {
     comptime {
         var bytes: [2]u8 = undefined;
-        std.mem.writeIntLittle(u16, &bytes, 0x1234);
-        const result = std.mem.readIntBig(u16, &bytes);
+        writeIntLittle(u16, &bytes, 0x1234);
+        const result = readIntBig(u16, &bytes);
         testing.expect(result == 0x3412);
     }
     comptime {
         var bytes: [2]u8 = undefined;
-        std.mem.writeIntBig(u16, &bytes, 0x1234);
-        const result = std.mem.readIntLittle(u16, &bytes);
+        writeIntBig(u16, &bytes, 0x1234);
+        const result = readIntLittle(u16, &bytes);
         testing.expect(result == 0x3412);
     }
 }
@@ -1053,7 +1053,7 @@ fn testReadIntImpl() void {
     }
 }
 
-test "std.mem.writeIntSlice" {
+test "writeIntSlice" {
     testWriteIntImpl();
     comptime testWriteIntImpl();
 }
@@ -1184,7 +1184,7 @@ pub fn reverse(comptime T: type, items: []T) void {
     }
 }
 
-test "std.mem.reverse" {
+test "reverse" {
     var arr = []i32{
         5,
         3,
@@ -1211,7 +1211,7 @@ pub fn rotate(comptime T: type, items: []T, amount: usize) void {
     reverse(T, items);
 }
 
-test "std.mem.rotate" {
+test "rotate" {
     var arr = []i32{
         5,
         3,
@@ -1296,14 +1296,14 @@ pub fn asBytes(ptr: var) AsBytesReturnType(@typeOf(ptr)) {
     return @ptrCast(AsBytesReturnType(P), ptr);
 }
 
-test "std.mem.asBytes" {
+test "asBytes" {
     const deadbeef = u32(0xDEADBEEF);
     const deadbeef_bytes = switch (builtin.endian) {
         builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
         builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
     };
 
-    testing.expect(std.mem.eql(u8, asBytes(&deadbeef), deadbeef_bytes));
+    testing.expect(eql(u8, asBytes(&deadbeef), deadbeef_bytes));
 
     var codeface = u32(0xC0DEFACE);
     for (asBytes(&codeface).*) |*b|
@@ -1323,7 +1323,7 @@ test "std.mem.asBytes" {
         .c = 0xDE,
         .d = 0xA1,
     };
-    testing.expect(std.mem.eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));
+    testing.expect(eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));
 }
 
 ///Given any value, returns a copy of its bytes in an array.
@@ -1331,17 +1331,17 @@ pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 {
     return asBytes(&value).*;
 }
 
-test "std.mem.toBytes" {
+test "toBytes" {
     var my_bytes = toBytes(u32(0x12345678));
     switch (builtin.endian) {
-        builtin.Endian.Big => testing.expect(std.mem.eql(u8, my_bytes, "\x12\x34\x56\x78")),
-        builtin.Endian.Little => testing.expect(std.mem.eql(u8, my_bytes, "\x78\x56\x34\x12")),
+        builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x12\x34\x56\x78")),
+        builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x78\x56\x34\x12")),
     }
 
     my_bytes[0] = '\x99';
     switch (builtin.endian) {
-        builtin.Endian.Big => testing.expect(std.mem.eql(u8, my_bytes, "\x99\x34\x56\x78")),
-        builtin.Endian.Little => testing.expect(std.mem.eql(u8, my_bytes, "\x99\x56\x34\x12")),
+        builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x99\x34\x56\x78")),
+        builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x99\x56\x34\x12")),
     }
 }
 
@@ -1363,7 +1363,7 @@ pub fn bytesAsValue(comptime T: type, bytes: var) BytesAsValueReturnType(T, @typ
     return @ptrCast(BytesAsValueReturnType(T, @typeOf(bytes)), bytes);
 }
 
-test "std.mem.bytesAsValue" {
+test "bytesAsValue" {
     const deadbeef = u32(0xDEADBEEF);
     const deadbeef_bytes = switch (builtin.endian) {
         builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
@@ -1405,7 +1405,7 @@ test "std.mem.bytesAsValue" {
 pub fn bytesToValue(comptime T: type, bytes: var) T {
     return bytesAsValue(T, &bytes).*;
 }
-test "std.mem.bytesToValue" {
+test "bytesToValue" {
     const deadbeef_bytes = switch (builtin.endian) {
         builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
         builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
@@ -1430,25 +1430,25 @@ pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubA
     return @ptrCast(ReturnType, &ptr[start]);
 }
 
-test "std.mem.subArrayPtr" {
+test "subArrayPtr" {
     const a1 = "abcdef";
     const sub1 = subArrayPtr(&a1, 2, 3);
-    testing.expect(std.mem.eql(u8, sub1.*, "cde"));
+    testing.expect(eql(u8, sub1.*, "cde"));
 
     var a2 = "abcdef";
     var sub2 = subArrayPtr(&a2, 2, 3);
 
-    testing.expect(std.mem.eql(u8, sub2, "cde"));
+    testing.expect(eql(u8, sub2, "cde"));
     sub2[1] = 'X';
-    testing.expect(std.mem.eql(u8, a2, "abcXef"));
+    testing.expect(eql(u8, a2, "abcXef"));
 }
 
 /// Round an address up to the nearest aligned address
 pub fn alignForward(addr: usize, alignment: usize) usize {
-    return (addr + alignment - 1) & ~(alignment - 1);
+    return alignBackward(addr + (alignment - 1), alignment);
 }
 
-test "std.mem.alignForward" {
+test "alignForward" {
     testing.expect(alignForward(1, 1) == 1);
     testing.expect(alignForward(2, 1) == 2);
     testing.expect(alignForward(1, 2) == 2);
@@ -1462,3 +1462,30 @@ test "std.mem.alignForward" {
     testing.expect(alignForward(16, 8) == 16);
     testing.expect(alignForward(17, 8) == 24);
 }
+
+pub fn alignBackward(addr: usize, alignment: usize) usize {
+    // 000010000 // example addr
+    // 000001111 // subtract 1
+    // 111110000 // binary not
+    return addr & ~(alignment - 1);
+}
+
+pub fn isAligned(addr: usize, alignment: usize) bool {
+    return alignBackward(addr, alignment) == addr;
+}
+
+test "isAligned" {
+    testing.expect(isAligned(0, 4));
+    testing.expect(isAligned(1, 1));
+    testing.expect(isAligned(2, 1));
+    testing.expect(isAligned(2, 2));
+    testing.expect(!isAligned(2, 4));
+    testing.expect(isAligned(3, 1));
+    testing.expect(!isAligned(3, 2));
+    testing.expect(!isAligned(3, 4));
+    testing.expect(isAligned(4, 4));
+    testing.expect(isAligned(4, 2));
+    testing.expect(isAligned(4, 1));
+    testing.expect(!isAligned(4, 8));
+    testing.expect(!isAligned(4, 16));
+}
std/os.zig
@@ -251,7 +251,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
     // Linux can return EINVAL when read amount is > 0x7ffff000
     // See https://github.com/ziglang/zig/pull/743#issuecomment-363158274
     // TODO audit this. Shawn Landden says that this is not actually true.
-    // if this logic should stay, move it to std.os.linux.sys
+    // if this logic should stay, move it to std.os.linux
     const max_buf_len = 0x7ffff000;
 
     var index: usize = 0;
@@ -260,8 +260,9 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
         const rc = system.read(fd, buf.ptr + index, want_to_read);
         switch (errno(rc)) {
             0 => {
-                index += rc;
-                if (rc == want_to_read) continue;
+                const amt_read = @intCast(usize, rc);
+                index += amt_read;
+                if (amt_read == want_to_read) continue;
                 // Read returned less than buf.len.
                 return index;
             },
@@ -374,7 +375,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
     // Linux can return EINVAL when write amount is > 0x7ffff000
     // See https://github.com/ziglang/zig/pull/743#issuecomment-363165856
     // TODO audit this. Shawn Landden says that this is not actually true.
-    // if this logic should stay, move it to std.os.linux.sys
+    // if this logic should stay, move it to std.os.linux
     const max_bytes_len = 0x7ffff000;
 
     var index: usize = 0;
@@ -383,7 +384,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
         const rc = system.write(fd, bytes.ptr + index, amt_to_write);
         switch (errno(rc)) {
             0 => {
-                index += rc;
+                index += @intCast(usize, rc);
                 continue;
             },
             EINTR => continue,
@@ -1863,14 +1864,10 @@ pub const MProtectError = error{
     Unexpected,
 };
 
-/// address and length must be page-aligned
-pub fn mprotect(address: usize, length: usize, protection: u32) MProtectError!void {
-    const negative_page_size = @bitCast(usize, -isize(mem.page_size));
-    const aligned_address = address & negative_page_size;
-    const aligned_end = (address + length + mem.page_size - 1) & negative_page_size;
-    assert(address == aligned_address);
-    assert(length == aligned_end - aligned_address);
-    switch (errno(system.mprotect(address, length, protection))) {
+/// `memory.len` must be page-aligned.
+pub fn mprotect(memory: [*]align(mem.page_size) u8, protection: u32) MProtectError!void {
+    assert(mem.isAligned(memory.len, mem.page_size));
+    switch (errno(system.mprotect(memory.ptr, memory.len, protection))) {
         0 => return,
         EINVAL => unreachable,
         EACCES => return error.AccessDenied,
@@ -1906,17 +1903,26 @@ pub const MMapError = error{
 
 /// Map files or devices into memory.
 /// Use of a mapped region can result in these signals:
+/// `length` must be page-aligned.
 /// * SIGSEGV - Attempted write into a region mapped as read-only.
 /// * SIGBUS - Attempted  access to a portion of the buffer that does not correspond to the file
-pub fn mmap(address: ?[*]u8, length: usize, prot: u32, flags: u32, fd: fd_t, offset: isize) MMapError!usize {
+pub fn mmap(
+    ptr: ?[*]align(mem.page_size) u8,
+    length: usize,
+    prot: u32,
+    flags: u32,
+    fd: fd_t,
+    offset: isize,
+) MMapError![]align(mem.page_size) u8 {
+    assert(mem.isAligned(length, mem.page_size));
     const err = if (builtin.link_libc) blk: {
-        const rc = system.mmap(address, length, prot, flags, fd, offset);
-        if (rc != system.MMAP_FAILED) return rc;
-        break :blk system._errno().*;
+        const rc = std.c.mmap(ptr, length, prot, flags, fd, offset);
+        if (rc != MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];
+        break :blk @intCast(usize, system._errno().*);
     } else blk: {
-        const rc = system.mmap(address, length, prot, flags, fd, offset);
+        const rc = system.mmap(ptr, length, prot, flags, fd, offset);
         const err = errno(rc);
-        if (err == 0) return rc;
+        if (err == 0) return @intToPtr([*]align(mem.page_size) u8, rc)[0..length];
         break :blk err;
     };
     switch (err) {
@@ -1940,8 +1946,8 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: u32, flags: u32, fd: fd_t, off
 /// Zig's munmap function does not, for two reasons:
 /// * It violates the Zig principle that resource deallocation must succeed.
 /// * The Windows function, VirtualFree, has this restriction.
-pub fn munmap(address: usize, length: usize) void {
-    switch (errno(system.munmap(address, length))) {
+pub fn munmap(memory: []align(mem.page_size) u8) void {
+    switch (errno(system.munmap(memory.ptr, memory.len))) {
         0 => return,
         EINVAL => unreachable, // Invalid parameters.
         ENOMEM => unreachable, // Attempted to unmap a region in the middle of an existing mapping.
test/stage1/behavior/cast.zig
@@ -318,7 +318,7 @@ fn testCastPtrOfArrayToSliceAndPtr() void {
 test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
     const window_name = [1][*]const u8{c"window name"};
     const x: [*]const ?[*]const u8 = &window_name;
-    expect(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name"));
+    expect(mem.eql(u8, std.mem.toSliceConst(u8, x[0].?), "window name"));
 }
 
 test "@intCast comptime_int" {
test/stage1/behavior/misc.zig
@@ -2,7 +2,6 @@ const std = @import("std");
 const expect = std.testing.expect;
 const expectEqualSlices = std.testing.expectEqualSlices;
 const mem = std.mem;
-const cstr = std.cstr;
 const builtin = @import("builtin");
 const maxInt = std.math.maxInt;
 
@@ -210,7 +209,7 @@ test "multiline C string" {
         c\\three
     ;
     const s2 = c"one\ntwo)\nthree";
-    expect(cstr.cmp(s1, s2) == 0);
+    expect(std.cstr.cmp(s1, s2) == 0);
 }
 
 test "type equality" {
@@ -363,7 +362,7 @@ test "C string concatenation" {
     const a = c"OK" ++ c" IT " ++ c"WORKED";
     const b = c"OK IT WORKED";
 
-    const len = cstr.len(b);
+    const len = mem.len(u8, b);
     const len_with_null = len + 1;
     {
         var i: u32 = 0;