mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
compile errors test harness: support unknown file/line/column
This gets us 2 more passing compile error test cases.
This commit is contained in:
parent
c5c23db627
commit
5103053977
@ -362,8 +362,8 @@ pub fn format(
|
||||
const missing_count = arg_state.args_len - @popCount(ArgSetType, arg_state.used_args);
|
||||
switch (missing_count) {
|
||||
0 => unreachable,
|
||||
1 => @compileError("Unused argument in \"" ++ fmt ++ "\""),
|
||||
else => @compileError((comptime comptimePrint("{d}", .{missing_count})) ++ " unused arguments in \"" ++ fmt ++ "\""),
|
||||
1 => @compileError("Unused argument in '" ++ fmt ++ "'"),
|
||||
else => @compileError((comptime comptimePrint("{d}", .{missing_count})) ++ " unused arguments in '" ++ fmt ++ "'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
90
src/test.zig
90
src/test.zig
@ -37,7 +37,11 @@ const ErrorMsg = union(enum) {
|
||||
src: struct {
|
||||
src_path: []const u8,
|
||||
msg: []const u8,
|
||||
// maxint means match anything
|
||||
// this is a workaround for stage1 compiler bug I ran into when making it ?u32
|
||||
line: u32,
|
||||
// maxint means match anything
|
||||
// this is a workaround for stage1 compiler bug I ran into when making it ?u32
|
||||
column: u32,
|
||||
kind: Kind,
|
||||
},
|
||||
@ -81,13 +85,23 @@ const ErrorMsg = union(enum) {
|
||||
_ = options;
|
||||
switch (self) {
|
||||
.src => |src| {
|
||||
return writer.print("{s}:{d}:{d}: {s}: {s}", .{
|
||||
src.src_path,
|
||||
src.line + 1,
|
||||
src.column + 1,
|
||||
@tagName(src.kind),
|
||||
src.msg,
|
||||
});
|
||||
if (!std.mem.eql(u8, src.src_path, "?") or
|
||||
src.line != std.math.maxInt(u32) or
|
||||
src.column != std.math.maxInt(u32))
|
||||
{
|
||||
try writer.print("{s}:", .{src.src_path});
|
||||
if (src.line != std.math.maxInt(u32)) {
|
||||
try writer.print("{d}:", .{src.line + 1});
|
||||
} else {
|
||||
try writer.writeAll("?:");
|
||||
}
|
||||
if (src.column != std.math.maxInt(u32)) {
|
||||
try writer.print("{d}: ", .{src.column + 1});
|
||||
} else {
|
||||
try writer.writeAll("?: ");
|
||||
}
|
||||
}
|
||||
return writer.print("{s}: {s}", .{ @tagName(src.kind), src.msg });
|
||||
},
|
||||
.plain => |plain| {
|
||||
return writer.print("{s}: {s}", .{ @tagName(plain.kind), plain.msg });
|
||||
@ -220,8 +234,14 @@ pub const TestContext = struct {
|
||||
const kind_text = it.next() orelse @panic("missing 'error'/'note'");
|
||||
const msg = it.rest()[1..]; // skip over the space at end of "error: "
|
||||
|
||||
const line = std.fmt.parseInt(u32, line_text, 10) catch @panic("bad line number");
|
||||
const column = std.fmt.parseInt(u32, col_text, 10) catch @panic("bad column number");
|
||||
const line: ?u32 = if (std.mem.eql(u8, line_text, "?"))
|
||||
null
|
||||
else
|
||||
std.fmt.parseInt(u32, line_text, 10) catch @panic("bad line number");
|
||||
const column: ?u32 = if (std.mem.eql(u8, line_text, "?"))
|
||||
null
|
||||
else
|
||||
std.fmt.parseInt(u32, col_text, 10) catch @panic("bad column number");
|
||||
const kind: ErrorMsg.Kind = if (std.mem.eql(u8, kind_text, " error"))
|
||||
.@"error"
|
||||
else if (std.mem.eql(u8, kind_text, " note"))
|
||||
@ -229,16 +249,28 @@ pub const TestContext = struct {
|
||||
else
|
||||
@panic("expected 'error'/'note'");
|
||||
|
||||
if (line == 0 or column == 0) {
|
||||
@panic("line and column must be specified starting at one");
|
||||
}
|
||||
const line_0based: u32 = if (line) |n| blk: {
|
||||
if (n == 0) {
|
||||
print("{s}: line must be specified starting at one\n", .{self.name});
|
||||
return;
|
||||
}
|
||||
break :blk n - 1;
|
||||
} else std.math.maxInt(u32);
|
||||
|
||||
const column_0based: u32 = if (column) |n| blk: {
|
||||
if (n == 0) {
|
||||
print("{s}: line must be specified starting at one\n", .{self.name});
|
||||
return;
|
||||
}
|
||||
break :blk n - 1;
|
||||
} else std.math.maxInt(u32);
|
||||
|
||||
array[i] = .{
|
||||
.src = .{
|
||||
.src_path = src_path,
|
||||
.msg = msg,
|
||||
.line = line - 1,
|
||||
.column = column - 1,
|
||||
.line = line_0based,
|
||||
.column = column_0based,
|
||||
.kind = kind,
|
||||
},
|
||||
};
|
||||
@ -737,7 +769,7 @@ pub const TestContext = struct {
|
||||
}
|
||||
var ok = true;
|
||||
if (case.expect_exact) {
|
||||
var err_iter = ErrLineIter.init(result.stderr);
|
||||
var err_iter = std.mem.split(result.stderr, "\n");
|
||||
var i: usize = 0;
|
||||
ok = while (err_iter.next()) |line| : (i += 1) {
|
||||
if (i >= case_error_list.len) break false;
|
||||
@ -940,8 +972,10 @@ pub const TestContext = struct {
|
||||
std.mem.eql(u8, case_msg.src.src_path, actual_msg.src_path);
|
||||
|
||||
if (src_path_ok and
|
||||
actual_msg.line == case_msg.src.line and
|
||||
actual_msg.column == case_msg.src.column and
|
||||
(case_msg.src.line == std.math.maxInt(u32) or
|
||||
actual_msg.line == case_msg.src.line) and
|
||||
(case_msg.src.column == std.math.maxInt(u32) or
|
||||
actual_msg.column == case_msg.src.column) and
|
||||
std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and
|
||||
case_msg.src.kind == .@"error")
|
||||
{
|
||||
@ -978,8 +1012,10 @@ pub const TestContext = struct {
|
||||
}
|
||||
if (ex_tag != .src) continue;
|
||||
|
||||
if (actual_msg.line == case_msg.src.line and
|
||||
actual_msg.column == case_msg.src.column and
|
||||
if ((case_msg.src.line == std.math.maxInt(u32) or
|
||||
actual_msg.line == case_msg.src.line) and
|
||||
(case_msg.src.column == std.math.maxInt(u32) or
|
||||
actual_msg.column == case_msg.src.column) and
|
||||
std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and
|
||||
case_msg.src.kind == .note)
|
||||
{
|
||||
@ -1162,19 +1198,3 @@ fn dumpArgs(argv: []const []const u8) void {
|
||||
}
|
||||
|
||||
const tmp_src_path = "tmp.zig";
|
||||
|
||||
const ErrLineIter = struct {
|
||||
lines: std.mem.SplitIterator,
|
||||
|
||||
fn init(input: []const u8) ErrLineIter {
|
||||
return ErrLineIter{ .lines = std.mem.split(input, "\n") };
|
||||
}
|
||||
|
||||
fn next(self: *ErrLineIter) ?[]const u8 {
|
||||
while (self.lines.next()) |line| {
|
||||
if (std.mem.indexOf(u8, line, tmp_src_path) != null)
|
||||
return line;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@ -2,6 +2,14 @@ const std = @import("std");
|
||||
const TestContext = @import("../src/test.zig").TestContext;
|
||||
|
||||
pub fn addCases(ctx: *TestContext) !void {
|
||||
ctx.exeErrStage1("std.fmt error for unused arguments",
|
||||
\\pub fn main() !void {
|
||||
\\ @import("std").debug.print("{d} {d} {d} {d} {d}", .{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15});
|
||||
\\}
|
||||
, &.{
|
||||
"?:?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'",
|
||||
});
|
||||
|
||||
ctx.objErrStage1("lazy pointer with undefined element type",
|
||||
\\export fn foo() void {
|
||||
\\ comptime var T: type = undefined;
|
||||
@ -6120,7 +6128,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\
|
||||
\\export fn entry() usize { return @sizeOf(@TypeOf(resource)); }
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:1:29: error: unable to find 'bogus.txt'",
|
||||
"tmp.zig:1:29: error: unable to find '",
|
||||
});
|
||||
|
||||
ctx.objErrStage1("non-const expression in struct literal outside function",
|
||||
|
Loading…
Reference in New Issue
Block a user