From e8740a90b9c1ec2b7043dc5a0aed5474bb648c3d Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Fri, 15 Jan 2021 14:21:39 +1100 Subject: complete {Z} deprecation in std.fmt.formatIntValue formatZigEscapes doesn't exist any more. --- lib/std/fmt.zig | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'lib/std/fmt.zig') diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 196e95f838..02d0c4de68 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -634,12 +634,7 @@ pub fn formatIntValue( @compileError("Cannot print integer that is larger than 8 bits as a ascii"); } } else if (comptime std.mem.eql(u8, fmt, "Z")) { - if (@typeInfo(@TypeOf(int_value)).Int.bits <= 8) { - const c: u8 = int_value; - return formatZigEscapes(@as(*const [1]u8, &c), options, writer); - } else { - @compileError("Cannot escape character with more than 8 bits"); - } + @compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead"); } else if (comptime std.mem.eql(u8, fmt, "u")) { if (@typeInfo(@TypeOf(int_value)).Int.bits <= 21) { return formatUnicodeCodepoint(@as(u21, int_value), options, writer); -- cgit v1.2.3 From 290efc074797e893678154efac61f94a38f6bfc1 Mon Sep 17 00:00:00 2001 From: Dmitry Atamanov Date: Sat, 30 Jan 2021 11:12:44 +0000 Subject: Improve error messages in std.fmt (#7898) --- lib/std/fmt.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/std/fmt.zig') diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 02d0c4de68..27e68ee9c1 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -654,7 +654,7 @@ pub fn formatIntValue( radix = 8; uppercase = false; } else { - @compileError("Unknown format string: '" ++ fmt ++ "'"); + @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); } return formatInt(int_value, radix, uppercase, options, writer); @@ -681,7 +681,7 @@ fn formatFloatValue( else => |e| return e, }; } else { - @compileError("Unknown format string: '" ++ fmt ++ "'"); + @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); } return formatBuf(buf_stream.getWritten(), options, writer); @@ -715,7 +715,7 @@ pub fn formatText( } else if (comptime std.mem.eql(u8, fmt, "Z")) { @compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead"); } else { - @compileError("Unknown format string: '" ++ fmt ++ "'"); + @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); } } -- cgit v1.2.3 From 1480c428065c01c6feff22ce84021c2e0e30aa9b Mon Sep 17 00:00:00 2001 From: Jonathan Marler Date: Sun, 3 Jan 2021 02:20:37 -0700 Subject: require specifier for arrayish types --- lib/std/build.zig | 2 +- lib/std/fmt.zig | 85 ++++++++++++++++++++++++++++---------------- lib/std/testing.zig | 14 ++++---- src/Module.zig | 2 +- src/codegen.zig | 2 +- src/zir_sema.zig | 2 +- test/cli.zig | 8 ++--- test/standalone/cat/main.zig | 2 +- 8 files changed, 71 insertions(+), 46 deletions(-) (limited to 'lib/std/fmt.zig') diff --git a/lib/std/build.zig b/lib/std/build.zig index 0db9d4c24e..77ca854f15 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -739,7 +739,7 @@ pub const Builder = struct { return args.default_target; }, else => |e| { - warn("Unable to parse target '{}': {s}\n\n", .{ triple, @errorName(e) }); + warn("Unable to parse target '{s}': {s}\n\n", .{ triple, @errorName(e) }); self.markInvalidUserInput(); return args.default_target; }, diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 27e68ee9c1..c1b24cc6da 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -69,6 +69,7 @@ pub const FormatOptions = struct { /// - `c`: output integer as an ASCII character. Integer type must have 8 bits at max. /// - `u`: output integer as an UTF-8 sequence. Integer type must have 21 bits at max. /// - `*`: output the address of the value instead of the value itself. +/// - `any`: output a value of any type using its default format /// /// If a formatted user type contains a function of the type /// ``` @@ -387,17 +388,32 @@ pub fn formatAddress(value: anytype, options: FormatOptions, writer: anytype) @T return; } }, - .Array => |info| { - try writer.writeAll(@typeName(info.child) ++ "@"); - try formatInt(@ptrToInt(value), 16, false, FormatOptions{}, writer); - return; - }, else => {}, } @compileError("Cannot format non-pointer type " ++ @typeName(T) ++ " with * specifier"); } +// This ANY const is a workaround for: https://github.com/ziglang/zig/issues/7948 +const ANY = "any"; + +fn defaultSpec(comptime T: type) [:0]const u8 { + switch (@typeInfo(T)) { + .Array => |_| return ANY, + .Pointer => |ptr_info| switch (ptr_info.size) { + .One => switch (@typeInfo(ptr_info.child)) { + .Array => |_| return "*", + else => {}, + }, + .Many, .C => return "*", + .Slice => return ANY, + }, + .Optional => |info| return defaultSpec(info.child), + else => {}, + } + return ""; +} + pub fn formatType( value: anytype, comptime fmt: []const u8, @@ -405,18 +421,19 @@ pub fn formatType( writer: anytype, max_depth: usize, ) @TypeOf(writer).Error!void { - if (comptime std.mem.eql(u8, fmt, "*")) { + const actual_fmt = comptime if (std.mem.eql(u8, fmt, ANY)) defaultSpec(@TypeOf(value)) else fmt; + if (comptime std.mem.eql(u8, actual_fmt, "*")) { return formatAddress(value, options, writer); } const T = @TypeOf(value); if (comptime std.meta.trait.hasFn("format")(T)) { - return try value.format(fmt, options, writer); + return try value.format(actual_fmt, options, writer); } switch (@typeInfo(T)) { .ComptimeInt, .Int, .ComptimeFloat, .Float => { - return formatValue(value, fmt, options, writer); + return formatValue(value, actual_fmt, options, writer); }, .Void => { return formatBuf("void", options, writer); @@ -426,16 +443,16 @@ pub fn formatType( }, .Optional => { if (value) |payload| { - return formatType(payload, fmt, options, writer, max_depth); + return formatType(payload, actual_fmt, options, writer, max_depth); } else { return formatBuf("null", options, writer); } }, .ErrorUnion => { if (value) |payload| { - return formatType(payload, fmt, options, writer, max_depth); + return formatType(payload, actual_fmt, options, writer, max_depth); } else |err| { - return formatType(err, fmt, options, writer, max_depth); + return formatType(err, actual_fmt, options, writer, max_depth); } }, .ErrorSet => { @@ -461,7 +478,7 @@ pub fn formatType( } try writer.writeAll("("); - try formatType(@enumToInt(value), fmt, options, writer, max_depth); + try formatType(@enumToInt(value), actual_fmt, options, writer, max_depth); try writer.writeAll(")"); }, .Union => |info| { @@ -475,7 +492,7 @@ pub fn formatType( try writer.writeAll(" = "); inline for (info.fields) |u_field| { if (value == @field(UnionTagType, u_field.name)) { - try formatType(@field(value, u_field.name), fmt, options, writer, max_depth - 1); + try formatType(@field(value, u_field.name), ANY, options, writer, max_depth - 1); } } try writer.writeAll(" }"); @@ -497,48 +514,54 @@ pub fn formatType( } try writer.writeAll(f.name); try writer.writeAll(" = "); - try formatType(@field(value, f.name), fmt, options, writer, max_depth - 1); + try formatType(@field(value, f.name), ANY, options, writer, max_depth - 1); } try writer.writeAll(" }"); }, .Pointer => |ptr_info| switch (ptr_info.size) { .One => switch (@typeInfo(ptr_info.child)) { .Array => |info| { + if (actual_fmt.len == 0) + @compileError("cannot format array ref without a specifier (i.e. {s} or {*})"); if (info.child == u8) { - if (fmt.len > 0 and comptime mem.indexOfScalar(u8, "sxXeEzZ", fmt[0]) != null) { - return formatText(value, fmt, options, writer); + if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) { + return formatText(value, actual_fmt, options, writer); } } - return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) }); + @compileError("Unknown format string: '" ++ actual_fmt ++ "'"); }, .Enum, .Union, .Struct => { - return formatType(value.*, fmt, options, writer, max_depth); + return formatType(value.*, actual_fmt, options, writer, max_depth); }, else => return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) }), }, .Many, .C => { + if (actual_fmt.len == 0) + @compileError("cannot format pointer without a specifier (i.e. {s} or {*})"); if (ptr_info.sentinel) |sentinel| { - return formatType(mem.span(value), fmt, options, writer, max_depth); + return formatType(mem.span(value), actual_fmt, options, writer, max_depth); } if (ptr_info.child == u8) { - if (fmt.len > 0 and comptime mem.indexOfScalar(u8, "sxXeEzZ", fmt[0]) != null) { - return formatText(mem.span(value), fmt, options, writer); + if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) { + return formatText(mem.span(value), actual_fmt, options, writer); } } - return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) }); + @compileError("Unknown format string: '" ++ actual_fmt ++ "'"); }, .Slice => { + if (actual_fmt.len == 0) + @compileError("cannot format slice without a specifier (i.e. {s} or {any})"); if (max_depth == 0) { return writer.writeAll("{ ... }"); } if (ptr_info.child == u8) { - if (fmt.len > 0 and comptime mem.indexOfScalar(u8, "sxXeEzZ", fmt[0]) != null) { - return formatText(value, fmt, options, writer); + if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) { + return formatText(value, actual_fmt, options, writer); } } try writer.writeAll("{ "); for (value) |elem, i| { - try formatType(elem, fmt, options, writer, max_depth - 1); + try formatType(elem, actual_fmt, options, writer, max_depth - 1); if (i != value.len - 1) { try writer.writeAll(", "); } @@ -547,17 +570,19 @@ pub fn formatType( }, }, .Array => |info| { + if (actual_fmt.len == 0) + @compileError("cannot format array without a specifier (i.e. {s} or {any})"); if (max_depth == 0) { return writer.writeAll("{ ... }"); } if (info.child == u8) { - if (fmt.len > 0 and comptime mem.indexOfScalar(u8, "sxXeEzZ", fmt[0]) != null) { - return formatText(&value, fmt, options, writer); + if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) { + return formatText(&value, actual_fmt, options, writer); } } try writer.writeAll("{ "); for (value) |elem, i| { - try formatType(elem, fmt, options, writer, max_depth - 1); + try formatType(elem, actual_fmt, options, writer, max_depth - 1); if (i < value.len - 1) { try writer.writeAll(", "); } @@ -568,7 +593,7 @@ pub fn formatType( try writer.writeAll("{ "); var i: usize = 0; while (i < info.len) : (i += 1) { - try formatValue(value[i], fmt, options, writer); + try formatValue(value[i], actual_fmt, options, writer); if (i < info.len - 1) { try writer.writeAll(", "); } @@ -1668,7 +1693,7 @@ test "slice" { { var int_slice = [_]u32{ 1, 4096, 391891, 1111111111 }; var runtime_zero: usize = 0; - try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {}", .{int_slice[runtime_zero..]}); + try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {any}", .{int_slice[runtime_zero..]}); try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {d}", .{int_slice[runtime_zero..]}); try expectFmt("int: { 1, 1000, 5fad3, 423a35c7 }", "int: {x}", .{int_slice[runtime_zero..]}); try expectFmt("int: { 00001, 01000, 5fad3, 423a35c7 }", "int: {x:0>5}", .{int_slice[runtime_zero..]}); diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 8df05ba7fe..1d89155a58 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -29,7 +29,7 @@ pub var zig_exe_path: []const u8 = undefined; /// and then aborts when actual_error_union is not expected_error. pub fn expectError(expected_error: anyerror, actual_error_union: anytype) void { if (actual_error_union) |actual_payload| { - std.debug.panic("expected error.{s}, found {}", .{ @errorName(expected_error), actual_payload }); + std.debug.panic("expected error.{s}, found {any}", .{ @errorName(expected_error), actual_payload }); } else |actual_error| { if (expected_error != actual_error) { std.debug.panic("expected error.{s}, found error.{s}", .{ @@ -88,7 +88,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void { }, .Slice => { if (actual.ptr != expected.ptr) { - std.debug.panic("expected slice ptr {}, found {}", .{ expected.ptr, actual.ptr }); + std.debug.panic("expected slice ptr {*}, found {*}", .{ expected.ptr, actual.ptr }); } if (actual.len != expected.len) { std.debug.panic("expected slice len {}, found {}", .{ expected.len, actual.len }); @@ -145,11 +145,11 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void { if (actual) |actual_payload| { expectEqual(expected_payload, actual_payload); } else { - std.debug.panic("expected {}, found null", .{expected_payload}); + std.debug.panic("expected {any}, found null", .{expected_payload}); } } else { if (actual) |actual_payload| { - std.debug.panic("expected null, found {}", .{actual_payload}); + std.debug.panic("expected null, found {any}", .{actual_payload}); } } }, @@ -159,11 +159,11 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void { if (actual) |actual_payload| { expectEqual(expected_payload, actual_payload); } else |actual_err| { - std.debug.panic("expected {}, found {}", .{ expected_payload, actual_err }); + std.debug.panic("expected {any}, found {}", .{ expected_payload, actual_err }); } } else |expected_err| { if (actual) |actual_payload| { - std.debug.panic("expected {}, found {}", .{ expected_err, actual_payload }); + std.debug.panic("expected {}, found {any}", .{ expected_err, actual_payload }); } else |actual_err| { expectEqual(expected_err, actual_err); } @@ -279,7 +279,7 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const var i: usize = 0; while (i < expected.len) : (i += 1) { if (!std.meta.eql(expected[i], actual[i])) { - std.debug.panic("index {} incorrect. expected {}, found {}", .{ i, expected[i], actual[i] }); + std.debug.panic("index {} incorrect. expected {any}, found {any}", .{ i, expected[i], actual[i] }); } } } diff --git a/src/Module.zig b/src/Module.zig index 8de03b54ab..a90998a386 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -2400,7 +2400,7 @@ fn getAnonTypeName(self: *Module, scope: *Scope, base_token: std.zig.ast.TokenIn else => unreachable, }; const loc = tree.tokenLocationLoc(0, tree.token_locs[base_token]); - return std.fmt.allocPrint(self.gpa, "{}:{}:{}", .{ base_name, loc.line, loc.column }); + return std.fmt.allocPrint(self.gpa, "{s}:{}:{}", .{ base_name, loc.line, loc.column }); } fn getNextAnonNameIndex(self: *Module) usize { diff --git a/src/codegen.zig b/src/codegen.zig index 63dbe3268e..9771386403 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -2223,7 +2223,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { writeInt(u32, try self.code.addManyAsArray(4), Instruction.cmp(.al, reg, op).toU32()); break :blk .ne; }, - else => return self.fail(inst.base.src, "TODO implement condbr {} when condition is {}", .{ self.target.cpu.arch, @tagName(cond) }), + else => return self.fail(inst.base.src, "TODO implement condbr {} when condition is {s}", .{ self.target.cpu.arch, @tagName(cond) }), }; const reloc = Reloc{ diff --git a/src/zir_sema.zig b/src/zir_sema.zig index f373d7174d..a8120108a4 100644 --- a/src/zir_sema.zig +++ b/src/zir_sema.zig @@ -1832,7 +1832,7 @@ fn zirBitwise(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*In const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; if (!is_int) { - return mod.fail(scope, inst.base.src, "invalid operands to binary bitwise expression: '{}' and '{}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) }); + return mod.fail(scope, inst.base.src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) }); } if (casted_lhs.value()) |lhs_val| { diff --git a/test/cli.zig b/test/cli.zig index 33dbc2d62b..8dbef06887 100644 --- a/test/cli.zig +++ b/test/cli.zig @@ -51,9 +51,9 @@ fn unwrapArg(arg: UnwrapArgError![]u8) UnwrapArgError![]u8 { } fn printCmd(cwd: []const u8, argv: []const []const u8) void { - std.debug.warn("cd {} && ", .{cwd}); + std.debug.warn("cd {s} && ", .{cwd}); for (argv) |arg| { - std.debug.warn("{} ", .{arg}); + std.debug.warn("{s} ", .{arg}); } std.debug.warn("\n", .{}); } @@ -75,14 +75,14 @@ fn exec(cwd: []const u8, expect_0: bool, argv: []const []const u8) !ChildProcess if ((code != 0) == expect_0) { std.debug.warn("The following command exited with error code {}:\n", .{code}); printCmd(cwd, argv); - std.debug.warn("stderr:\n{}\n", .{result.stderr}); + std.debug.warn("stderr:\n{s}\n", .{result.stderr}); return error.CommandFailed; } }, else => { std.debug.warn("The following command terminated unexpectedly:\n", .{}); printCmd(cwd, argv); - std.debug.warn("stderr:\n{}\n", .{result.stderr}); + std.debug.warn("stderr:\n{s}\n", .{result.stderr}); return error.CommandFailed; }, } diff --git a/test/standalone/cat/main.zig b/test/standalone/cat/main.zig index 89e5fde3cd..80ec97877a 100644 --- a/test/standalone/cat/main.zig +++ b/test/standalone/cat/main.zig @@ -41,6 +41,6 @@ pub fn main() !void { } fn usage(exe: []const u8) !void { - warn("Usage: {} [FILE]...\n", .{exe}); + warn("Usage: {s} [FILE]...\n", .{exe}); return error.Invalid; } -- cgit v1.2.3