authorgravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2022-07-23 16:53:59+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-27 18:07:53+03:00
logbaafb8a491c296fbf434c8cf44d9485e8f2c729c
tree4dffed76fe1898abb975c70085e509b7f0e3a879
parent4ef7d8581085394d55f5effbb38c05a15546af1b

std.fmt: add more invalid format string errors


12 files changed, 64 insertions(+), 30 deletions(-)

lib/std/fmt.zig+44-10
......@@ -454,6 +454,10 @@ fn stripOptionalOrErrorUnionSpec(comptime fmt: []const u8) []const u8 {
454454 fmt[1..];
455455}
456456
457fn invalidFmtErr(comptime fmt: []const u8, value: anytype) void {
458 @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
459}
460
457461pub fn formatType(
458462 value: anytype,
459463 comptime fmt: []const u8,
......@@ -482,9 +486,11 @@ pub fn formatType(
482486 return formatValue(value, actual_fmt, options, writer);
483487 },
484488 .Void => {
489 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
485490 return formatBuf("void", options, writer);
486491 },
487492 .Bool => {
493 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
488494 return formatBuf(if (value) "true" else "false", options, writer);
489495 },
490496 .Optional => {
......@@ -504,16 +510,18 @@ pub fn formatType(
504510 if (value) |payload| {
505511 return formatType(payload, remaining_fmt, options, writer, max_depth);
506512 } else |err| {
507 return formatType(err, remaining_fmt, options, writer, max_depth);
513 return formatType(err, "", options, writer, max_depth);
508514 }
509515 },
510516 .ErrorSet => {
517 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
511518 try writer.writeAll("error.");
512519 return writer.writeAll(@errorName(value));
513520 },
514521 .Enum => |enumInfo| {
515522 try writer.writeAll(@typeName(T));
516523 if (enumInfo.is_exhaustive) {
524 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
517525 try writer.writeAll(".");
518526 try writer.writeAll(@tagName(value));
519527 return;
......@@ -534,6 +542,7 @@ pub fn formatType(
534542 try writer.writeAll(")");
535543 },
536544 .Union => |info| {
545 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
537546 try writer.writeAll(@typeName(T));
538547 if (max_depth == 0) {
539548 return writer.writeAll("{ ... }");
......@@ -553,6 +562,7 @@ pub fn formatType(
553562 }
554563 },
555564 .Struct => |info| {
565 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
556566 if (info.is_tuple) {
557567 // Skip the type and field names when formatting tuples.
558568 if (max_depth == 0) {
......@@ -608,7 +618,7 @@ pub fn formatType(
608618 }
609619 return;
610620 }
611 @compileError("unknown format string: '" ++ actual_fmt ++ "' for type '" ++ @typeName(T) ++ "'");
621 invalidFmtErr(fmt, value);
612622 },
613623 .Enum, .Union, .Struct => {
614624 return formatType(value.*, actual_fmt, options, writer, max_depth);
......@@ -630,7 +640,7 @@ pub fn formatType(
630640 else => {},
631641 }
632642 }
633 @compileError("unknown format string: '" ++ actual_fmt ++ "' for type '" ++ @typeName(T) ++ "'");
643 invalidFmtErr(fmt, value);
634644 },
635645 .Slice => {
636646 if (actual_fmt.len == 0)
......@@ -693,14 +703,22 @@ pub fn formatType(
693703 try writer.writeAll(" }");
694704 },
695705 .Fn => {
706 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
696707 return format(writer, "{s}@{x}", .{ @typeName(T), @ptrToInt(value) });
697708 },
698 .Type => return formatBuf(@typeName(value), options, writer),
709 .Type => {
710 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
711 return formatBuf(@typeName(value), options, writer);
712 },
699713 .EnumLiteral => {
714 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
700715 const buffer = [_]u8{'.'} ++ @tagName(value);
701716 return formatBuf(buffer, options, writer);
702717 },
703 .Null => return formatBuf("null", options, writer),
718 .Null => {
719 if (actual_fmt.len != 0) invalidFmtErr(fmt, value);
720 return formatBuf("null", options, writer);
721 },
704722 else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"),
705723 }
706724}
......@@ -768,7 +786,7 @@ pub fn formatIntValue(
768786 radix = 8;
769787 case = .lower;
770788 } else {
771 @compileError("unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
789 invalidFmtErr(fmt, value);
772790 }
773791
774792 return formatInt(int_value, radix, case, options, writer);
......@@ -797,7 +815,7 @@ fn formatFloatValue(
797815 error.NoSpaceLeft => unreachable,
798816 };
799817 } else {
800 @compileError("unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
818 invalidFmtErr(fmt, value);
801819 }
802820
803821 return formatBuf(buf_stream.getWritten(), options, writer);
......@@ -2000,6 +2018,12 @@ test "optional" {
20002018 {
20012019 const value: ?i32 = 1234;
20022020 try expectFmt("optional: 1234\n", "optional: {?}\n", .{value});
2021 try expectFmt("optional: 1234\n", "optional: {?d}\n", .{value});
2022 try expectFmt("optional: 4d2\n", "optional: {?x}\n", .{value});
2023 }
2024 {
2025 const value: ?[]const u8 = "string";
2026 try expectFmt("optional: string\n", "optional: {?s}\n", .{value});
20032027 }
20042028 {
20052029 const value: ?i32 = null;
......@@ -2015,6 +2039,12 @@ test "error" {
20152039 {
20162040 const value: anyerror!i32 = 1234;
20172041 try expectFmt("error union: 1234\n", "error union: {!}\n", .{value});
2042 try expectFmt("error union: 1234\n", "error union: {!d}\n", .{value});
2043 try expectFmt("error union: 4d2\n", "error union: {!x}\n", .{value});
2044 }
2045 {
2046 const value: anyerror![]const u8 = "string";
2047 try expectFmt("error union: string\n", "error union: {!s}\n", .{value});
20182048 }
20192049 {
20202050 const value: anyerror!i32 = error.InvalidChar;
......@@ -2209,6 +2239,10 @@ test "struct" {
22092239}
22102240
22112241test "enum" {
2242 if (builtin.zig_backend == .stage1) {
2243 // stage1 starts the typename with 'std' which might also be desireable for stage2
2244 return error.SkipZigTest;
2245 }
22122246 const Enum = enum {
22132247 One,
22142248 Two,
......@@ -2216,8 +2250,8 @@ test "enum" {
22162250 const value = Enum.Two;
22172251 try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{value});
22182252 try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});
2219 try expectFmt("enum: Enum.One\n", "enum: {x}\n", .{Enum.One});
2220 try expectFmt("enum: Enum.Two\n", "enum: {X}\n", .{Enum.Two});
2253 try expectFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});
2254 try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});
22212255
22222256 // test very large enum to verify ct branch quota is large enough
22232257 try expectFmt("enum: os.windows.win32error.Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
......@@ -2675,7 +2709,7 @@ test "vector" {
26752709}
26762710
26772711test "enum-literal" {
2678 try expectFmt(".hello_world", "{s}", .{.hello_world});
2712 try expectFmt(".hello_world", "{}", .{.hello_world});
26792713}
26802714
26812715test "padding" {
src/Sema.zig+1-1
......@@ -2173,7 +2173,7 @@ fn coerceResultPtr(
21732173 },
21742174 else => {
21752175 if (std.debug.runtime_safety) {
2176 std.debug.panic("unexpected AIR tag for coerce_result_ptr: {s}", .{
2176 std.debug.panic("unexpected AIR tag for coerce_result_ptr: {}", .{
21772177 air_tags[trash_inst],
21782178 });
21792179 } else {
src/arch/sparc64/bits.zig+2-2
......@@ -1582,8 +1582,8 @@ test "Serialize formats" {
15821582 for (testcases) |case| {
15831583 const actual = case.inst.toU32();
15841584 testing.expectEqual(case.expected, actual) catch |err| {
1585 std.debug.print("error: {x}\n", .{err});
1586 std.debug.print("case: {x}\n", .{case});
1585 std.debug.print("error: {}\n", .{err});
1586 std.debug.print("case: {}\n", .{case});
15871587 return err;
15881588 };
15891589 }
src/arch/wasm/CodeGen.zig+3-3
......@@ -1773,7 +1773,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
17731773 } else if (func_val.castTag(.decl_ref)) |decl_ref| {
17741774 break :blk module.declPtr(decl_ref.data);
17751775 }
1776 return self.fail("Expected a function, but instead found type '{s}'", .{func_val.tag()});
1776 return self.fail("Expected a function, but instead found type '{}'", .{func_val.tag()});
17771777 };
17781778
17791779 const sret = if (first_param_sret) blk: {
......@@ -2365,7 +2365,7 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
23652365 },
23662366 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
23672367 .zero, .null_value => return WValue{ .imm32 = 0 },
2368 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),
2368 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {}", .{val.tag()}),
23692369 },
23702370 .Enum => {
23712371 if (val.castTag(.enum_field_index)) |field_index| {
......@@ -2421,7 +2421,7 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
24212421 const is_pl = val.tag() == .opt_payload;
24222422 return WValue{ .imm32 = if (is_pl) @as(u32, 1) else 0 };
24232423 },
2424 else => |zig_type| return self.fail("Wasm TODO: LowerConstant for zigTypeTag {s}", .{zig_type}),
2424 else => |zig_type| return self.fail("Wasm TODO: LowerConstant for zigTypeTag {}", .{zig_type}),
24252425 }
24262426}
24272427
src/arch/x86_64/Emit.zig+1-1
......@@ -202,7 +202,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
202202 .pop_regs => try emit.mirPushPopRegisterList(.pop, inst),
203203
204204 else => {
205 return emit.fail("Implement MIR->Emit lowering for x86_64 for pseudo-inst: {s}", .{tag});
205 return emit.fail("Implement MIR->Emit lowering for x86_64 for pseudo-inst: {}", .{tag});
206206 },
207207 }
208208 }
src/link/MachO/Atom.zig+3-3
......@@ -246,7 +246,7 @@ pub fn parseRelocs(self: *Atom, relocs: []const macho.relocation_info, context:
246246 else => {
247247 log.err("unexpected relocation type after ARM64_RELOC_ADDEND", .{});
248248 log.err(" expected ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12", .{});
249 log.err(" found {s}", .{next});
249 log.err(" found {}", .{next});
250250 return error.UnexpectedRelocationType;
251251 },
252252 }
......@@ -285,7 +285,7 @@ pub fn parseRelocs(self: *Atom, relocs: []const macho.relocation_info, context:
285285 else => {
286286 log.err("unexpected relocation type after ARM64_RELOC_ADDEND", .{});
287287 log.err(" expected ARM64_RELOC_UNSIGNED", .{});
288 log.err(" found {s}", .{@intToEnum(macho.reloc_type_arm64, relocs[i + 1].r_type)});
288 log.err(" found {}", .{@intToEnum(macho.reloc_type_arm64, relocs[i + 1].r_type)});
289289 return error.UnexpectedRelocationType;
290290 },
291291 },
......@@ -294,7 +294,7 @@ pub fn parseRelocs(self: *Atom, relocs: []const macho.relocation_info, context:
294294 else => {
295295 log.err("unexpected relocation type after X86_64_RELOC_ADDEND", .{});
296296 log.err(" expected X86_64_RELOC_UNSIGNED", .{});
297 log.err(" found {s}", .{@intToEnum(macho.reloc_type_x86_64, relocs[i + 1].r_type)});
297 log.err(" found {}", .{@intToEnum(macho.reloc_type_x86_64, relocs[i + 1].r_type)});
298298 return error.UnexpectedRelocationType;
299299 },
300300 },
src/link/MachO/Dylib.zig+2-2
......@@ -167,7 +167,7 @@ pub fn parse(
167167 const this_arch: std.Target.Cpu.Arch = try fat.decodeArch(self.header.?.cputype, true);
168168
169169 if (this_arch != cpu_arch) {
170 log.err("mismatched cpu architecture: expected {s}, found {s}", .{ cpu_arch, this_arch });
170 log.err("mismatched cpu architecture: expected {}, found {}", .{ cpu_arch, this_arch });
171171 return error.MismatchedCpuArchitecture;
172172 }
173173
......@@ -208,7 +208,7 @@ fn readLoadCommands(
208208 }
209209 },
210210 else => {
211 log.debug("Unknown load command detected: 0x{x}.", .{cmd.cmd()});
211 log.debug("Unknown load command detected: 0x{x}.", .{@enumToInt(cmd.cmd())});
212212 },
213213 }
214214 self.load_commands.appendAssumeCapacity(cmd);
src/link/MachO/Object.zig+2-2
......@@ -110,7 +110,7 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch)
110110 },
111111 };
112112 if (this_arch != cpu_arch) {
113 log.err("mismatched cpu architecture: expected {s}, found {s}", .{ cpu_arch, this_arch });
113 log.err("mismatched cpu architecture: expected {}, found {}", .{ cpu_arch, this_arch });
114114 return error.MismatchedCpuArchitecture;
115115 }
116116
......@@ -171,7 +171,7 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch)
171171 cmd.linkedit_data.dataoff += file_offset;
172172 },
173173 else => {
174 log.debug("Unknown load command detected: 0x{x}.", .{cmd.cmd()});
174 log.debug("Unknown load command detected: 0x{x}.", .{@enumToInt(cmd.cmd())});
175175 },
176176 }
177177 self.load_commands.appendAssumeCapacity(cmd);
src/link/MachO/fat.zig+1-1
......@@ -46,7 +46,7 @@ pub fn getLibraryOffset(reader: anytype, cpu_arch: std.Target.Cpu.Arch) !u64 {
4646 return fat_arch.offset;
4747 }
4848 } else {
49 log.err("Could not find matching cpu architecture in fat library: expected {s}", .{cpu_arch});
49 log.err("Could not find matching cpu architecture in fat library: expected {}", .{cpu_arch});
5050 return error.MismatchedCpuArchitecture;
5151 }
5252}
src/main.zig+3-3
......@@ -4076,12 +4076,12 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
40764076
40774077 const stdin = io.getStdIn();
40784078 const source_code = readSourceFileToEndAlloc(gpa, &stdin, null) catch |err| {
4079 fatal("unable to read stdin: {s}", .{err});
4079 fatal("unable to read stdin: {}", .{err});
40804080 };
40814081 defer gpa.free(source_code);
40824082
40834083 var tree = std.zig.parse(gpa, source_code) catch |err| {
4084 fatal("error parsing stdin: {s}", .{err});
4084 fatal("error parsing stdin: {}", .{err});
40854085 };
40864086 defer tree.deinit(gpa);
40874087
......@@ -5011,7 +5011,7 @@ pub fn cmdAstCheck(
50115011 } else {
50125012 const stdin = io.getStdIn();
50135013 const source = readSourceFileToEndAlloc(arena, &stdin, null) catch |err| {
5014 fatal("unable to read stdin: {s}", .{err});
5014 fatal("unable to read stdin: {}", .{err});
50155015 };
50165016 file.sub_file_path = "<stdin>";
50175017 file.source = source;
src/print_zir.zig+1-1
......@@ -551,7 +551,7 @@ const Writer = struct {
551551 fn writeElemTypeIndex(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
552552 const inst_data = self.code.instructions.items(.data)[inst].bin;
553553 try self.writeInstRef(stream, inst_data.lhs);
554 try stream.print(", {d})", .{inst_data.rhs});
554 try stream.print(", {d})", .{@enumToInt(inst_data.rhs)});
555555 }
556556
557557 fn writeUnNode(
src/translate_c.zig+1-1
......@@ -3279,7 +3279,7 @@ fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used:
32793279 return maybeSuppressResult(c, scope, used, as_node);
32803280 },
32813281 else => |kind| {
3282 return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "unsupported constant expression kind '{s}'", .{kind});
3282 return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "unsupported constant expression kind '{}'", .{kind});
32833283 },
32843284 }
32853285}