| 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); |
| 3 | const Cases = @import("src/Cases.zig"); |
| 4 | |
| 5 | pub 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 | } |