From 0b0de22fd1b0391f0cf1c7d821afc6522041c699 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Fri, 27 Dec 2019 14:31:20 +1100 Subject: [PATCH 1/4] std: format contents of sentinel terminated many pointers std: add std.meta.Sentinel to get sentinel of a type --- lib/std/cstr.zig | 2 +- lib/std/fmt.zig | 8 ++++++-- lib/std/mem.zig | 23 ++++++++++++++++++----- lib/std/meta.zig | 26 ++++++++++++++++++++++++++ src-self-hosted/main.zig | 14 +++++++------- test/stage1/behavior/misc.zig | 2 +- 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/lib/std/cstr.zig b/lib/std/cstr.zig index 4057d4b62b..6b2407cb7d 100644 --- a/lib/std/cstr.zig +++ b/lib/std/cstr.zig @@ -28,7 +28,7 @@ test "cstr fns" { fn testCStrFnsImpl() void { testing.expect(cmp("aoeu", "aoez") == -1); - testing.expect(mem.len(u8, "123456789") == 9); + testing.expect(mem.len(u8, "123456789".*) == 9); } /// Returns a mutable, null-terminated slice with the same length as `slice`. diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index d093101646..97f2133d67 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -441,10 +441,14 @@ pub fn formatType( else => return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }), }, .Many, .C => { + if (ptr_info.sentinel) |sentinel| { + const slice = mem.pointerToSlice([:sentinel]const ptr_info.child, value); + return formatType(slice, fmt, options, context, Errors, output, max_depth); + } if (ptr_info.child == u8) { if (fmt.len > 0 and fmt[0] == 's') { - const len = mem.len(u8, value); - return formatText(value[0..len], fmt, options, context, Errors, output); + const slice = mem.pointerToSlice([:0]const u8, @as([*:0]const u8, value)); + return formatText(slice, fmt, options, context, Errors, output); } } return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }); diff --git a/lib/std/mem.zig b/lib/std/mem.zig index a4b48bbc1c..e6ef7d6752 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -470,18 +470,31 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { return true; } -pub fn len(comptime T: type, ptr: [*:0]const T) usize { +pub fn len(comptime T: type, ptr: var) usize { + const sentinel: T = comptime meta.Sentinel(@TypeOf(ptr)); var count: usize = 0; - while (ptr[count] != 0) : (count += 1) {} + while (ptr[count] != sentinel) : (count += 1) {} return count; } -pub fn toSliceConst(comptime T: type, ptr: [*:0]const T) [:0]const T { - return ptr[0..len(T, ptr) :0]; +/// Given a sentintel-terminated pointer-to-many, find the sentintel and return a slice. +pub fn pointerToSlice(comptime T: type, ptr: blk: { + var info = @typeInfo(T).Pointer; + info.size = .Many; + break :blk @Type(std.builtin.TypeInfo{ .Pointer = info }); +}) T { + const sentinel = comptime meta.Sentinel(T); + return ptr[0..len(meta.Child(T), ptr) :sentinel]; } +/// Deprecated; use pointerToSlice instead +pub fn toSliceConst(comptime T: type, ptr: [*:0]const T) [:0]const T { + return pointerToSlice([:0]const T, ptr); +} + +/// Deprecated; use pointerToSlice instead pub fn toSlice(comptime T: type, ptr: [*:0]T) [:0]T { - return ptr[0..len(T, ptr) :0]; + return pointerToSlice([:0]T, ptr); } /// Returns true if all elements in a slice are equal to the scalar value provided diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 58fd6b9da7..65809abb5c 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -115,6 +115,32 @@ test "std.meta.Child" { testing.expect(Child(?u8) == u8); } +/// Given a type with a sentinel e.g. `[:0]u8`, returns the sentinel +pub fn Sentinel(comptime T: type) Child(T) { + // comptime asserts that ptr has a sentinel + switch (@typeInfo(T)) { + .Array => |arrayInfo| { + return comptime arrayInfo.sentinel.?; + }, + .Pointer => |ptrInfo| { + switch (ptrInfo.size) { + .Many, .Slice => { + return comptime ptrInfo.sentinel.?; + }, + else => {}, + } + }, + else => {}, + } + @compileError("not a sentinel type, found '" ++ @typeName(T) ++ "'"); +} + +test "std.meta.Sentinel" { + testing.expectEqual(@as(u8, 0), Sentinel([:0]u8)); + testing.expectEqual(@as(u8, 0), Sentinel([*:0]u8)); + testing.expectEqual(@as(u8, 0), Sentinel([5:0]u8)); +} + pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout { return switch (@typeInfo(T)) { .Struct => |info| info.layout, diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 264a896f46..4446a974d4 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -792,7 +792,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro } fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void { - try stdout.print("{}\n", .{std.mem.toSliceConst(u8, c.ZIG_VERSION_STRING)}); + try stdout.print("{}\n", .{c.ZIG_VERSION_STRING}); } fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void { @@ -863,12 +863,12 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void { \\ZIG_DIA_GUIDS_LIB {} \\ , .{ - std.mem.toSliceConst(u8, c.ZIG_CMAKE_BINARY_DIR), - std.mem.toSliceConst(u8, c.ZIG_CXX_COMPILER), - std.mem.toSliceConst(u8, c.ZIG_LLD_INCLUDE_PATH), - std.mem.toSliceConst(u8, c.ZIG_LLD_LIBRARIES), - std.mem.toSliceConst(u8, c.ZIG_LLVM_CONFIG_EXE), - std.mem.toSliceConst(u8, c.ZIG_DIA_GUIDS_LIB), + c.ZIG_CMAKE_BINARY_DIR, + c.ZIG_CXX_COMPILER, + c.ZIG_LLD_INCLUDE_PATH, + c.ZIG_LLD_LIBRARIES, + c.ZIG_LLVM_CONFIG_EXE, + c.ZIG_DIA_GUIDS_LIB, }); } diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index 681f5be500..e2513c3f4a 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -335,7 +335,7 @@ test "string concatenation" { comptime expect(@TypeOf(a) == *const [12:0]u8); comptime expect(@TypeOf(b) == *const [12:0]u8); - const len = mem.len(u8, b); + const len = b.len; const len_with_null = len + 1; { var i: u32 = 0; From 4505857e30233d87f9ece403458c0988e8c68493 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Mar 2020 13:07:31 -0500 Subject: [PATCH 2/4] revert changes outside std.fmt --- lib/std/cstr.zig | 2 +- lib/std/mem.zig | 21 ++++----------------- test/stage1/behavior/misc.zig | 2 +- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/lib/std/cstr.zig b/lib/std/cstr.zig index 6b2407cb7d..4057d4b62b 100644 --- a/lib/std/cstr.zig +++ b/lib/std/cstr.zig @@ -28,7 +28,7 @@ test "cstr fns" { fn testCStrFnsImpl() void { testing.expect(cmp("aoeu", "aoez") == -1); - testing.expect(mem.len(u8, "123456789".*) == 9); + testing.expect(mem.len(u8, "123456789") == 9); } /// Returns a mutable, null-terminated slice with the same length as `slice`. diff --git a/lib/std/mem.zig b/lib/std/mem.zig index e6ef7d6752..a4b48bbc1c 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -470,31 +470,18 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { return true; } -pub fn len(comptime T: type, ptr: var) usize { - const sentinel: T = comptime meta.Sentinel(@TypeOf(ptr)); +pub fn len(comptime T: type, ptr: [*:0]const T) usize { var count: usize = 0; - while (ptr[count] != sentinel) : (count += 1) {} + while (ptr[count] != 0) : (count += 1) {} return count; } -/// Given a sentintel-terminated pointer-to-many, find the sentintel and return a slice. -pub fn pointerToSlice(comptime T: type, ptr: blk: { - var info = @typeInfo(T).Pointer; - info.size = .Many; - break :blk @Type(std.builtin.TypeInfo{ .Pointer = info }); -}) T { - const sentinel = comptime meta.Sentinel(T); - return ptr[0..len(meta.Child(T), ptr) :sentinel]; -} - -/// Deprecated; use pointerToSlice instead pub fn toSliceConst(comptime T: type, ptr: [*:0]const T) [:0]const T { - return pointerToSlice([:0]const T, ptr); + return ptr[0..len(T, ptr) :0]; } -/// Deprecated; use pointerToSlice instead pub fn toSlice(comptime T: type, ptr: [*:0]T) [:0]T { - return pointerToSlice([:0]T, ptr); + return ptr[0..len(T, ptr) :0]; } /// Returns true if all elements in a slice are equal to the scalar value provided diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index e2513c3f4a..681f5be500 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -335,7 +335,7 @@ test "string concatenation" { comptime expect(@TypeOf(a) == *const [12:0]u8); comptime expect(@TypeOf(b) == *const [12:0]u8); - const len = b.len; + const len = mem.len(u8, b); const len_with_null = len + 1; { var i: u32 = 0; From 5b26128bacddf594dfe45958a236bfa2459f878b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Mar 2020 13:07:55 -0500 Subject: [PATCH 3/4] add new functions to std.mem and deprecate others add std.mem.Span add std.mem.span add std.mem.length add std.mem.indexOfSentinel deprecate std.mem.len deprecate std.mem.toSlice deprecate std.mem.toSliceConst --- lib/std/builtin.zig | 2 + lib/std/mem.zig | 118 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index de37fda903..a4f0ef269f 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -185,6 +185,7 @@ pub const TypeInfo = union(enum) { child: type, is_allowzero: bool, + /// This field is an optional type. /// The type of the sentinel is the element type of the pointer, which is /// the value of the `child` field in this struct. However there is no way /// to refer to that type here, so we use `var`. @@ -206,6 +207,7 @@ pub const TypeInfo = union(enum) { len: comptime_int, child: type, + /// This field is an optional type. /// The type of the sentinel is the element type of the array, which is /// the value of the `child` field in this struct. However there is no way /// to refer to that type here, so we use `var`. diff --git a/lib/std/mem.zig b/lib/std/mem.zig index a4b48bbc1c..775e999e0b 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -333,8 +333,20 @@ pub fn zeroes(comptime T: type) T { } return array; }, - .Vector, .ErrorUnion, .ErrorSet, .Union, .Fn, .BoundFn, .Type, .NoReturn, .Undefined, .Opaque, .Frame, .AnyFrame, => { - @compileError("Can't set a "++ @typeName(T) ++" to zero."); + .Vector, + .ErrorUnion, + .ErrorSet, + .Union, + .Fn, + .BoundFn, + .Type, + .NoReturn, + .Undefined, + .Opaque, + .Frame, + .AnyFrame, + => { + @compileError("Can't set a " ++ @typeName(T) ++ " to zero."); }, } } @@ -470,20 +482,122 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { return true; } +/// Deprecated. Use `length` or `indexOfSentinel`. pub fn len(comptime T: type, ptr: [*:0]const T) usize { var count: usize = 0; while (ptr[count] != 0) : (count += 1) {} return count; } +/// Deprecated. Use `span`. pub fn toSliceConst(comptime T: type, ptr: [*:0]const T) [:0]const T { return ptr[0..len(T, ptr) :0]; } +/// Deprecated. Use `span`. pub fn toSlice(comptime T: type, ptr: [*:0]T) [:0]T { return ptr[0..len(T, ptr) :0]; } +/// 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 +/// the constness of the input type. `[*c]` pointers are assumed to be 0-terminated. +pub fn Span(comptime T: type) type { + var ptr_info = @typeInfo(T).Pointer; + switch (ptr_info.size) { + .One => switch (@typeInfo(ptr_info.child)) { + .Array => |info| { + ptr_info.child = info.child; + ptr_info.sentinel = info.sentinel; + }, + else => @compileError("invalid type given to std.mem.Span"), + }, + .C => { + ptr_info.sentinel = 0; + }, + .Many, .Slice => {}, + } + ptr_info.size = .Slice; + return @Type(std.builtin.TypeInfo{ .Pointer = ptr_info }); +} + +test "Span" { + testing.expect(Span(*[5]u16) == []u16); + testing.expect(Span(*const [5]u16) == []const u16); + testing.expect(Span([]u16) == []u16); + testing.expect(Span([]const u8) == []const u8); + testing.expect(Span([:1]u16) == [:1]u16); + testing.expect(Span([:1]const u8) == [:1]const u8); + testing.expect(Span([*:1]u16) == [:1]u16); + testing.expect(Span([*:1]const u8) == [:1]const u8); + testing.expect(Span([*c]u16) == [:0]u16); + testing.expect(Span([*c]const u8) == [:0]const u8); +} + +/// 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 +/// the constness of the input type. +pub fn span(ptr: var) Span(@TypeOf(ptr)) { + const Result = Span(@TypeOf(ptr)); + const l = length(ptr); + if (@typeInfo(Result).Pointer.sentinel) |s| { + return ptr[0..l :s]; + } else { + return ptr[0..l]; + } +} + +test "span" { + var array: [5]u16 = [_]u16{ 1, 2, 3, 4, 5 }; + const ptr = array[0..2 :3].ptr; + testing.expect(eql(u16, span(ptr), &[_]u16{ 1, 2 })); + testing.expect(eql(u16, span(&array), &[_]u16{ 1, 2, 3, 4, 5 })); +} + +/// Takes a pointer to an array, an array, a sentinel-terminated pointer, +/// or a slice, and returns the length. +pub fn length(ptr: var) usize { + return switch (@typeInfo(@TypeOf(ptr))) { + .Array => |info| info.len, + .Pointer => |info| switch (info.size) { + .One => switch (@typeInfo(info.child)) { + .Array => |x| x.len, + else => @compileError("invalid type given to std.mem.length"), + }, + .Many => if (info.sentinel) |sentinel| + indexOfSentinel(info.child, sentinel, ptr) + else + @compileError("length of pointer with no sentinel"), + .C => indexOfSentinel(info.child, 0, ptr), + .Slice => ptr.len, + }, + else => @compileError("invalid type given to std.mem.length"), + }; +} + +test "length" { + testing.expect(length("aoeu") == 4); + + { + var array: [5]u16 = [_]u16{ 1, 2, 3, 4, 5 }; + testing.expect(length(&array) == 5); + testing.expect(length(array[0..3]) == 3); + array[2] = 0; + const ptr = array[0..2 :0].ptr; + testing.expect(length(ptr) == 2); + } +} + +pub fn indexOfSentinel(comptime Elem: type, comptime sentinel: Elem, ptr: [*:sentinel]const Elem) usize { + var i: usize = 0; + while (ptr[i] != sentinel) { + i += 1; + } + return i; +} + /// Returns true if all elements in a slice are equal to the scalar value provided pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool { for (slice) |item| { From ef3d761da545a3a72928ed0e0ba3b749a4cb74d8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 1 Mar 2020 13:21:29 -0500 Subject: [PATCH 4/4] breaking: std.mem.len no longer takes a type argument also update fmt code to use std.mem.span. --- lib/std/cstr.zig | 2 +- lib/std/fmt.zig | 6 ++---- lib/std/mem.zig | 38 ++++++++++++++++----------------- lib/std/net.zig | 2 +- lib/std/os.zig | 2 +- lib/std/special/c.zig | 2 +- src-self-hosted/translate_c.zig | 2 +- test/stage1/behavior/misc.zig | 2 +- 8 files changed, 27 insertions(+), 29 deletions(-) diff --git a/lib/std/cstr.zig b/lib/std/cstr.zig index 4057d4b62b..9cb16b0ed3 100644 --- a/lib/std/cstr.zig +++ b/lib/std/cstr.zig @@ -28,7 +28,7 @@ test "cstr fns" { fn testCStrFnsImpl() void { testing.expect(cmp("aoeu", "aoez") == -1); - testing.expect(mem.len(u8, "123456789") == 9); + testing.expect(mem.len("123456789") == 9); } /// Returns a mutable, null-terminated slice with the same length as `slice`. diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 97f2133d67..3729b7dc87 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -442,13 +442,11 @@ pub fn formatType( }, .Many, .C => { if (ptr_info.sentinel) |sentinel| { - const slice = mem.pointerToSlice([:sentinel]const ptr_info.child, value); - return formatType(slice, fmt, options, context, Errors, output, max_depth); + return formatType(mem.span(value), fmt, options, context, Errors, output, max_depth); } if (ptr_info.child == u8) { if (fmt.len > 0 and fmt[0] == 's') { - const slice = mem.pointerToSlice([:0]const u8, @as([*:0]const u8, value)); - return formatText(slice, fmt, options, context, Errors, output); + return formatText(mem.span(value), fmt, options, context, Errors, output); } } return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }); diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 775e999e0b..a6c4d0057e 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -482,27 +482,21 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { return true; } -/// Deprecated. Use `length` or `indexOfSentinel`. -pub fn len(comptime T: type, ptr: [*:0]const T) usize { - var count: usize = 0; - while (ptr[count] != 0) : (count += 1) {} - return count; -} - /// Deprecated. Use `span`. pub fn toSliceConst(comptime T: type, ptr: [*:0]const T) [:0]const T { - return ptr[0..len(T, ptr) :0]; + return ptr[0..len(ptr) :0]; } /// Deprecated. Use `span`. pub fn toSlice(comptime T: type, ptr: [*:0]T) [:0]T { - return ptr[0..len(T, ptr) :0]; + return ptr[0..len(ptr) :0]; } /// 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 -/// the constness of the input type. `[*c]` pointers are assumed to be 0-terminated. +/// the constness of the input type. `[*c]` pointers are assumed to be 0-terminated, +/// and assumed to not allow null. pub fn Span(comptime T: type) type { var ptr_info = @typeInfo(T).Pointer; switch (ptr_info.size) { @@ -515,6 +509,7 @@ pub fn Span(comptime T: type) type { }, .C => { ptr_info.sentinel = 0; + ptr_info.is_allowzero = false; }, .Many, .Slice => {}, } @@ -541,7 +536,7 @@ test "Span" { /// the constness of the input type. pub fn span(ptr: var) Span(@TypeOf(ptr)) { const Result = Span(@TypeOf(ptr)); - const l = length(ptr); + const l = len(ptr); if (@typeInfo(Result).Pointer.sentinel) |s| { return ptr[0..l :s]; } else { @@ -558,7 +553,7 @@ test "span" { /// Takes a pointer to an array, an array, a sentinel-terminated pointer, /// or a slice, and returns the length. -pub fn length(ptr: var) usize { +pub fn len(ptr: var) usize { return switch (@typeInfo(@TypeOf(ptr))) { .Array => |info| info.len, .Pointer => |info| switch (info.size) { @@ -577,16 +572,16 @@ pub fn length(ptr: var) usize { }; } -test "length" { - testing.expect(length("aoeu") == 4); +test "len" { + testing.expect(len("aoeu") == 4); { var array: [5]u16 = [_]u16{ 1, 2, 3, 4, 5 }; - testing.expect(length(&array) == 5); - testing.expect(length(array[0..3]) == 3); + testing.expect(len(&array) == 5); + testing.expect(len(array[0..3]) == 3); array[2] = 0; const ptr = array[0..2 :0].ptr; - testing.expect(length(ptr) == 2); + testing.expect(len(ptr) == 2); } } @@ -1867,8 +1862,13 @@ fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type { return *[length]meta.Child(meta.Child(T)); } -///Given a pointer to an array, returns a pointer to a portion of that array, preserving constness. -pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubArrayPtrReturnType(@TypeOf(ptr), length) { +/// Given a pointer to an array, returns a pointer to a portion of that array, preserving constness. +/// TODO this will be obsoleted by https://github.com/ziglang/zig/issues/863 +pub fn subArrayPtr( + ptr: var, + comptime start: usize, + comptime length: usize, +) SubArrayPtrReturnType(@TypeOf(ptr), length) { assert(start + length <= ptr.*.len); const ReturnType = SubArrayPtrReturnType(@TypeOf(ptr), length); diff --git a/lib/std/net.zig b/lib/std/net.zig index b54803cd39..6d0daefdc0 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -352,7 +352,7 @@ pub const Address = extern union { unreachable; } - const path_len = std.mem.len(u8, @ptrCast([*:0]const u8, &self.un.path)); + const path_len = std.mem.len(@ptrCast([*:0]const u8, &self.un.path)); return @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len); }, else => unreachable, diff --git a/lib/std/os.zig b/lib/std/os.zig index 24d78bec9a..127ada8fe5 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1095,7 +1095,7 @@ pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std. pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8) void { for (envp_buf) |env| { - const env_buf = if (env) |ptr| ptr[0 .. mem.len(u8, ptr) + 1] else break; + const env_buf = if (env) |ptr| ptr[0 .. mem.len(ptr) + 1] else break; allocator.free(env_buf); } allocator.free(envp_buf); diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig index 1f11fabca0..e0c2636df1 100644 --- a/lib/std/special/c.zig +++ b/lib/std/special/c.zig @@ -47,7 +47,7 @@ fn strcmp(s1: [*:0]const u8, s2: [*:0]const u8) callconv(.C) c_int { } fn strlen(s: [*:0]const u8) callconv(.C) usize { - return std.mem.len(u8, s); + return std.mem.len(s); } fn strncmp(_l: [*:0]const u8, _r: [*:0]const u8, _n: usize) callconv(.C) c_int { diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index b33c758c38..8efc0e3746 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -4849,7 +4849,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { } const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc); - const slice = begin_c[0..mem.len(u8, begin_c)]; + const slice = begin_c[0..mem.len(begin_c)]; tok_list.shrink(0); var tokenizer = std.c.Tokenizer{ diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index 681f5be500..44a8334b5d 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -335,7 +335,7 @@ test "string concatenation" { comptime expect(@TypeOf(a) == *const [12:0]u8); comptime expect(@TypeOf(b) == *const [12:0]u8); - const len = mem.len(u8, b); + const len = mem.len(b); const len_with_null = len + 1; { var i: u32 = 0;