master
  1const std = @import("std");
  2const builtin = @import("builtin");
  3const Cases = @import("src/Cases.zig");
  4
  5pub fn addCases(ctx: *Cases, b: *std.Build) !void {
  6    // This test is currently disabled because the leading spaces aligning non-initial lines of the
  7    // error message don't play nice with the test runner.
  8    if (false) {
  9        const case = ctx.obj("multiline error message", b.graph.host);
 10        case.addError(
 11            \\comptime {
 12            \\    @compileError("hello\nworld");
 13            \\}
 14        , &[_][]const u8{
 15            \\:2:5: error: hello
 16            \\             world
 17        });
 18    }
 19
 20    // This test is currently disabled because the leading spaces aligning non-initial lines of the
 21    // error message don't play nice with the test runner.
 22    if (false) {
 23        const case = ctx.obj("multiline error message with trailing newline", b.graph.host);
 24        case.addError(
 25            \\comptime {
 26            \\    @compileError(
 27            \\        \\
 28            \\        \\hello!
 29            \\        \\I'm a multiline error message.
 30            \\        \\I hope to be very useful!
 31            \\        \\
 32            \\        \\also I will leave this trailing newline here if you don't mind
 33            \\        \\
 34            \\    );
 35            \\}
 36        , &[_][]const u8{
 37            \\:2:5: error: 
 38            \\             hello!
 39            \\             I'm a multiline error message.
 40            \\             I hope to be very useful!
 41            \\             
 42            \\             also I will leave this trailing newline here if you don't mind
 43            \\             
 44        });
 45    }
 46
 47    {
 48        const case = ctx.obj("missing semicolon at EOF", b.graph.host);
 49        case.addError(
 50            \\const foo = 1
 51        , &[_][]const u8{
 52            \\:1:14: error: expected ';' after declaration
 53        });
 54    }
 55
 56    {
 57        const case = ctx.obj("argument causes error", b.graph.host);
 58
 59        case.addError(
 60            \\pub export fn entry() void {
 61            \\    var lib: @import("b.zig").ElfDynLib = undefined;
 62            \\    _ = lib.lookup(fn () void);
 63            \\}
 64        , &[_][]const u8{
 65            ":3:12: error: unable to resolve comptime value",
 66            ":3:19: note: call to generic function instantiated with comptime-only return type '?fn () void' is evaluated at comptime",
 67            ":2:55: note: return type declared here",
 68            ":3:19: note: use '*const fn () void' for a function pointer type",
 69        });
 70        case.addSourceFile("b.zig",
 71            \\pub const ElfDynLib = struct {
 72            \\    pub fn lookup(self: *ElfDynLib, comptime T: type) ?T {
 73            \\        _ = self;
 74            \\        return undefined;
 75            \\    }
 76            \\};
 77        );
 78    }
 79
 80    {
 81        const case = ctx.obj("astgen failure in file struct", b.graph.host);
 82
 83        case.addError(
 84            \\pub export fn entry() void {
 85            \\    _ = (@sizeOf(@import("b.zig")));
 86            \\}
 87        , &[_][]const u8{
 88            ":1:1: error: expected type expression, found '+'",
 89        });
 90        case.addSourceFile("b.zig",
 91            \\+
 92        );
 93    }
 94
 95    {
 96        const case = ctx.obj("invalid store to comptime field", b.graph.host);
 97
 98        case.addError(
 99            \\const a = @import("a.zig");
100            \\
101            \\export fn entry() void {
102            \\    _ = a.S.qux(a.S{ .foo = 2, .bar = 2 });
103            \\}
104        , &[_][]const u8{
105            ":4:23: error: value stored in comptime field does not match the default value of the field",
106            ":2:25: note: default value set here",
107        });
108        case.addSourceFile("a.zig",
109            \\pub const S = struct {
110            \\    comptime foo: u32 = 1,
111            \\    bar: u32,
112            \\    pub fn qux(x: @This()) void {
113            \\        _ = x;
114            \\    }
115            \\};
116        );
117    }
118
119    {
120        const case = ctx.obj("file in multiple modules", b.graph.host);
121        case.addDepModule("foo", "foo.zig");
122
123        case.addError(
124            \\comptime {
125            \\    _ = @import("foo");
126            \\    _ = @import("foo.zig");
127            \\}
128        , &[_][]const u8{
129            ":1:1: error: file exists in modules 'foo' and 'root'",
130            ":1:1: note: files must belong to only one module",
131            ":1:1: note: file is the root of module 'foo'",
132            ":3:17: note: file is imported here by the root of module 'root'",
133        });
134        case.addSourceFile("foo.zig",
135            \\const dummy = 0;
136        );
137    }
138
139    {
140        const case = ctx.obj("wrong same named struct", b.graph.host);
141
142        case.addError(
143            \\const a = @import("a.zig");
144            \\const b = @import("b.zig");
145            \\
146            \\export fn entry() void {
147            \\    var a1: a.Foo = undefined;
148            \\    bar(&a1);
149            \\}
150            \\
151            \\fn bar(_: *b.Foo) void {}
152        , &[_][]const u8{
153            ":6:9: error: expected type '*b.Foo', found '*a.Foo'",
154            ":6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
155            ":1:17: note: struct declared here",
156            ":1:17: note: struct declared here",
157            ":9:11: note: parameter type declared here",
158        });
159
160        case.addSourceFile("a.zig",
161            \\pub const Foo = struct {
162            \\    x: i32,
163            \\};
164        );
165
166        case.addSourceFile("b.zig",
167            \\pub const Foo = struct {
168            \\    z: f64,
169            \\};
170        );
171    }
172
173    {
174        const case = ctx.obj("non-printable invalid character", b.graph.host);
175
176        case.addError("\xff\xfe" ++
177            \\export fn foo() bool {
178            \\    return true;
179            \\}
180        , &[_][]const u8{
181            ":1:1: error: expected type expression, found 'invalid token'",
182        });
183    }
184
185    {
186        const case = ctx.obj("imported generic method call with invalid param", b.graph.host);
187
188        case.addError(
189            \\pub const import = @import("import.zig");
190            \\
191            \\export fn callComptimeBoolFunctionWithRuntimeBool(x: bool) void {
192            \\    import.comptimeBoolFunction(x);
193            \\}
194            \\
195            \\export fn callComptimeAnytypeFunctionWithRuntimeBool(x: bool) void {
196            \\    import.comptimeAnytypeFunction(x);
197            \\}
198            \\
199            \\export fn callAnytypeFunctionWithRuntimeComptimeOnlyType(x: u32) void {
200            \\    const S = struct { x: u32, y: type };
201            \\    import.anytypeFunction(S{ .x = x, .y = u32 });
202            \\}
203        , &[_][]const u8{
204            ":4:33: error: unable to resolve comptime value",
205            ":4:33: note: argument to comptime parameter must be comptime-known",
206            ":1:29: note: parameter declared comptime here",
207            ":8:36: error: unable to resolve comptime value",
208            ":8:36: note: argument to comptime parameter must be comptime-known",
209            ":2:32: note: parameter declared comptime here",
210            ":13:32: error: unable to resolve comptime value",
211            ":13:32: note: initializer of comptime-only struct 'tmp.callAnytypeFunctionWithRuntimeComptimeOnlyType.S' must be comptime-known",
212            ":12:35: note: struct requires comptime because of this field",
213            ":12:35: note: types are not available at runtime",
214        });
215
216        case.addSourceFile("import.zig",
217            \\pub fn comptimeBoolFunction(comptime _: bool) void {}
218            \\pub fn comptimeAnytypeFunction(comptime _: anytype) void {}
219            \\pub fn anytypeFunction(_: anytype) void {}
220        );
221    }
222
223    {
224        const case = ctx.obj("invalid byte in string", b.graph.host);
225
226        case.addError("_ = \"\x01Q\";", &[_][]const u8{
227            ":1:6: error: string literal contains invalid byte: '\\x01'",
228        });
229    }
230
231    {
232        const case = ctx.obj("invalid byte in comment", b.graph.host);
233
234        case.addError("//\x01Q", &[_][]const u8{
235            ":1:3: error: comment contains invalid byte: '\\x01'",
236        });
237    }
238
239    {
240        const case = ctx.obj("control character in character literal", b.graph.host);
241
242        case.addError("const c = '\x01';", &[_][]const u8{
243            ":1:12: error: character literal contains invalid byte: '\\x01'",
244        });
245    }
246
247    {
248        const case = ctx.obj("invalid byte at start of token", b.graph.host);
249
250        case.addError("x = \x00Q", &[_][]const u8{
251            ":1:5: error: expected expression, found 'invalid token'",
252        });
253    }
254}