blob f936eb49 (274405B) - Raw
1 const tests = @import("tests.zig"); 2 const std = @import("std"); 3 4 pub fn addCases(cases: *tests.CompileErrorContext) void { 5 cases.add("lazy pointer with undefined element type", 6 \\export fn foo() void { 7 \\ comptime var T: type = undefined; 8 \\ const S = struct { x: *T }; 9 \\ const I = @typeInfo(S); 10 \\} 11 , &[_][]const u8{ 12 "tmp.zig:3:28: error: use of undefined value here causes undefined behavior", 13 }); 14 15 cases.add("pointer arithmetic on pointer-to-array", 16 \\export fn foo() void { 17 \\ var x: [10]u8 = undefined; 18 \\ var y = &x; 19 \\ var z = y + 1; 20 \\} 21 , &[_][]const u8{ 22 "tmp.zig:4:17: error: integer value 1 cannot be coerced to type '*[10]u8'", 23 }); 24 25 cases.add("pointer attributes checked when coercing pointer to anon literal", 26 \\comptime { 27 \\ const c: [][]const u8 = &.{"hello", "world" }; 28 \\} 29 \\comptime { 30 \\ const c: *[2][]const u8 = &.{"hello", "world" }; 31 \\} 32 \\const S = struct {a: u8 = 1, b: u32 = 2}; 33 \\comptime { 34 \\ const c: *S = &.{}; 35 \\} 36 , &[_][]const u8{ 37 "mp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'", 38 "mp.zig:5:33: error: expected type '*[2][]const u8', found '*const struct:5:33'", 39 "mp.zig:9:21: error: expected type '*S', found '*const struct:9:21'", 40 }); 41 42 cases.add("@Type() union payload is undefined", 43 \\const Foo = @Type(@import("std").builtin.TypeInfo{ 44 \\ .Struct = undefined, 45 \\}); 46 \\comptime { _ = Foo; } 47 , &[_][]const u8{ 48 "tmp.zig:1:50: error: use of undefined value here causes undefined behavior", 49 }); 50 51 cases.add("wrong initializer for union payload of type 'type'", 52 \\const U = union(enum) { 53 \\ A: type, 54 \\}; 55 \\const S = struct { 56 \\ u: U, 57 \\}; 58 \\export fn entry() void { 59 \\ comptime var v: S = undefined; 60 \\ v.u.A = U{ .A = i32 }; 61 \\} 62 , &[_][]const u8{ 63 "tmp.zig:9:8: error: use of undefined value here causes undefined behavior", 64 }); 65 66 cases.add("union with too small explicit signed tag type", 67 \\const U = union(enum(i2)) { 68 \\ A: u8, 69 \\ B: u8, 70 \\ C: u8, 71 \\ D: u8, 72 \\}; 73 \\export fn entry() void { 74 \\ _ = U{ .D = 1 }; 75 \\} 76 , &[_][]const u8{ 77 "tmp.zig:1:22: error: specified integer tag type cannot represent every field", 78 "tmp.zig:1:22: note: type i2 cannot fit values in range 0...3", 79 }); 80 81 cases.add("union with too small explicit unsigned tag type", 82 \\const U = union(enum(u2)) { 83 \\ A: u8, 84 \\ B: u8, 85 \\ C: u8, 86 \\ D: u8, 87 \\ E: u8, 88 \\}; 89 \\export fn entry() void { 90 \\ _ = U{ .E = 1 }; 91 \\} 92 , &[_][]const u8{ 93 "tmp.zig:1:22: error: specified integer tag type cannot represent every field", 94 "tmp.zig:1:22: note: type u2 cannot fit values in range 0...4", 95 }); 96 97 cases.addCase(x: { 98 var tc = cases.create("callconv(.Interrupt) on unsupported platform", 99 \\export fn entry() callconv(.Interrupt) void {} 100 , &[_][]const u8{ 101 "tmp.zig:1:28: error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64", 102 }); 103 tc.target = std.zig.CrossTarget{ 104 .cpu_arch = .aarch64, 105 .os_tag = .linux, 106 .abi = .none, 107 }; 108 break :x tc; 109 }); 110 111 cases.addCase(x: { 112 var tc = cases.create("callconv(.Signal) on unsupported platform", 113 \\export fn entry() callconv(.Signal) void {} 114 , &[_][]const u8{ 115 "tmp.zig:1:28: error: callconv 'Signal' is only available on AVR, not x86_64", 116 }); 117 tc.target = std.zig.CrossTarget{ 118 .cpu_arch = .x86_64, 119 .os_tag = .linux, 120 .abi = .none, 121 }; 122 break :x tc; 123 }); 124 cases.addCase(x: { 125 var tc = cases.create("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform", 126 \\const F1 = fn () callconv(.Stdcall) void; 127 \\const F2 = fn () callconv(.Fastcall) void; 128 \\const F3 = fn () callconv(.Thiscall) void; 129 \\export fn entry1() void { var a: F1 = undefined; } 130 \\export fn entry2() void { var a: F2 = undefined; } 131 \\export fn entry3() void { var a: F3 = undefined; } 132 , &[_][]const u8{ 133 "tmp.zig:1:27: error: callconv 'Stdcall' is only available on x86, not x86_64", 134 "tmp.zig:2:27: error: callconv 'Fastcall' is only available on x86, not x86_64", 135 "tmp.zig:3:27: error: callconv 'Thiscall' is only available on x86, not x86_64", 136 }); 137 tc.target = std.zig.CrossTarget{ 138 .cpu_arch = .x86_64, 139 .os_tag = .linux, 140 .abi = .none, 141 }; 142 break :x tc; 143 }); 144 145 cases.addCase(x: { 146 var tc = cases.create("callconv(.Stdcall, .Fastcall, .Thiscall) on unsupported platform", 147 \\export fn entry1() callconv(.Stdcall) void {} 148 \\export fn entry2() callconv(.Fastcall) void {} 149 \\export fn entry3() callconv(.Thiscall) void {} 150 , &[_][]const u8{ 151 "tmp.zig:1:29: error: callconv 'Stdcall' is only available on x86, not x86_64", 152 "tmp.zig:2:29: error: callconv 'Fastcall' is only available on x86, not x86_64", 153 "tmp.zig:3:29: error: callconv 'Thiscall' is only available on x86, not x86_64", 154 }); 155 tc.target = std.zig.CrossTarget{ 156 .cpu_arch = .x86_64, 157 .os_tag = .linux, 158 .abi = .none, 159 }; 160 break :x tc; 161 }); 162 163 cases.addCase(x: { 164 var tc = cases.create("callconv(.Vectorcall) on unsupported platform", 165 \\export fn entry() callconv(.Vectorcall) void {} 166 , &[_][]const u8{ 167 "tmp.zig:1:28: error: callconv 'Vectorcall' is only available on x86 and AArch64, not x86_64", 168 }); 169 tc.target = std.zig.CrossTarget{ 170 .cpu_arch = .x86_64, 171 .os_tag = .linux, 172 .abi = .none, 173 }; 174 break :x tc; 175 }); 176 177 cases.addCase(x: { 178 var tc = cases.create("callconv(.APCS, .AAPCS, .AAPCSVFP) on unsupported platform", 179 \\export fn entry1() callconv(.APCS) void {} 180 \\export fn entry2() callconv(.AAPCS) void {} 181 \\export fn entry3() callconv(.AAPCSVFP) void {} 182 , &[_][]const u8{ 183 "tmp.zig:1:29: error: callconv 'APCS' is only available on ARM, not x86_64", 184 "tmp.zig:2:29: error: callconv 'AAPCS' is only available on ARM, not x86_64", 185 "tmp.zig:3:29: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64", 186 }); 187 tc.target = std.zig.CrossTarget{ 188 .cpu_arch = .x86_64, 189 .os_tag = .linux, 190 .abi = .none, 191 }; 192 break :x tc; 193 }); 194 195 cases.add("unreachable executed at comptime", 196 \\fn foo(comptime x: i32) i32 { 197 \\ comptime { 198 \\ if (x >= 0) return -x; 199 \\ unreachable; 200 \\ } 201 \\} 202 \\export fn entry() void { 203 \\ _ = foo(-42); 204 \\} 205 , &[_][]const u8{ 206 "tmp.zig:4:9: error: reached unreachable code", 207 "tmp.zig:8:12: note: called from here", 208 }); 209 210 cases.add("@Type with TypeInfo.Int", 211 \\const builtin = @import("builtin"); 212 \\export fn entry() void { 213 \\ _ = @Type(builtin.TypeInfo.Int { 214 \\ .signedness = .signed, 215 \\ .bits = 8, 216 \\ }); 217 \\} 218 , &[_][]const u8{ 219 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'", 220 }); 221 222 cases.add("indexing a undefined slice at comptime", 223 \\comptime { 224 \\ var slice: []u8 = undefined; 225 \\ slice[0] = 2; 226 \\} 227 , &[_][]const u8{ 228 "tmp.zig:3:10: error: index 0 outside slice of size 0", 229 }); 230 231 cases.add("array in c exported function", 232 \\export fn zig_array(x: [10]u8) void { 233 \\ expect(std.mem.eql(u8, &x, "1234567890")); 234 \\} 235 \\ 236 \\export fn zig_return_array() [10]u8 { 237 \\ return "1234567890".*; 238 \\} 239 , &[_][]const u8{ 240 "tmp.zig:1:24: error: parameter of type '[10]u8' not allowed in function with calling convention 'C'", 241 "tmp.zig:5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'", 242 }); 243 244 cases.add("@Type for exhaustive enum with undefined tag type", 245 \\const TypeInfo = @import("builtin").TypeInfo; 246 \\const Tag = @Type(.{ 247 \\ .Enum = .{ 248 \\ .layout = .Auto, 249 \\ .tag_type = undefined, 250 \\ .fields = &[_]TypeInfo.EnumField{}, 251 \\ .decls = &[_]TypeInfo.Declaration{}, 252 \\ .is_exhaustive = false, 253 \\ }, 254 \\}); 255 \\export fn entry() void { 256 \\ _ = @intToEnum(Tag, 0); 257 \\} 258 , &[_][]const u8{ 259 "tmp.zig:2:20: error: use of undefined value here causes undefined behavior", 260 }); 261 262 cases.add("extern struct with non-extern-compatible integer tag type", 263 \\pub const E = enum(u31) { A, B, C }; 264 \\pub const S = extern struct { 265 \\ e: E, 266 \\}; 267 \\export fn entry() void { 268 \\ const s: S = undefined; 269 \\} 270 , &[_][]const u8{ 271 "tmp.zig:3:5: error: extern structs cannot contain fields of type 'E'", 272 }); 273 274 cases.add("@Type for exhaustive enum with non-integer tag type", 275 \\const TypeInfo = @import("builtin").TypeInfo; 276 \\const Tag = @Type(.{ 277 \\ .Enum = .{ 278 \\ .layout = .Auto, 279 \\ .tag_type = bool, 280 \\ .fields = &[_]TypeInfo.EnumField{}, 281 \\ .decls = &[_]TypeInfo.Declaration{}, 282 \\ .is_exhaustive = false, 283 \\ }, 284 \\}); 285 \\export fn entry() void { 286 \\ _ = @intToEnum(Tag, 0); 287 \\} 288 , &[_][]const u8{ 289 "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'", 290 }); 291 292 cases.add("extern struct with extern-compatible but inferred integer tag type", 293 \\pub const E = enum { 294 \\@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12", 295 \\@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23", 296 \\@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34", 297 \\@"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45", 298 \\@"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56", 299 \\@"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67", 300 \\@"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78", 301 \\@"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89", 302 \\@"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100", 303 \\@"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109", 304 \\@"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118", 305 \\@"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127", 306 \\@"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136", 307 \\@"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145", 308 \\@"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154", 309 \\@"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163", 310 \\@"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172", 311 \\@"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181", 312 \\@"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190", 313 \\@"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199", 314 \\@"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208", 315 \\@"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217", 316 \\@"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226", 317 \\@"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235", 318 \\@"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244", 319 \\@"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253", 320 \\@"254",@"255" 321 \\}; 322 \\pub const S = extern struct { 323 \\ e: E, 324 \\}; 325 \\export fn entry() void { 326 \\ if (@TagType(E) != u8) @compileError("did not infer u8 tag type"); 327 \\ const s: S = undefined; 328 \\} 329 , &[_][]const u8{ 330 "tmp.zig:31:5: error: extern structs cannot contain fields of type 'E'", 331 }); 332 333 cases.add("@Type for tagged union with extra enum field", 334 \\const TypeInfo = @import("builtin").TypeInfo; 335 \\const Tag = @Type(.{ 336 \\ .Enum = .{ 337 \\ .layout = .Auto, 338 \\ .tag_type = u2, 339 \\ .fields = &[_]TypeInfo.EnumField{ 340 \\ .{ .name = "signed", .value = 0 }, 341 \\ .{ .name = "unsigned", .value = 1 }, 342 \\ .{ .name = "arst", .value = 2 }, 343 \\ }, 344 \\ .decls = &[_]TypeInfo.Declaration{}, 345 \\ .is_exhaustive = true, 346 \\ }, 347 \\}); 348 \\const Tagged = @Type(.{ 349 \\ .Union = .{ 350 \\ .layout = .Auto, 351 \\ .tag_type = Tag, 352 \\ .fields = &[_]TypeInfo.UnionField{ 353 \\ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, 354 \\ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, 355 \\ }, 356 \\ .decls = &[_]TypeInfo.Declaration{}, 357 \\ }, 358 \\}); 359 \\export fn entry() void { 360 \\ var tagged = Tagged{ .signed = -1 }; 361 \\ tagged = .{ .unsigned = 1 }; 362 \\} 363 , &[_][]const u8{ 364 "tmp.zig:15:23: error: enum field missing: 'arst'", 365 "tmp.zig:27:24: note: referenced here", 366 }); 367 368 cases.add("field access of opaque type", 369 \\const MyType = opaque {}; 370 \\ 371 \\export fn entry() bool { 372 \\ var x: i32 = 1; 373 \\ return bar(@ptrCast(*MyType, &x)); 374 \\} 375 \\ 376 \\fn bar(x: *MyType) bool { 377 \\ return x.blah; 378 \\} 379 , &[_][]const u8{ 380 "tmp.zig:9:13: error: no member named 'blah' in opaque type 'MyType'", 381 }); 382 383 cases.add("opaque type with field", 384 \\const Opaque = opaque { foo: i32 }; 385 \\export fn entry() void { 386 \\ const foo: ?*Opaque = null; 387 \\} 388 , &[_][]const u8{ 389 "tmp.zig:1:25: error: opaque types cannot have fields", 390 }); 391 392 cases.add("@Type(.Fn) with is_generic = true", 393 \\const Foo = @Type(.{ 394 \\ .Fn = .{ 395 \\ .calling_convention = .Unspecified, 396 \\ .alignment = 0, 397 \\ .is_generic = true, 398 \\ .is_var_args = false, 399 \\ .return_type = u0, 400 \\ .args = &[_]@import("builtin").TypeInfo.FnArg{}, 401 \\ }, 402 \\}); 403 \\comptime { _ = Foo; } 404 , &[_][]const u8{ 405 "tmp.zig:1:20: error: TypeInfo.Fn.is_generic must be false for @Type", 406 }); 407 408 cases.add("@Type(.Fn) with is_var_args = true and non-C callconv", 409 \\const Foo = @Type(.{ 410 \\ .Fn = .{ 411 \\ .calling_convention = .Unspecified, 412 \\ .alignment = 0, 413 \\ .is_generic = false, 414 \\ .is_var_args = true, 415 \\ .return_type = u0, 416 \\ .args = &[_]@import("builtin").TypeInfo.FnArg{}, 417 \\ }, 418 \\}); 419 \\comptime { _ = Foo; } 420 , &[_][]const u8{ 421 "tmp.zig:1:20: error: varargs functions must have C calling convention", 422 }); 423 424 cases.add("@Type(.Fn) with return_type = null", 425 \\const Foo = @Type(.{ 426 \\ .Fn = .{ 427 \\ .calling_convention = .Unspecified, 428 \\ .alignment = 0, 429 \\ .is_generic = false, 430 \\ .is_var_args = false, 431 \\ .return_type = null, 432 \\ .args = &[_]@import("builtin").TypeInfo.FnArg{}, 433 \\ }, 434 \\}); 435 \\comptime { _ = Foo; } 436 , &[_][]const u8{ 437 "tmp.zig:1:20: error: TypeInfo.Fn.return_type must be non-null for @Type", 438 }); 439 440 cases.add("@Type for union with opaque field", 441 \\const TypeInfo = @import("builtin").TypeInfo; 442 \\const Untagged = @Type(.{ 443 \\ .Union = .{ 444 \\ .layout = .Auto, 445 \\ .tag_type = null, 446 \\ .fields = &[_]TypeInfo.UnionField{ 447 \\ .{ .name = "foo", .field_type = opaque {}, .alignment = 1 }, 448 \\ }, 449 \\ .decls = &[_]TypeInfo.Declaration{}, 450 \\ }, 451 \\}); 452 \\export fn entry() void { 453 \\ _ = Untagged{}; 454 \\} 455 , &[_][]const u8{ 456 "tmp.zig:2:25: error: opaque types have unknown size and therefore cannot be directly embedded in unions", 457 "tmp.zig:13:17: note: referenced here", 458 }); 459 460 cases.add("slice sentinel mismatch", 461 \\export fn entry() void { 462 \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 }; 463 \\} 464 , &[_][]const u8{ 465 "tmp.zig:2:62: error: index 3 outside vector of size 3", 466 }); 467 468 cases.add("slice sentinel mismatch", 469 \\export fn entry() void { 470 \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 }; 471 \\} 472 , &[_][]const u8{ 473 "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'", 474 }); 475 476 cases.add("@Type for union with zero fields", 477 \\const TypeInfo = @import("builtin").TypeInfo; 478 \\const Untagged = @Type(.{ 479 \\ .Union = .{ 480 \\ .layout = .Auto, 481 \\ .tag_type = null, 482 \\ .fields = &[_]TypeInfo.UnionField{}, 483 \\ .decls = &[_]TypeInfo.Declaration{}, 484 \\ }, 485 \\}); 486 \\export fn entry() void { 487 \\ _ = Untagged{}; 488 \\} 489 , &[_][]const u8{ 490 "tmp.zig:2:25: error: unions must have 1 or more fields", 491 "tmp.zig:11:17: note: referenced here", 492 }); 493 494 cases.add("@Type for exhaustive enum with zero fields", 495 \\const TypeInfo = @import("builtin").TypeInfo; 496 \\const Tag = @Type(.{ 497 \\ .Enum = .{ 498 \\ .layout = .Auto, 499 \\ .tag_type = u1, 500 \\ .fields = &[_]TypeInfo.EnumField{}, 501 \\ .decls = &[_]TypeInfo.Declaration{}, 502 \\ .is_exhaustive = true, 503 \\ }, 504 \\}); 505 \\export fn entry() void { 506 \\ _ = @intToEnum(Tag, 0); 507 \\} 508 , &[_][]const u8{ 509 "tmp.zig:2:20: error: enums must have 1 or more fields", 510 "tmp.zig:12:9: note: referenced here", 511 }); 512 513 cases.add("@Type for tagged union with extra union field", 514 \\const TypeInfo = @import("builtin").TypeInfo; 515 \\const Tag = @Type(.{ 516 \\ .Enum = .{ 517 \\ .layout = .Auto, 518 \\ .tag_type = u1, 519 \\ .fields = &[_]TypeInfo.EnumField{ 520 \\ .{ .name = "signed", .value = 0 }, 521 \\ .{ .name = "unsigned", .value = 1 }, 522 \\ }, 523 \\ .decls = &[_]TypeInfo.Declaration{}, 524 \\ .is_exhaustive = true, 525 \\ }, 526 \\}); 527 \\const Tagged = @Type(.{ 528 \\ .Union = .{ 529 \\ .layout = .Auto, 530 \\ .tag_type = Tag, 531 \\ .fields = &[_]TypeInfo.UnionField{ 532 \\ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, 533 \\ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, 534 \\ .{ .name = "arst", .field_type = f32, .alignment = @alignOf(f32) }, 535 \\ }, 536 \\ .decls = &[_]TypeInfo.Declaration{}, 537 \\ }, 538 \\}); 539 \\export fn entry() void { 540 \\ var tagged = Tagged{ .signed = -1 }; 541 \\ tagged = .{ .unsigned = 1 }; 542 \\} 543 , &[_][]const u8{ 544 "tmp.zig:14:23: error: enum field not found: 'arst'", 545 "tmp.zig:2:20: note: enum declared here", 546 "tmp.zig:27:24: note: referenced here", 547 }); 548 549 cases.add("@Type with undefined", 550 \\comptime { 551 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } }); 552 \\} 553 \\comptime { 554 \\ _ = @Type(.{ 555 \\ .Struct = .{ 556 \\ .fields = undefined, 557 \\ .decls = undefined, 558 \\ .is_tuple = false, 559 \\ .layout = .Auto, 560 \\ }, 561 \\ }); 562 \\} 563 , &[_][]const u8{ 564 "tmp.zig:2:16: error: use of undefined value here causes undefined behavior", 565 "tmp.zig:5:16: error: use of undefined value here causes undefined behavior", 566 }); 567 568 cases.add("struct with declarations unavailable for @Type", 569 \\export fn entry() void { 570 \\ _ = @Type(@typeInfo(struct { const foo = 1; })); 571 \\} 572 , &[_][]const u8{ 573 "tmp.zig:2:15: error: TypeInfo.Struct.decls must be empty for @Type", 574 }); 575 576 cases.add("enum with declarations unavailable for @Type", 577 \\export fn entry() void { 578 \\ _ = @Type(@typeInfo(enum { foo, const bar = 1; })); 579 \\} 580 , &[_][]const u8{ 581 "tmp.zig:2:15: error: TypeInfo.Enum.decls must be empty for @Type", 582 }); 583 584 cases.addTest("reject extern variables with initializers", 585 \\extern var foo: int = 2; 586 , &[_][]const u8{ 587 "tmp.zig:1:1: error: extern variables have no initializers", 588 }); 589 590 cases.addTest("duplicate/unused labels", 591 \\comptime { 592 \\ blk: { blk: while (false) {} } 593 \\ blk: while (false) { blk: for (@as([0]void, undefined)) |_| {} } 594 \\ blk: for (@as([0]void, undefined)) |_| { blk: {} } 595 \\} 596 \\comptime { 597 \\ blk: {} 598 \\ blk: while(false) {} 599 \\ blk: for(@as([0]void, undefined)) |_| {} 600 \\} 601 , &[_][]const u8{ 602 "tmp.zig:2:17: error: redeclaration of label 'blk'", 603 "tmp.zig:2:10: note: previous declaration is here", 604 "tmp.zig:3:31: error: redeclaration of label 'blk'", 605 "tmp.zig:3:10: note: previous declaration is here", 606 "tmp.zig:4:51: error: redeclaration of label 'blk'", 607 "tmp.zig:4:10: note: previous declaration is here", 608 "tmp.zig:7:10: error: unused block label", 609 "tmp.zig:8:10: error: unused while label", 610 "tmp.zig:9:10: error: unused for label", 611 }); 612 613 cases.addTest("@alignCast of zero sized types", 614 \\export fn foo() void { 615 \\ const a: *void = undefined; 616 \\ _ = @alignCast(2, a); 617 \\} 618 \\export fn bar() void { 619 \\ const a: ?*void = undefined; 620 \\ _ = @alignCast(2, a); 621 \\} 622 \\export fn baz() void { 623 \\ const a: []void = undefined; 624 \\ _ = @alignCast(2, a); 625 \\} 626 \\export fn qux() void { 627 \\ const a = struct { 628 \\ fn a(comptime b: u32) void {} 629 \\ }.a; 630 \\ _ = @alignCast(2, a); 631 \\} 632 , &[_][]const u8{ 633 "tmp.zig:3:23: error: cannot adjust alignment of zero sized type '*void'", 634 "tmp.zig:7:23: error: cannot adjust alignment of zero sized type '?*void'", 635 "tmp.zig:11:23: error: cannot adjust alignment of zero sized type '[]void'", 636 "tmp.zig:17:23: error: cannot adjust alignment of zero sized type 'fn(u32) anytype'", 637 }); 638 639 cases.addTest("invalid non-exhaustive enum to union", 640 \\const E = enum(u8) { 641 \\ a, 642 \\ b, 643 \\ _, 644 \\}; 645 \\const U = union(E) { 646 \\ a, 647 \\ b, 648 \\}; 649 \\export fn foo() void { 650 \\ var e = @intToEnum(E, 15); 651 \\ var u: U = e; 652 \\} 653 \\export fn bar() void { 654 \\ const e = @intToEnum(E, 15); 655 \\ var u: U = e; 656 \\} 657 , &[_][]const u8{ 658 "tmp.zig:12:16: error: runtime cast to union 'U' from non-exhustive enum", 659 "tmp.zig:16:16: error: no tag by value 15", 660 }); 661 662 cases.addTest("switching with exhaustive enum has '_' prong ", 663 \\const E = enum{ 664 \\ a, 665 \\ b, 666 \\}; 667 \\pub export fn entry() void { 668 \\ var e: E = .b; 669 \\ switch (e) { 670 \\ .a => {}, 671 \\ .b => {}, 672 \\ _ => {}, 673 \\ } 674 \\} 675 , &[_][]const u8{ 676 "tmp.zig:7:5: error: switch on exhaustive enum has `_` prong", 677 }); 678 679 cases.addTest("invalid pointer with @Type", 680 \\export fn entry() void { 681 \\ _ = @Type(.{ .Pointer = .{ 682 \\ .size = .One, 683 \\ .is_const = false, 684 \\ .is_volatile = false, 685 \\ .alignment = 1, 686 \\ .child = u8, 687 \\ .is_allowzero = false, 688 \\ .sentinel = 0, 689 \\ }}); 690 \\} 691 , &[_][]const u8{ 692 "tmp.zig:2:16: error: sentinels are only allowed on slices and unknown-length pointers", 693 }); 694 695 cases.addTest("helpful return type error message", 696 \\export fn foo() u32 { 697 \\ return error.Ohno; 698 \\} 699 \\fn bar() !u32 { 700 \\ return error.Ohno; 701 \\} 702 \\export fn baz() void { 703 \\ try bar(); 704 \\} 705 \\export fn qux() u32 { 706 \\ return bar(); 707 \\} 708 \\export fn quux() u32 { 709 \\ var buf: u32 = 0; 710 \\ buf = bar(); 711 \\} 712 , &[_][]const u8{ 713 "tmp.zig:2:17: error: expected type 'u32', found 'error{Ohno}'", 714 "tmp.zig:1:17: note: function cannot return an error", 715 "tmp.zig:8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set'", 716 "tmp.zig:7:17: note: function cannot return an error", 717 "tmp.zig:11:15: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'", 718 "tmp.zig:10:17: note: function cannot return an error", 719 "tmp.zig:15:14: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'", 720 "tmp.zig:14:5: note: cannot store an error in type 'u32'", 721 }); 722 723 cases.addTest("int/float conversion to comptime_int/float", 724 \\export fn foo() void { 725 \\ var a: f32 = 2; 726 \\ _ = @floatToInt(comptime_int, a); 727 \\} 728 \\export fn bar() void { 729 \\ var a: u32 = 2; 730 \\ _ = @intToFloat(comptime_float, a); 731 \\} 732 , &[_][]const u8{ 733 "tmp.zig:3:35: error: unable to evaluate constant expression", 734 "tmp.zig:3:9: note: referenced here", 735 "tmp.zig:7:37: error: unable to evaluate constant expression", 736 "tmp.zig:7:9: note: referenced here", 737 }); 738 739 cases.add("extern variable has no type", 740 \\extern var foo; 741 \\pub export fn entry() void { 742 \\ foo; 743 \\} 744 , &[_][]const u8{ 745 "tmp.zig:1:1: error: unable to infer variable type", 746 }); 747 748 cases.add("@src outside function", 749 \\comptime { 750 \\ @src(); 751 \\} 752 , &[_][]const u8{ 753 "tmp.zig:2:5: error: @src outside function", 754 }); 755 756 cases.add("call assigned to constant", 757 \\const Foo = struct { 758 \\ x: i32, 759 \\}; 760 \\fn foo() Foo { 761 \\ return .{ .x = 42 }; 762 \\} 763 \\fn bar(val: anytype) Foo { 764 \\ return .{ .x = val }; 765 \\} 766 \\export fn entry() void { 767 \\ const baz: Foo = undefined; 768 \\ baz = foo(); 769 \\} 770 \\export fn entry1() void { 771 \\ const baz: Foo = undefined; 772 \\ baz = bar(42); 773 \\} 774 , &[_][]const u8{ 775 "tmp.zig:12:14: error: cannot assign to constant", 776 "tmp.zig:16:14: error: cannot assign to constant", 777 }); 778 779 cases.add("invalid pointer syntax", 780 \\export fn foo() void { 781 \\ var guid: *:0 const u8 = undefined; 782 \\} 783 , &[_][]const u8{ 784 "tmp.zig:2:15: error: sentinels are only allowed on unknown-length pointers", 785 }); 786 787 cases.add("declaration between fields", 788 \\const S = struct { 789 \\ const foo = 2; 790 \\ const bar = 2; 791 \\ const baz = 2; 792 \\ a: usize, 793 \\ const foo1 = 2; 794 \\ const bar1 = 2; 795 \\ const baz1 = 2; 796 \\ b: usize, 797 \\}; 798 \\comptime { 799 \\ _ = S; 800 \\} 801 , &[_][]const u8{ 802 "tmp.zig:6:5: error: declarations are not allowed between container fields", 803 }); 804 805 cases.add("non-extern function with var args", 806 \\fn foo(args: ...) void {} 807 \\export fn entry() void { 808 \\ foo(); 809 \\} 810 , &[_][]const u8{ 811 "tmp.zig:1:1: error: non-extern function is variadic", 812 }); 813 814 cases.addTest("invalid int casts", 815 \\export fn foo() void { 816 \\ var a: u32 = 2; 817 \\ _ = @intCast(comptime_int, a); 818 \\} 819 \\export fn bar() void { 820 \\ var a: u32 = 2; 821 \\ _ = @intToFloat(u32, a); 822 \\} 823 \\export fn baz() void { 824 \\ var a: u32 = 2; 825 \\ _ = @floatToInt(u32, a); 826 \\} 827 \\export fn qux() void { 828 \\ var a: f32 = 2; 829 \\ _ = @intCast(u32, a); 830 \\} 831 , &[_][]const u8{ 832 "tmp.zig:3:32: error: unable to evaluate constant expression", 833 "tmp.zig:3:9: note: referenced here", 834 "tmp.zig:7:21: error: expected float type, found 'u32'", 835 "tmp.zig:7:9: note: referenced here", 836 "tmp.zig:11:26: error: expected float type, found 'u32'", 837 "tmp.zig:11:9: note: referenced here", 838 "tmp.zig:15:23: error: expected integer type, found 'f32'", 839 "tmp.zig:15:9: note: referenced here", 840 }); 841 842 cases.addTest("invalid float casts", 843 \\export fn foo() void { 844 \\ var a: f32 = 2; 845 \\ _ = @floatCast(comptime_float, a); 846 \\} 847 \\export fn bar() void { 848 \\ var a: f32 = 2; 849 \\ _ = @floatToInt(f32, a); 850 \\} 851 \\export fn baz() void { 852 \\ var a: f32 = 2; 853 \\ _ = @intToFloat(f32, a); 854 \\} 855 \\export fn qux() void { 856 \\ var a: u32 = 2; 857 \\ _ = @floatCast(f32, a); 858 \\} 859 , &[_][]const u8{ 860 "tmp.zig:3:36: error: unable to evaluate constant expression", 861 "tmp.zig:3:9: note: referenced here", 862 "tmp.zig:7:21: error: expected integer type, found 'f32'", 863 "tmp.zig:7:9: note: referenced here", 864 "tmp.zig:11:26: error: expected int type, found 'f32'", 865 "tmp.zig:11:9: note: referenced here", 866 "tmp.zig:15:25: error: expected float type, found 'u32'", 867 "tmp.zig:15:9: note: referenced here", 868 }); 869 870 cases.addTest("invalid assignments", 871 \\export fn entry1() void { 872 \\ var a: []const u8 = "foo"; 873 \\ a[0..2] = "bar"; 874 \\} 875 \\export fn entry2() void { 876 \\ var a: u8 = 2; 877 \\ a + 2 = 3; 878 \\} 879 \\export fn entry4() void { 880 \\ 2 + 2 = 3; 881 \\} 882 , &[_][]const u8{ 883 "tmp.zig:3:6: error: invalid left-hand side to assignment", 884 "tmp.zig:7:7: error: invalid left-hand side to assignment", 885 "tmp.zig:10:7: error: invalid left-hand side to assignment", 886 }); 887 888 cases.addTest("reassign to array parameter", 889 \\fn reassign(a: [3]f32) void { 890 \\ a = [3]f32{4, 5, 6}; 891 \\} 892 \\export fn entry() void { 893 \\ reassign(.{1, 2, 3}); 894 \\} 895 , &[_][]const u8{ 896 "tmp.zig:2:15: error: cannot assign to constant", 897 }); 898 899 cases.addTest("reassign to slice parameter", 900 \\pub fn reassign(s: []const u8) void { 901 \\ s = s[0..]; 902 \\} 903 \\export fn entry() void { 904 \\ reassign("foo"); 905 \\} 906 , &[_][]const u8{ 907 "tmp.zig:2:10: error: cannot assign to constant", 908 }); 909 910 cases.addTest("reassign to struct parameter", 911 \\const S = struct { 912 \\ x: u32, 913 \\}; 914 \\fn reassign(s: S) void { 915 \\ s = S{.x = 2}; 916 \\} 917 \\export fn entry() void { 918 \\ reassign(S{.x = 3}); 919 \\} 920 , &[_][]const u8{ 921 "tmp.zig:5:10: error: cannot assign to constant", 922 }); 923 924 cases.addTest("reference to const data", 925 \\export fn foo() void { 926 \\ var ptr = &[_]u8{0,0,0,0}; 927 \\ ptr[1] = 2; 928 \\} 929 \\export fn bar() void { 930 \\ var ptr = &@as(u32, 2); 931 \\ ptr.* = 2; 932 \\} 933 \\export fn baz() void { 934 \\ var ptr = &true; 935 \\ ptr.* = false; 936 \\} 937 \\export fn qux() void { 938 \\ const S = struct{ 939 \\ x: usize, 940 \\ y: usize, 941 \\ }; 942 \\ var ptr = &S{.x=1,.y=2}; 943 \\ ptr.x = 2; 944 \\} 945 , &[_][]const u8{ 946 "tmp.zig:3:14: error: cannot assign to constant", 947 "tmp.zig:7:13: error: cannot assign to constant", 948 "tmp.zig:11:13: error: cannot assign to constant", 949 "tmp.zig:19:13: error: cannot assign to constant", 950 }); 951 952 cases.addTest("cast between ?T where T is not a pointer", 953 \\pub const fnty1 = ?fn (i8) void; 954 \\pub const fnty2 = ?fn (u64) void; 955 \\export fn entry() void { 956 \\ var a: fnty1 = undefined; 957 \\ var b: fnty2 = undefined; 958 \\ a = b; 959 \\} 960 , &[_][]const u8{ 961 "tmp.zig:6:9: error: expected type '?fn(i8) void', found '?fn(u64) void'", 962 "tmp.zig:6:9: note: optional type child 'fn(u64) void' cannot cast into optional type child 'fn(i8) void'", 963 }); 964 965 cases.addTest("unused variable error on errdefer", 966 \\fn foo() !void { 967 \\ errdefer |a| unreachable; 968 \\ return error.A; 969 \\} 970 \\export fn entry() void { 971 \\ foo() catch unreachable; 972 \\} 973 , &[_][]const u8{ 974 "tmp.zig:2:15: error: unused variable: 'a'", 975 }); 976 977 cases.addTest("comparison of non-tagged union and enum literal", 978 \\export fn entry() void { 979 \\ const U = union { A: u32, B: u64 }; 980 \\ var u = U{ .A = 42 }; 981 \\ var ok = u == .A; 982 \\} 983 , &[_][]const u8{ 984 "tmp.zig:4:16: error: comparison of union and enum literal is only valid for tagged union types", 985 "tmp.zig:2:15: note: type U is not a tagged union", 986 }); 987 988 cases.addTest("shift on type with non-power-of-two size", 989 \\export fn entry() void { 990 \\ const S = struct { 991 \\ fn a() void { 992 \\ var x: u24 = 42; 993 \\ _ = x >> 24; 994 \\ } 995 \\ fn b() void { 996 \\ var x: u24 = 42; 997 \\ _ = x << 24; 998 \\ } 999 \\ fn c() void { 1000 \\ var x: u24 = 42; 1001 \\ _ = @shlExact(x, 24); 1002 \\ } 1003 \\ fn d() void { 1004 \\ var x: u24 = 42; 1005 \\ _ = @shrExact(x, 24); 1006 \\ } 1007 \\ }; 1008 \\ S.a(); 1009 \\ S.b(); 1010 \\ S.c(); 1011 \\ S.d(); 1012 \\} 1013 , &[_][]const u8{ 1014 "tmp.zig:5:19: error: RHS of shift is too large for LHS type", 1015 "tmp.zig:9:19: error: RHS of shift is too large for LHS type", 1016 "tmp.zig:13:17: error: RHS of shift is too large for LHS type", 1017 "tmp.zig:17:17: error: RHS of shift is too large for LHS type", 1018 }); 1019 1020 cases.addTest("combination of nosuspend and async", 1021 \\export fn entry() void { 1022 \\ nosuspend { 1023 \\ const bar = async foo(); 1024 \\ suspend; 1025 \\ resume bar; 1026 \\ } 1027 \\} 1028 \\fn foo() void {} 1029 , &[_][]const u8{ 1030 "tmp.zig:3:21: error: async call in nosuspend scope", 1031 "tmp.zig:4:9: error: suspend in nosuspend scope", 1032 "tmp.zig:5:9: error: resume in nosuspend scope", 1033 }); 1034 1035 cases.add("atomicrmw with bool op not .Xchg", 1036 \\export fn entry() void { 1037 \\ var x = false; 1038 \\ _ = @atomicRmw(bool, &x, .Add, true, .SeqCst); 1039 \\} 1040 , &[_][]const u8{ 1041 "tmp.zig:3:30: error: @atomicRmw with bool only allowed with .Xchg", 1042 }); 1043 1044 cases.addTest("@TypeOf with no arguments", 1045 \\export fn entry() void { 1046 \\ _ = @TypeOf(); 1047 \\} 1048 , &[_][]const u8{ 1049 "tmp.zig:2:9: error: expected at least 1 argument, found 0", 1050 }); 1051 1052 cases.addTest("@TypeOf with incompatible arguments", 1053 \\export fn entry() void { 1054 \\ var var_1: f32 = undefined; 1055 \\ var var_2: u32 = undefined; 1056 \\ _ = @TypeOf(var_1, var_2); 1057 \\} 1058 , &[_][]const u8{ 1059 "tmp.zig:4:9: error: incompatible types: 'f32' and 'u32'", 1060 }); 1061 1062 cases.addTest("type mismatch with tuple concatenation", 1063 \\export fn entry() void { 1064 \\ var x = .{}; 1065 \\ x = x ++ .{ 1, 2, 3 }; 1066 \\} 1067 , &[_][]const u8{ 1068 "tmp.zig:3:11: error: expected type 'struct:2:14', found 'struct:3:11'", 1069 }); 1070 1071 cases.addTest("@tagName on invalid value of non-exhaustive enum", 1072 \\test "enum" { 1073 \\ const E = enum(u8) {A, B, _}; 1074 \\ _ = @tagName(@intToEnum(E, 5)); 1075 \\} 1076 , &[_][]const u8{ 1077 "tmp.zig:3:18: error: no tag by value 5", 1078 }); 1079 1080 cases.addTest("@ptrToInt with pointer to zero-sized type", 1081 \\export fn entry() void { 1082 \\ var pointer: ?*u0 = null; 1083 \\ var x = @ptrToInt(pointer); 1084 \\} 1085 , &[_][]const u8{ 1086 "tmp.zig:3:23: error: pointer to size 0 type has no address", 1087 }); 1088 1089 cases.addTest("access invalid @typeInfo decl", 1090 \\const A = B; 1091 \\test "Crash" { 1092 \\ _ = @typeInfo(@This()).Struct.decls[0]; 1093 \\} 1094 , &[_][]const u8{ 1095 "tmp.zig:1:11: error: use of undeclared identifier 'B'", 1096 }); 1097 1098 cases.addTest("reject extern function definitions with body", 1099 \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 { 1100 \\ return a + b; 1101 \\} 1102 , &[_][]const u8{ 1103 "tmp.zig:1:1: error: extern functions have no body", 1104 }); 1105 1106 cases.addTest("duplicate field in anonymous struct literal", 1107 \\export fn entry() void { 1108 \\ const anon = .{ 1109 \\ .inner = .{ 1110 \\ .a = .{ 1111 \\ .something = "text", 1112 \\ }, 1113 \\ .a = .{}, 1114 \\ }, 1115 \\ }; 1116 \\} 1117 , &[_][]const u8{ 1118 "tmp.zig:7:13: error: duplicate field", 1119 "tmp.zig:4:13: note: other field here", 1120 }); 1121 1122 cases.addTest("type mismatch in C prototype with varargs", 1123 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void; 1124 \\extern fn fn_decl(fmt: [*:0]u8, ...) void; 1125 \\ 1126 \\export fn main() void { 1127 \\ const x: fn_ty = fn_decl; 1128 \\} 1129 , &[_][]const u8{ 1130 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'", 1131 }); 1132 1133 cases.addTest("dependency loop in top-level decl with @TypeInfo when accessing the decls", 1134 \\export const foo = @typeInfo(@This()).Struct.decls; 1135 , &[_][]const u8{ 1136 "tmp.zig:1:20: error: dependency loop detected", 1137 "tmp.zig:1:45: note: referenced here", 1138 }); 1139 1140 cases.add("function call assigned to incorrect type", 1141 \\export fn entry() void { 1142 \\ var arr: [4]f32 = undefined; 1143 \\ arr = concat(); 1144 \\} 1145 \\fn concat() [16]f32 { 1146 \\ return [1]f32{0}**16; 1147 \\} 1148 , &[_][]const u8{ 1149 "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'", 1150 }); 1151 1152 cases.add("generic function call assigned to incorrect type", 1153 \\pub export fn entry() void { 1154 \\ var res: []i32 = undefined; 1155 \\ res = myAlloc(i32); 1156 \\} 1157 \\fn myAlloc(comptime arg: type) anyerror!arg{ 1158 \\ unreachable; 1159 \\} 1160 , &[_][]const u8{ 1161 "tmp.zig:3:18: error: expected type '[]i32', found 'anyerror!i32", 1162 }); 1163 1164 cases.addTest("non-exhaustive enums", 1165 \\const A = enum { 1166 \\ a, 1167 \\ b, 1168 \\ _ = 1, 1169 \\}; 1170 \\const B = enum(u1) { 1171 \\ a, 1172 \\ _, 1173 \\ b, 1174 \\}; 1175 \\const C = enum(u1) { 1176 \\ a, 1177 \\ b, 1178 \\ _, 1179 \\}; 1180 \\pub export fn entry() void { 1181 \\ _ = A; 1182 \\ _ = B; 1183 \\ _ = C; 1184 \\} 1185 , &[_][]const u8{ 1186 "tmp.zig:4:5: error: value assigned to '_' field of non-exhaustive enum", 1187 "error: non-exhaustive enum must specify size", 1188 "error: non-exhaustive enum specifies every value", 1189 "error: '_' field of non-exhaustive enum must be last", 1190 }); 1191 1192 cases.addTest("switching with non-exhaustive enums", 1193 \\const E = enum(u8) { 1194 \\ a, 1195 \\ b, 1196 \\ _, 1197 \\}; 1198 \\const U = union(E) { 1199 \\ a: i32, 1200 \\ b: u32, 1201 \\}; 1202 \\pub export fn entry() void { 1203 \\ var e: E = .b; 1204 \\ switch (e) { // error: switch not handling the tag `b` 1205 \\ .a => {}, 1206 \\ _ => {}, 1207 \\ } 1208 \\ switch (e) { // error: switch on non-exhaustive enum must include `else` or `_` prong 1209 \\ .a => {}, 1210 \\ .b => {}, 1211 \\ } 1212 \\ var u = U{.a = 2}; 1213 \\ switch (u) { // error: `_` prong not allowed when switching on tagged union 1214 \\ .a => {}, 1215 \\ .b => {}, 1216 \\ _ => {}, 1217 \\ } 1218 \\} 1219 , &[_][]const u8{ 1220 "tmp.zig:12:5: error: enumeration value 'E.b' not handled in switch", 1221 "tmp.zig:16:5: error: switch on non-exhaustive enum must include `else` or `_` prong", 1222 "tmp.zig:21:5: error: `_` prong not allowed when switching on tagged union", 1223 }); 1224 1225 cases.add("switch expression - unreachable else prong (bool)", 1226 \\fn foo(x: bool) void { 1227 \\ switch (x) { 1228 \\ true => {}, 1229 \\ false => {}, 1230 \\ else => {}, 1231 \\ } 1232 \\} 1233 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 1234 , &[_][]const u8{ 1235 "tmp.zig:5:9: error: unreachable else prong, all cases already handled", 1236 }); 1237 1238 cases.add("switch expression - unreachable else prong (u1)", 1239 \\fn foo(x: u1) void { 1240 \\ switch (x) { 1241 \\ 0 => {}, 1242 \\ 1 => {}, 1243 \\ else => {}, 1244 \\ } 1245 \\} 1246 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 1247 , &[_][]const u8{ 1248 "tmp.zig:5:9: error: unreachable else prong, all cases already handled", 1249 }); 1250 1251 cases.add("switch expression - unreachable else prong (u2)", 1252 \\fn foo(x: u2) void { 1253 \\ switch (x) { 1254 \\ 0 => {}, 1255 \\ 1 => {}, 1256 \\ 2 => {}, 1257 \\ 3 => {}, 1258 \\ else => {}, 1259 \\ } 1260 \\} 1261 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 1262 , &[_][]const u8{ 1263 "tmp.zig:7:9: error: unreachable else prong, all cases already handled", 1264 }); 1265 1266 cases.add("switch expression - unreachable else prong (range u8)", 1267 \\fn foo(x: u8) void { 1268 \\ switch (x) { 1269 \\ 0 => {}, 1270 \\ 1 => {}, 1271 \\ 2 => {}, 1272 \\ 3 => {}, 1273 \\ 4...255 => {}, 1274 \\ else => {}, 1275 \\ } 1276 \\} 1277 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 1278 , &[_][]const u8{ 1279 "tmp.zig:8:9: error: unreachable else prong, all cases already handled", 1280 }); 1281 1282 cases.add("switch expression - unreachable else prong (range i8)", 1283 \\fn foo(x: i8) void { 1284 \\ switch (x) { 1285 \\ -128...0 => {}, 1286 \\ 1 => {}, 1287 \\ 2 => {}, 1288 \\ 3 => {}, 1289 \\ 4...127 => {}, 1290 \\ else => {}, 1291 \\ } 1292 \\} 1293 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 1294 , &[_][]const u8{ 1295 "tmp.zig:8:9: error: unreachable else prong, all cases already handled", 1296 }); 1297 1298 cases.add("switch expression - unreachable else prong (enum)", 1299 \\const TestEnum = enum{ T1, T2 }; 1300 \\ 1301 \\fn err(x: u8) TestEnum { 1302 \\ switch (x) { 1303 \\ 0 => return TestEnum.T1, 1304 \\ else => return TestEnum.T2, 1305 \\ } 1306 \\} 1307 \\ 1308 \\fn foo(x: u8) void { 1309 \\ switch (err(x)) { 1310 \\ TestEnum.T1 => {}, 1311 \\ TestEnum.T2 => {}, 1312 \\ else => {}, 1313 \\ } 1314 \\} 1315 \\ 1316 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 1317 , &[_][]const u8{ 1318 "tmp.zig:14:9: error: unreachable else prong, all cases already handled", 1319 }); 1320 1321 cases.addTest("@export with empty name string", 1322 \\pub export fn entry() void { } 1323 \\comptime { 1324 \\ @export(entry, .{ .name = "" }); 1325 \\} 1326 , &[_][]const u8{ 1327 "tmp.zig:3:5: error: exported symbol name cannot be empty", 1328 }); 1329 1330 cases.addTest("switch ranges endpoints are validated", 1331 \\pub export fn entry() void { 1332 \\ var x: i32 = 0; 1333 \\ switch (x) { 1334 \\ 6...1 => {}, 1335 \\ -1...-5 => {}, 1336 \\ else => unreachable, 1337 \\ } 1338 \\} 1339 , &[_][]const u8{ 1340 "tmp.zig:4:9: error: range start value is greater than the end value", 1341 "tmp.zig:5:9: error: range start value is greater than the end value", 1342 }); 1343 1344 cases.addTest("errors in for loop bodies are propagated", 1345 \\pub export fn entry() void { 1346 \\ var arr: [100]u8 = undefined; 1347 \\ for (arr) |bits| _ = @popCount(bits); 1348 \\} 1349 , &[_][]const u8{ 1350 "tmp.zig:3:26: error: expected 2 argument(s), found 1", 1351 }); 1352 1353 cases.addTest("@call rejects non comptime-known fn - always_inline", 1354 \\pub export fn entry() void { 1355 \\ var call_me: fn () void = undefined; 1356 \\ @call(.{ .modifier = .always_inline }, call_me, .{}); 1357 \\} 1358 , &[_][]const u8{ 1359 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function", 1360 }); 1361 1362 cases.addTest("@call rejects non comptime-known fn - compile_time", 1363 \\pub export fn entry() void { 1364 \\ var call_me: fn () void = undefined; 1365 \\ @call(.{ .modifier = .compile_time }, call_me, .{}); 1366 \\} 1367 , &[_][]const u8{ 1368 "tmp.zig:3:5: error: the specified modifier requires a comptime-known function", 1369 }); 1370 1371 cases.addTest("error in struct initializer doesn't crash the compiler", 1372 \\pub export fn entry() void { 1373 \\ const bitfield = struct { 1374 \\ e: u8, 1375 \\ e: u8, 1376 \\ }; 1377 \\ var a = .{@sizeOf(bitfield)}; 1378 \\} 1379 , &[_][]const u8{ 1380 "tmp.zig:4:9: error: duplicate struct field: 'e'", 1381 }); 1382 1383 cases.addTest("repeated invalid field access to generic function returning type crashes compiler. #2655", 1384 \\pub fn A() type { 1385 \\ return Q; 1386 \\} 1387 \\test "1" { 1388 \\ _ = A().a; 1389 \\ _ = A().a; 1390 \\} 1391 , &[_][]const u8{ 1392 "tmp.zig:2:12: error: use of undeclared identifier 'Q'", 1393 }); 1394 1395 cases.add("bitCast to enum type", 1396 \\export fn entry() void { 1397 \\ const y = @bitCast(enum(u32) { a, b }, @as(u32, 3)); 1398 \\} 1399 , &[_][]const u8{ 1400 "tmp.zig:2:24: error: cannot cast a value of type 'y'", 1401 }); 1402 1403 cases.add("comparing against undefined produces undefined value", 1404 \\export fn entry() void { 1405 \\ if (2 == undefined) {} 1406 \\} 1407 , &[_][]const u8{ 1408 "tmp.zig:2:11: error: use of undefined value here causes undefined behavior", 1409 }); 1410 1411 cases.add("comptime ptrcast of zero-sized type", 1412 \\fn foo() void { 1413 \\ const node: struct {} = undefined; 1414 \\ const vla_ptr = @ptrCast([*]const u8, &node); 1415 \\} 1416 \\comptime { foo(); } 1417 , &[_][]const u8{ 1418 "tmp.zig:3:21: error: '*const struct:2:17' and '[*]const u8' do not have the same in-memory representation", 1419 }); 1420 1421 cases.add("slice sentinel mismatch", 1422 \\fn foo() [:0]u8 { 1423 \\ var x: []u8 = undefined; 1424 \\ return x; 1425 \\} 1426 \\comptime { _ = foo; } 1427 , &[_][]const u8{ 1428 "tmp.zig:3:12: error: expected type '[:0]u8', found '[]u8'", 1429 "tmp.zig:3:12: note: destination pointer requires a terminating '0' sentinel", 1430 }); 1431 1432 cases.add("cmpxchg with float", 1433 \\export fn entry() void { 1434 \\ var x: f32 = 0; 1435 \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst); 1436 \\} 1437 , &[_][]const u8{ 1438 "tmp.zig:3:22: error: expected bool, integer, enum or pointer type, found 'f32'", 1439 }); 1440 1441 cases.add("atomicrmw with float op not .Xchg, .Add or .Sub", 1442 \\export fn entry() void { 1443 \\ var x: f32 = 0; 1444 \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst); 1445 \\} 1446 , &[_][]const u8{ 1447 "tmp.zig:3:29: error: @atomicRmw with float only allowed with .Xchg, .Add and .Sub", 1448 }); 1449 1450 cases.add("intToPtr with misaligned address", 1451 \\pub fn main() void { 1452 \\ var y = @intToPtr([*]align(4) u8, 5); 1453 \\} 1454 , &[_][]const u8{ 1455 "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address", 1456 }); 1457 1458 cases.add("invalid float literal", 1459 \\const std = @import("std"); 1460 \\ 1461 \\pub fn main() void { 1462 \\ var bad_float :f32 = 0.0; 1463 \\ bad_float = bad_float + .20; 1464 \\ std.debug.assert(bad_float < 1.0); 1465 \\} 1466 , &[_][]const u8{ 1467 "tmp.zig:5:29: error: invalid token: '.'", 1468 }); 1469 1470 cases.add("invalid exponent in float literal - 1", 1471 \\fn main() void { 1472 \\ var bad: f128 = 0x1.0p1ab1; 1473 \\} 1474 , &[_][]const u8{ 1475 "tmp.zig:2:28: error: invalid character: 'a'", 1476 }); 1477 1478 cases.add("invalid exponent in float literal - 2", 1479 \\fn main() void { 1480 \\ var bad: f128 = 0x1.0p50F; 1481 \\} 1482 , &[_][]const u8{ 1483 "tmp.zig:2:29: error: invalid character: 'F'", 1484 }); 1485 1486 cases.add("invalid underscore placement in float literal - 1", 1487 \\fn main() void { 1488 \\ var bad: f128 = 0._0; 1489 \\} 1490 , &[_][]const u8{ 1491 "tmp.zig:2:23: error: invalid character: '_'", 1492 }); 1493 1494 cases.add("invalid underscore placement in float literal - 2", 1495 \\fn main() void { 1496 \\ var bad: f128 = 0_.0; 1497 \\} 1498 , &[_][]const u8{ 1499 "tmp.zig:2:23: error: invalid character: '.'", 1500 }); 1501 1502 cases.add("invalid underscore placement in float literal - 3", 1503 \\fn main() void { 1504 \\ var bad: f128 = 0.0_; 1505 \\} 1506 , &[_][]const u8{ 1507 "tmp.zig:2:25: error: invalid character: ';'", 1508 }); 1509 1510 cases.add("invalid underscore placement in float literal - 4", 1511 \\fn main() void { 1512 \\ var bad: f128 = 1.0e_1; 1513 \\} 1514 , &[_][]const u8{ 1515 "tmp.zig:2:25: error: invalid character: '_'", 1516 }); 1517 1518 cases.add("invalid underscore placement in float literal - 5", 1519 \\fn main() void { 1520 \\ var bad: f128 = 1.0e+_1; 1521 \\} 1522 , &[_][]const u8{ 1523 "tmp.zig:2:26: error: invalid character: '_'", 1524 }); 1525 1526 cases.add("invalid underscore placement in float literal - 6", 1527 \\fn main() void { 1528 \\ var bad: f128 = 1.0e-_1; 1529 \\} 1530 , &[_][]const u8{ 1531 "tmp.zig:2:26: error: invalid character: '_'", 1532 }); 1533 1534 cases.add("invalid underscore placement in float literal - 7", 1535 \\fn main() void { 1536 \\ var bad: f128 = 1.0e-1_; 1537 \\} 1538 , &[_][]const u8{ 1539 "tmp.zig:2:28: error: invalid character: ';'", 1540 }); 1541 1542 cases.add("invalid underscore placement in float literal - 9", 1543 \\fn main() void { 1544 \\ var bad: f128 = 1__0.0e-1; 1545 \\} 1546 , &[_][]const u8{ 1547 "tmp.zig:2:23: error: invalid character: '_'", 1548 }); 1549 1550 cases.add("invalid underscore placement in float literal - 10", 1551 \\fn main() void { 1552 \\ var bad: f128 = 1.0__0e-1; 1553 \\} 1554 , &[_][]const u8{ 1555 "tmp.zig:2:25: error: invalid character: '_'", 1556 }); 1557 1558 cases.add("invalid underscore placement in float literal - 11", 1559 \\fn main() void { 1560 \\ var bad: f128 = 1.0e-1__0; 1561 \\} 1562 , &[_][]const u8{ 1563 "tmp.zig:2:28: error: invalid character: '_'", 1564 }); 1565 1566 cases.add("invalid underscore placement in float literal - 12", 1567 \\fn main() void { 1568 \\ var bad: f128 = 0_x0.0; 1569 \\} 1570 , &[_][]const u8{ 1571 "tmp.zig:2:23: error: invalid character: 'x'", 1572 }); 1573 1574 cases.add("invalid underscore placement in float literal - 13", 1575 \\fn main() void { 1576 \\ var bad: f128 = 0x_0.0; 1577 \\} 1578 , &[_][]const u8{ 1579 "tmp.zig:2:23: error: invalid character: '_'", 1580 }); 1581 1582 cases.add("invalid underscore placement in float literal - 14", 1583 \\fn main() void { 1584 \\ var bad: f128 = 0x0.0_p1; 1585 \\} 1586 , &[_][]const u8{ 1587 "tmp.zig:2:27: error: invalid character: 'p'", 1588 }); 1589 1590 cases.add("invalid underscore placement in int literal - 1", 1591 \\fn main() void { 1592 \\ var bad: u128 = 0010_; 1593 \\} 1594 , &[_][]const u8{ 1595 "tmp.zig:2:26: error: invalid character: ';'", 1596 }); 1597 1598 cases.add("invalid underscore placement in int literal - 2", 1599 \\fn main() void { 1600 \\ var bad: u128 = 0b0010_; 1601 \\} 1602 , &[_][]const u8{ 1603 "tmp.zig:2:28: error: invalid character: ';'", 1604 }); 1605 1606 cases.add("invalid underscore placement in int literal - 3", 1607 \\fn main() void { 1608 \\ var bad: u128 = 0o0010_; 1609 \\} 1610 , &[_][]const u8{ 1611 "tmp.zig:2:28: error: invalid character: ';'", 1612 }); 1613 1614 cases.add("invalid underscore placement in int literal - 4", 1615 \\fn main() void { 1616 \\ var bad: u128 = 0x0010_; 1617 \\} 1618 , &[_][]const u8{ 1619 "tmp.zig:2:28: error: invalid character: ';'", 1620 }); 1621 1622 cases.add("comptime struct field, no init value", 1623 \\const Foo = struct { 1624 \\ comptime b: i32, 1625 \\}; 1626 \\export fn entry() void { 1627 \\ var f: Foo = undefined; 1628 \\} 1629 , &[_][]const u8{ 1630 "tmp.zig:2:5: error: comptime struct field missing initialization value", 1631 }); 1632 1633 cases.add("bad usage of @call", 1634 \\export fn entry1() void { 1635 \\ @call(.{}, foo, {}); 1636 \\} 1637 \\export fn entry2() void { 1638 \\ comptime @call(.{ .modifier = .never_inline }, foo, .{}); 1639 \\} 1640 \\export fn entry3() void { 1641 \\ comptime @call(.{ .modifier = .never_tail }, foo, .{}); 1642 \\} 1643 \\export fn entry4() void { 1644 \\ @call(.{ .modifier = .never_inline }, bar, .{}); 1645 \\} 1646 \\export fn entry5(c: bool) void { 1647 \\ var baz = if (c) baz1 else baz2; 1648 \\ @call(.{ .modifier = .compile_time }, baz, .{}); 1649 \\} 1650 \\fn foo() void {} 1651 \\inline fn bar() void {} 1652 \\fn baz1() void {} 1653 \\fn baz2() void {} 1654 , &[_][]const u8{ 1655 "tmp.zig:2:21: error: expected tuple or struct, found 'void'", 1656 "tmp.zig:5:14: error: unable to perform 'never_inline' call at compile-time", 1657 "tmp.zig:8:14: error: unable to perform 'never_tail' call at compile-time", 1658 "tmp.zig:11:5: error: no-inline call of inline function", 1659 "tmp.zig:15:5: error: the specified modifier requires a comptime-known function", 1660 }); 1661 1662 cases.add("exported async function", 1663 \\export fn foo() callconv(.Async) void {} 1664 , &[_][]const u8{ 1665 "tmp.zig:1:1: error: exported function cannot be async", 1666 }); 1667 1668 cases.addExe("main missing name", 1669 \\pub fn (main) void {} 1670 , &[_][]const u8{ 1671 "tmp.zig:1:5: error: missing function name", 1672 }); 1673 1674 cases.addCase(x: { 1675 var tc = cases.create("call with new stack on unsupported target", 1676 \\var buf: [10]u8 align(16) = undefined; 1677 \\export fn entry() void { 1678 \\ @call(.{.stack = &buf}, foo, .{}); 1679 \\} 1680 \\fn foo() void {} 1681 , &[_][]const u8{ 1682 "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack", 1683 }); 1684 tc.target = std.zig.CrossTarget{ 1685 .cpu_arch = .wasm32, 1686 .os_tag = .wasi, 1687 .abi = .none, 1688 }; 1689 break :x tc; 1690 }); 1691 1692 // Note: One of the error messages here is backwards. It would be nice to fix, but that's not 1693 // going to stop me from merging this branch which fixes a bunch of other stuff. 1694 cases.add("incompatible sentinels", 1695 \\export fn entry1(ptr: [*:255]u8) [*:0]u8 { 1696 \\ return ptr; 1697 \\} 1698 \\export fn entry2(ptr: [*]u8) [*:0]u8 { 1699 \\ return ptr; 1700 \\} 1701 \\export fn entry3() void { 1702 \\ var array: [2:0]u8 = [_:255]u8{1, 2}; 1703 \\} 1704 \\export fn entry4() void { 1705 \\ var array: [2:0]u8 = [_]u8{1, 2}; 1706 \\} 1707 , &[_][]const u8{ 1708 "tmp.zig:2:12: error: expected type '[*:0]u8', found '[*:255]u8'", 1709 "tmp.zig:2:12: note: destination pointer requires a terminating '0' sentinel, but source pointer has a terminating '255' sentinel", 1710 "tmp.zig:5:12: error: expected type '[*:0]u8', found '[*]u8'", 1711 "tmp.zig:5:12: note: destination pointer requires a terminating '0' sentinel", 1712 1713 "tmp.zig:8:35: error: expected type '[2:255]u8', found '[2:0]u8'", 1714 "tmp.zig:8:35: note: destination array requires a terminating '255' sentinel, but source array has a terminating '0' sentinel", 1715 "tmp.zig:11:31: error: expected type '[2:0]u8', found '[2]u8'", 1716 "tmp.zig:11:31: note: destination array requires a terminating '0' sentinel", 1717 }); 1718 1719 cases.add("empty switch on an integer", 1720 \\export fn entry() void { 1721 \\ var x: u32 = 0; 1722 \\ switch(x) {} 1723 \\} 1724 , &[_][]const u8{ 1725 "tmp.zig:3:5: error: switch must handle all possibilities", 1726 }); 1727 1728 cases.add("incorrect return type", 1729 \\ pub export fn entry() void{ 1730 \\ _ = foo(); 1731 \\ } 1732 \\ const A = struct { 1733 \\ a: u32, 1734 \\ }; 1735 \\ fn foo() A { 1736 \\ return bar(); 1737 \\ } 1738 \\ const B = struct { 1739 \\ a: u32, 1740 \\ }; 1741 \\ fn bar() B { 1742 \\ unreachable; 1743 \\ } 1744 , &[_][]const u8{ 1745 "tmp.zig:8:16: error: expected type 'A', found 'B'", 1746 }); 1747 1748 cases.add("regression test #2980: base type u32 is not type checked properly when assigning a value within a struct", 1749 \\const Foo = struct { 1750 \\ ptr: ?*usize, 1751 \\ uval: u32, 1752 \\}; 1753 \\fn get_uval(x: u32) !u32 { 1754 \\ return error.NotFound; 1755 \\} 1756 \\export fn entry() void { 1757 \\ const afoo = Foo{ 1758 \\ .ptr = null, 1759 \\ .uval = get_uval(42), 1760 \\ }; 1761 \\} 1762 , &[_][]const u8{ 1763 "tmp.zig:11:25: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'", 1764 }); 1765 1766 cases.add("assigning to struct or union fields that are not optionals with a function that returns an optional", 1767 \\fn maybe(is: bool) ?u8 { 1768 \\ if (is) return @as(u8, 10) else return null; 1769 \\} 1770 \\const U = union { 1771 \\ Ye: u8, 1772 \\}; 1773 \\const S = struct { 1774 \\ num: u8, 1775 \\}; 1776 \\export fn entry() void { 1777 \\ var u = U{ .Ye = maybe(false) }; 1778 \\ var s = S{ .num = maybe(false) }; 1779 \\} 1780 , &[_][]const u8{ 1781 "tmp.zig:11:27: error: expected type 'u8', found '?u8'", 1782 }); 1783 1784 cases.add("missing result type for phi node", 1785 \\fn foo() !void { 1786 \\ return anyerror.Foo; 1787 \\} 1788 \\export fn entry() void { 1789 \\ foo() catch 0; 1790 \\} 1791 , &[_][]const u8{ 1792 "tmp.zig:5:17: error: integer value 0 cannot be coerced to type 'void'", 1793 }); 1794 1795 cases.add("atomicrmw with enum op not .Xchg", 1796 \\export fn entry() void { 1797 \\ const E = enum(u8) { 1798 \\ a, 1799 \\ b, 1800 \\ c, 1801 \\ d, 1802 \\ }; 1803 \\ var x: E = .a; 1804 \\ _ = @atomicRmw(E, &x, .Add, .b, .SeqCst); 1805 \\} 1806 , &[_][]const u8{ 1807 "tmp.zig:9:27: error: @atomicRmw with enum only allowed with .Xchg", 1808 }); 1809 1810 cases.add("disallow coercion from non-null-terminated pointer to null-terminated pointer", 1811 \\extern fn puts(s: [*:0]const u8) c_int; 1812 \\pub fn main() void { 1813 \\ const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'}; 1814 \\ const no_zero_ptr: [*]const u8 = &no_zero_array; 1815 \\ _ = puts(no_zero_ptr); 1816 \\} 1817 , &[_][]const u8{ 1818 "tmp.zig:5:14: error: expected type '[*:0]const u8', found '[*]const u8'", 1819 }); 1820 1821 cases.add("atomic orderings of atomicStore Acquire or AcqRel", 1822 \\export fn entry() void { 1823 \\ var x: u32 = 0; 1824 \\ @atomicStore(u32, &x, 1, .Acquire); 1825 \\} 1826 , &[_][]const u8{ 1827 "tmp.zig:3:30: error: @atomicStore atomic ordering must not be Acquire or AcqRel", 1828 }); 1829 1830 cases.add("missing const in slice with nested array type", 1831 \\const Geo3DTex2D = struct { vertices: [][2]f32 }; 1832 \\pub fn getGeo3DTex2D() Geo3DTex2D { 1833 \\ return Geo3DTex2D{ 1834 \\ .vertices = [_][2]f32{ 1835 \\ [_]f32{ -0.5, -0.5}, 1836 \\ }, 1837 \\ }; 1838 \\} 1839 \\export fn entry() void { 1840 \\ var geo_data = getGeo3DTex2D(); 1841 \\} 1842 , &[_][]const u8{ 1843 "tmp.zig:4:30: error: array literal requires address-of operator to coerce to slice type '[][2]f32'", 1844 }); 1845 1846 cases.add("slicing of global undefined pointer", 1847 \\var buf: *[1]u8 = undefined; 1848 \\export fn entry() void { 1849 \\ _ = buf[0..1]; 1850 \\} 1851 , &[_][]const u8{ 1852 "tmp.zig:3:12: error: non-zero length slice of undefined pointer", 1853 }); 1854 1855 cases.add("using invalid types in function call raises an error", 1856 \\const MenuEffect = enum {}; 1857 \\fn func(effect: MenuEffect) void {} 1858 \\export fn entry() void { 1859 \\ func(MenuEffect.ThisDoesNotExist); 1860 \\} 1861 , &[_][]const u8{ 1862 "tmp.zig:1:20: error: enums must have 1 or more fields", 1863 "tmp.zig:4:20: note: referenced here", 1864 }); 1865 1866 cases.add("store vector pointer with unknown runtime index", 1867 \\export fn entry() void { 1868 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined }; 1869 \\ 1870 \\ var i: u32 = 0; 1871 \\ storev(&v[i], 42); 1872 \\} 1873 \\ 1874 \\fn storev(ptr: anytype, val: i32) void { 1875 \\ ptr.* = val; 1876 \\} 1877 , &[_][]const u8{ 1878 "tmp.zig:9:8: error: unable to determine vector element index of type '*align(16:0:4:?) i32", 1879 }); 1880 1881 cases.add("load vector pointer with unknown runtime index", 1882 \\export fn entry() void { 1883 \\ var v: @import("std").meta.Vector(4, i32) = [_]i32{ 1, 5, 3, undefined }; 1884 \\ 1885 \\ var i: u32 = 0; 1886 \\ var x = loadv(&v[i]); 1887 \\} 1888 \\ 1889 \\fn loadv(ptr: anytype) i32 { 1890 \\ return ptr.*; 1891 \\} 1892 , &[_][]const u8{ 1893 "tmp.zig:9:12: error: unable to determine vector element index of type '*align(16:0:4:?) i32", 1894 }); 1895 1896 cases.add("using an unknown len ptr type instead of array", 1897 \\const resolutions = [*][*]const u8{ 1898 \\ "[320 240 ]", 1899 \\ null, 1900 \\}; 1901 \\comptime { 1902 \\ _ = resolutions; 1903 \\} 1904 , &[_][]const u8{ 1905 "tmp.zig:1:21: error: expected array type or [_], found '[*][*]const u8'", 1906 }); 1907 1908 cases.add("comparison with error union and error value", 1909 \\export fn entry() void { 1910 \\ var number_or_error: anyerror!i32 = error.SomethingAwful; 1911 \\ _ = number_or_error == error.SomethingAwful; 1912 \\} 1913 , &[_][]const u8{ 1914 "tmp.zig:3:25: error: operator not allowed for type 'anyerror!i32'", 1915 }); 1916 1917 cases.add("switch with overlapping case ranges", 1918 \\export fn entry() void { 1919 \\ var q: u8 = 0; 1920 \\ switch (q) { 1921 \\ 1...2 => {}, 1922 \\ 0...255 => {}, 1923 \\ } 1924 \\} 1925 , &[_][]const u8{ 1926 "tmp.zig:5:9: error: duplicate switch value", 1927 }); 1928 1929 cases.add("invalid optional type in extern struct", 1930 \\const stroo = extern struct { 1931 \\ moo: ?[*c]u8, 1932 \\}; 1933 \\export fn testf(fluff: *stroo) void {} 1934 , &[_][]const u8{ 1935 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?[*c]u8'", 1936 }); 1937 1938 cases.add("attempt to negate a non-integer, non-float or non-vector type", 1939 \\fn foo() anyerror!u32 { 1940 \\ return 1; 1941 \\} 1942 \\ 1943 \\export fn entry() void { 1944 \\ const x = -foo(); 1945 \\} 1946 , &[_][]const u8{ 1947 "tmp.zig:6:15: error: negation of type 'anyerror!u32'", 1948 }); 1949 1950 cases.add("attempt to create 17 bit float type", 1951 \\const builtin = @import("builtin"); 1952 \\comptime { 1953 \\ _ = @Type(builtin.TypeInfo { .Float = builtin.TypeInfo.Float { .bits = 17 } }); 1954 \\} 1955 , &[_][]const u8{ 1956 "tmp.zig:3:32: error: 17-bit float unsupported", 1957 }); 1958 1959 cases.add("wrong type for @Type", 1960 \\export fn entry() void { 1961 \\ _ = @Type(0); 1962 \\} 1963 , &[_][]const u8{ 1964 "tmp.zig:2:15: error: expected type 'std.builtin.TypeInfo', found 'comptime_int'", 1965 }); 1966 1967 cases.add("@Type with non-constant expression", 1968 \\const builtin = @import("builtin"); 1969 \\var globalTypeInfo : builtin.TypeInfo = undefined; 1970 \\export fn entry() void { 1971 \\ _ = @Type(globalTypeInfo); 1972 \\} 1973 , &[_][]const u8{ 1974 "tmp.zig:4:15: error: unable to evaluate constant expression", 1975 }); 1976 1977 cases.add("wrong type for argument tuple to @asyncCall", 1978 \\export fn entry1() void { 1979 \\ var frame: @Frame(foo) = undefined; 1980 \\ @asyncCall(&frame, {}, foo, {}); 1981 \\} 1982 \\ 1983 \\fn foo() i32 { 1984 \\ return 0; 1985 \\} 1986 , &[_][]const u8{ 1987 "tmp.zig:3:33: error: expected tuple or struct, found 'void'", 1988 }); 1989 1990 cases.add("wrong type for result ptr to @asyncCall", 1991 \\export fn entry() void { 1992 \\ _ = async amain(); 1993 \\} 1994 \\fn amain() i32 { 1995 \\ var frame: @Frame(foo) = undefined; 1996 \\ return await @asyncCall(&frame, false, foo, .{}); 1997 \\} 1998 \\fn foo() i32 { 1999 \\ return 1234; 2000 \\} 2001 , &[_][]const u8{ 2002 "tmp.zig:6:37: error: expected type '*i32', found 'bool'", 2003 }); 2004 2005 cases.add("shift amount has to be an integer type", 2006 \\export fn entry() void { 2007 \\ const x = 1 << &@as(u8, 10); 2008 \\} 2009 , &[_][]const u8{ 2010 "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*const u8'", 2011 "tmp.zig:2:17: note: referenced here", 2012 }); 2013 2014 cases.add("bit shifting only works on integer types", 2015 \\export fn entry() void { 2016 \\ const x = &@as(u8, 1) << 10; 2017 \\} 2018 , &[_][]const u8{ 2019 "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*const u8'", 2020 "tmp.zig:2:27: note: referenced here", 2021 }); 2022 2023 cases.add("struct depends on itself via optional field", 2024 \\const LhsExpr = struct { 2025 \\ rhsExpr: ?AstObject, 2026 \\}; 2027 \\const AstObject = union { 2028 \\ lhsExpr: LhsExpr, 2029 \\}; 2030 \\export fn entry() void { 2031 \\ const lhsExpr = LhsExpr{ .rhsExpr = null }; 2032 \\ const obj = AstObject{ .lhsExpr = lhsExpr }; 2033 \\} 2034 , &[_][]const u8{ 2035 "tmp.zig:1:17: error: struct 'LhsExpr' depends on itself", 2036 "tmp.zig:5:5: note: while checking this field", 2037 "tmp.zig:2:5: note: while checking this field", 2038 }); 2039 2040 cases.add("alignment of enum field specified", 2041 \\const Number = enum { 2042 \\ a, 2043 \\ b align(i32), 2044 \\}; 2045 \\export fn entry1() void { 2046 \\ var x: Number = undefined; 2047 \\} 2048 , &[_][]const u8{ 2049 "tmp.zig:3:13: error: structs and unions, not enums, support field alignment", 2050 "tmp.zig:1:16: note: consider 'union(enum)' here", 2051 }); 2052 2053 cases.add("bad alignment type", 2054 \\export fn entry1() void { 2055 \\ var x: []align(true) i32 = undefined; 2056 \\} 2057 \\export fn entry2() void { 2058 \\ var x: *align(@as(f64, 12.34)) i32 = undefined; 2059 \\} 2060 , &[_][]const u8{ 2061 "tmp.zig:2:20: error: expected type 'u29', found 'bool'", 2062 "tmp.zig:5:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'", 2063 }); 2064 2065 cases.addCase(x: { 2066 var tc = cases.create("variable in inline assembly template cannot be found", 2067 \\export fn entry() void { 2068 \\ var sp = asm volatile ( 2069 \\ "mov %[foo], sp" 2070 \\ : [bar] "=r" (-> usize) 2071 \\ ); 2072 \\} 2073 , &[_][]const u8{ 2074 "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs", 2075 }); 2076 tc.target = std.zig.CrossTarget{ 2077 .cpu_arch = .x86_64, 2078 .os_tag = .linux, 2079 .abi = .gnu, 2080 }; 2081 break :x tc; 2082 }); 2083 2084 cases.add("indirect recursion of async functions detected", 2085 \\var frame: ?anyframe = null; 2086 \\ 2087 \\export fn a() void { 2088 \\ _ = async rangeSum(10); 2089 \\ while (frame) |f| resume f; 2090 \\} 2091 \\ 2092 \\fn rangeSum(x: i32) i32 { 2093 \\ suspend { 2094 \\ frame = @frame(); 2095 \\ } 2096 \\ frame = null; 2097 \\ 2098 \\ if (x == 0) return 0; 2099 \\ var child = rangeSumIndirect(x - 1); 2100 \\ return child + 1; 2101 \\} 2102 \\ 2103 \\fn rangeSumIndirect(x: i32) i32 { 2104 \\ suspend { 2105 \\ frame = @frame(); 2106 \\ } 2107 \\ frame = null; 2108 \\ 2109 \\ if (x == 0) return 0; 2110 \\ var child = rangeSum(x - 1); 2111 \\ return child + 1; 2112 \\} 2113 , &[_][]const u8{ 2114 "tmp.zig:8:1: error: '@Frame(rangeSum)' depends on itself", 2115 "tmp.zig:15:33: note: when analyzing type '@Frame(rangeSum)' here", 2116 "tmp.zig:26:25: note: when analyzing type '@Frame(rangeSumIndirect)' here", 2117 }); 2118 2119 cases.add("non-async function pointer eventually is inferred to become async", 2120 \\export fn a() void { 2121 \\ var non_async_fn: fn () void = undefined; 2122 \\ non_async_fn = func; 2123 \\} 2124 \\fn func() void { 2125 \\ suspend; 2126 \\} 2127 , &[_][]const u8{ 2128 "tmp.zig:5:1: error: 'func' cannot be async", 2129 "tmp.zig:3:20: note: required to be non-async here", 2130 "tmp.zig:6:5: note: suspends here", 2131 }); 2132 2133 cases.add("bad alignment in @asyncCall", 2134 \\export fn entry() void { 2135 \\ var ptr: fn () callconv(.Async) void = func; 2136 \\ var bytes: [64]u8 = undefined; 2137 \\ _ = @asyncCall(&bytes, {}, ptr, .{}); 2138 \\} 2139 \\fn func() callconv(.Async) void {} 2140 , &[_][]const u8{ 2141 "tmp.zig:4:21: error: expected type '[]align(16) u8', found '*[64]u8'", 2142 }); 2143 2144 cases.add("atomic orderings of fence Acquire or stricter", 2145 \\export fn entry() void { 2146 \\ @fence(.Monotonic); 2147 \\} 2148 , &[_][]const u8{ 2149 "tmp.zig:2:12: error: atomic ordering must be Acquire or stricter", 2150 }); 2151 2152 cases.add("bad alignment in implicit cast from array pointer to slice", 2153 \\export fn a() void { 2154 \\ var x: [10]u8 = undefined; 2155 \\ var y: []align(16) u8 = &x; 2156 \\} 2157 , &[_][]const u8{ 2158 "tmp.zig:3:30: error: expected type '[]align(16) u8', found '*[10]u8'", 2159 }); 2160 2161 cases.add("result location incompatibility mismatching handle_is_ptr (generic call)", 2162 \\export fn entry() void { 2163 \\ var damn = Container{ 2164 \\ .not_optional = getOptional(i32), 2165 \\ }; 2166 \\} 2167 \\pub fn getOptional(comptime T: type) ?T { 2168 \\ return 0; 2169 \\} 2170 \\pub const Container = struct { 2171 \\ not_optional: i32, 2172 \\}; 2173 , &[_][]const u8{ 2174 "tmp.zig:3:36: error: expected type 'i32', found '?i32'", 2175 }); 2176 2177 cases.add("result location incompatibility mismatching handle_is_ptr", 2178 \\export fn entry() void { 2179 \\ var damn = Container{ 2180 \\ .not_optional = getOptional(), 2181 \\ }; 2182 \\} 2183 \\pub fn getOptional() ?i32 { 2184 \\ return 0; 2185 \\} 2186 \\pub const Container = struct { 2187 \\ not_optional: i32, 2188 \\}; 2189 , &[_][]const u8{ 2190 "tmp.zig:3:36: error: expected type 'i32', found '?i32'", 2191 }); 2192 2193 cases.add("const frame cast to anyframe", 2194 \\export fn a() void { 2195 \\ const f = async func(); 2196 \\ resume f; 2197 \\} 2198 \\export fn b() void { 2199 \\ const f = async func(); 2200 \\ var x: anyframe = &f; 2201 \\} 2202 \\fn func() void { 2203 \\ suspend; 2204 \\} 2205 , &[_][]const u8{ 2206 "tmp.zig:3:12: error: expected type 'anyframe', found '*const @Frame(func)'", 2207 "tmp.zig:7:24: error: expected type 'anyframe', found '*const @Frame(func)'", 2208 }); 2209 2210 cases.add("prevent bad implicit casting of anyframe types", 2211 \\export fn a() void { 2212 \\ var x: anyframe = undefined; 2213 \\ var y: anyframe->i32 = x; 2214 \\} 2215 \\export fn b() void { 2216 \\ var x: i32 = undefined; 2217 \\ var y: anyframe->i32 = x; 2218 \\} 2219 \\export fn c() void { 2220 \\ var x: @Frame(func) = undefined; 2221 \\ var y: anyframe->i32 = &x; 2222 \\} 2223 \\fn func() void {} 2224 , &[_][]const u8{ 2225 "tmp.zig:3:28: error: expected type 'anyframe->i32', found 'anyframe'", 2226 "tmp.zig:7:28: error: expected type 'anyframe->i32', found 'i32'", 2227 "tmp.zig:11:29: error: expected type 'anyframe->i32', found '*@Frame(func)'", 2228 }); 2229 2230 cases.add("wrong frame type used for async call", 2231 \\export fn entry() void { 2232 \\ var frame: @Frame(foo) = undefined; 2233 \\ frame = async bar(); 2234 \\} 2235 \\fn foo() void { 2236 \\ suspend; 2237 \\} 2238 \\fn bar() void { 2239 \\ suspend; 2240 \\} 2241 , &[_][]const u8{ 2242 "tmp.zig:3:13: error: expected type '*@Frame(bar)', found '*@Frame(foo)'", 2243 }); 2244 2245 cases.add("@Frame() of generic function", 2246 \\export fn entry() void { 2247 \\ var frame: @Frame(func) = undefined; 2248 \\} 2249 \\fn func(comptime T: type) void { 2250 \\ var x: T = undefined; 2251 \\} 2252 , &[_][]const u8{ 2253 "tmp.zig:2:16: error: @Frame() of generic function", 2254 }); 2255 2256 cases.add("@frame() causes function to be async", 2257 \\export fn entry() void { 2258 \\ func(); 2259 \\} 2260 \\fn func() void { 2261 \\ _ = @frame(); 2262 \\} 2263 , &[_][]const u8{ 2264 "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", 2265 "tmp.zig:5:9: note: @frame() causes function to be async", 2266 }); 2267 2268 cases.add("invalid suspend in exported function", 2269 \\export fn entry() void { 2270 \\ var frame = async func(); 2271 \\ var result = await frame; 2272 \\} 2273 \\fn func() void { 2274 \\ suspend; 2275 \\} 2276 , &[_][]const u8{ 2277 "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", 2278 "tmp.zig:3:18: note: await here is a suspend point", 2279 }); 2280 2281 cases.add("async function indirectly depends on its own frame", 2282 \\export fn entry() void { 2283 \\ _ = async amain(); 2284 \\} 2285 \\fn amain() callconv(.Async) void { 2286 \\ other(); 2287 \\} 2288 \\fn other() void { 2289 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined; 2290 \\} 2291 , &[_][]const u8{ 2292 "tmp.zig:4:1: error: unable to determine async function frame of 'amain'", 2293 "tmp.zig:5:10: note: analysis of function 'other' depends on the frame", 2294 "tmp.zig:8:13: note: referenced here", 2295 }); 2296 2297 cases.add("async function depends on its own frame", 2298 \\export fn entry() void { 2299 \\ _ = async amain(); 2300 \\} 2301 \\fn amain() callconv(.Async) void { 2302 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined; 2303 \\} 2304 , &[_][]const u8{ 2305 "tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet", 2306 "tmp.zig:5:13: note: referenced here", 2307 }); 2308 2309 cases.add("non async function pointer passed to @asyncCall", 2310 \\export fn entry() void { 2311 \\ var ptr = afunc; 2312 \\ var bytes: [100]u8 align(16) = undefined; 2313 \\ _ = @asyncCall(&bytes, {}, ptr, .{}); 2314 \\} 2315 \\fn afunc() void { } 2316 , &[_][]const u8{ 2317 "tmp.zig:4:32: error: expected async function, found 'fn() void'", 2318 }); 2319 2320 cases.add("runtime-known async function called", 2321 \\export fn entry() void { 2322 \\ _ = async amain(); 2323 \\} 2324 \\fn amain() void { 2325 \\ var ptr = afunc; 2326 \\ _ = ptr(); 2327 \\} 2328 \\fn afunc() callconv(.Async) void {} 2329 , &[_][]const u8{ 2330 "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required", 2331 }); 2332 2333 cases.add("runtime-known function called with async keyword", 2334 \\export fn entry() void { 2335 \\ var ptr = afunc; 2336 \\ _ = async ptr(); 2337 \\} 2338 \\ 2339 \\fn afunc() callconv(.Async) void { } 2340 , &[_][]const u8{ 2341 "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required", 2342 }); 2343 2344 cases.add("function with ccc indirectly calling async function", 2345 \\export fn entry() void { 2346 \\ foo(); 2347 \\} 2348 \\fn foo() void { 2349 \\ bar(); 2350 \\} 2351 \\fn bar() void { 2352 \\ suspend; 2353 \\} 2354 , &[_][]const u8{ 2355 "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", 2356 "tmp.zig:2:8: note: async function call here", 2357 "tmp.zig:5:8: note: async function call here", 2358 "tmp.zig:8:5: note: suspends here", 2359 }); 2360 2361 cases.add("capture group on switch prong with incompatible payload types", 2362 \\const Union = union(enum) { 2363 \\ A: usize, 2364 \\ B: isize, 2365 \\}; 2366 \\comptime { 2367 \\ var u = Union{ .A = 8 }; 2368 \\ switch (u) { 2369 \\ .A, .B => |e| unreachable, 2370 \\ } 2371 \\} 2372 , &[_][]const u8{ 2373 "tmp.zig:8:20: error: capture group with incompatible types", 2374 "tmp.zig:8:9: note: type 'usize' here", 2375 "tmp.zig:8:13: note: type 'isize' here", 2376 }); 2377 2378 cases.add("wrong type to @hasField", 2379 \\export fn entry() bool { 2380 \\ return @hasField(i32, "hi"); 2381 \\} 2382 , &[_][]const u8{ 2383 "tmp.zig:2:22: error: type 'i32' does not support @hasField", 2384 }); 2385 2386 cases.add("slice passed as array init type with elems", 2387 \\export fn entry() void { 2388 \\ const x = []u8{1, 2}; 2389 \\} 2390 , &[_][]const u8{ 2391 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'", 2392 }); 2393 2394 cases.add("slice passed as array init type", 2395 \\export fn entry() void { 2396 \\ const x = []u8{}; 2397 \\} 2398 , &[_][]const u8{ 2399 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'", 2400 }); 2401 2402 cases.add("inferred array size invalid here", 2403 \\export fn entry() void { 2404 \\ const x = [_]u8; 2405 \\} 2406 \\export fn entry2() void { 2407 \\ const S = struct { a: *const [_]u8 }; 2408 \\ var a = .{ S{} }; 2409 \\} 2410 , &[_][]const u8{ 2411 "tmp.zig:2:15: error: inferred array size invalid here", 2412 "tmp.zig:5:34: error: inferred array size invalid here", 2413 }); 2414 2415 cases.add("initializing array with struct syntax", 2416 \\export fn entry() void { 2417 \\ const x = [_]u8{ .y = 2 }; 2418 \\} 2419 , &[_][]const u8{ 2420 "tmp.zig:2:15: error: initializing array with struct syntax", 2421 }); 2422 2423 cases.add("compile error in struct init expression", 2424 \\const Foo = struct { 2425 \\ a: i32 = crap, 2426 \\ b: i32, 2427 \\}; 2428 \\export fn entry() void { 2429 \\ var x = Foo{ 2430 \\ .b = 5, 2431 \\ }; 2432 \\} 2433 , &[_][]const u8{ 2434 "tmp.zig:2:14: error: use of undeclared identifier 'crap'", 2435 }); 2436 2437 cases.add("undefined as field type is rejected", 2438 \\const Foo = struct { 2439 \\ a: undefined, 2440 \\}; 2441 \\export fn entry1() void { 2442 \\ const foo: Foo = undefined; 2443 \\} 2444 , &[_][]const u8{ 2445 "tmp.zig:2:8: error: use of undefined value here causes undefined behavior", 2446 }); 2447 2448 cases.add("@hasDecl with non-container", 2449 \\export fn entry() void { 2450 \\ _ = @hasDecl(i32, "hi"); 2451 \\} 2452 , &[_][]const u8{ 2453 "tmp.zig:2:18: error: expected struct, enum, or union; found 'i32'", 2454 }); 2455 2456 cases.add("field access of slices", 2457 \\export fn entry() void { 2458 \\ var slice: []i32 = undefined; 2459 \\ const info = @TypeOf(slice).unknown; 2460 \\} 2461 , &[_][]const u8{ 2462 "tmp.zig:3:32: error: type 'type' does not support field access", 2463 }); 2464 2465 cases.add("peer cast then implicit cast const pointer to mutable C pointer", 2466 \\export fn func() void { 2467 \\ var strValue: [*c]u8 = undefined; 2468 \\ strValue = strValue orelse ""; 2469 \\} 2470 , &[_][]const u8{ 2471 "tmp.zig:3:32: error: expected type '[*c]u8', found '*const [0:0]u8'", 2472 "tmp.zig:3:32: note: cast discards const qualifier", 2473 }); 2474 2475 cases.add("overflow in enum value allocation", 2476 \\const Moo = enum(u8) { 2477 \\ Last = 255, 2478 \\ Over, 2479 \\}; 2480 \\pub fn main() void { 2481 \\ var y = Moo.Last; 2482 \\} 2483 , &[_][]const u8{ 2484 "tmp.zig:3:5: error: enumeration value 256 too large for type 'u8'", 2485 }); 2486 2487 cases.add("attempt to cast enum literal to error", 2488 \\export fn entry() void { 2489 \\ switch (error.Hi) { 2490 \\ .Hi => {}, 2491 \\ } 2492 \\} 2493 , &[_][]const u8{ 2494 "tmp.zig:3:9: error: expected type 'error{Hi}', found '(enum literal)'", 2495 }); 2496 2497 cases.add("@sizeOf bad type", 2498 \\export fn entry() usize { 2499 \\ return @sizeOf(@TypeOf(null)); 2500 \\} 2501 , &[_][]const u8{ 2502 "tmp.zig:2:20: error: no size available for type '(null)'", 2503 }); 2504 2505 cases.add("generic function where return type is self-referenced", 2506 \\fn Foo(comptime T: type) Foo(T) { 2507 \\ return struct{ x: T }; 2508 \\} 2509 \\export fn entry() void { 2510 \\ const t = Foo(u32) { 2511 \\ .x = 1 2512 \\ }; 2513 \\} 2514 , &[_][]const u8{ 2515 "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches", 2516 "tmp.zig:5:18: note: referenced here", 2517 }); 2518 2519 cases.add("@ptrToInt 0 to non optional pointer", 2520 \\export fn entry() void { 2521 \\ var b = @intToPtr(*i32, 0); 2522 \\} 2523 , &[_][]const u8{ 2524 "tmp.zig:2:13: error: pointer type '*i32' does not allow address zero", 2525 }); 2526 2527 cases.add("cast enum literal to enum but it doesn't match", 2528 \\const Foo = enum { 2529 \\ a, 2530 \\ b, 2531 \\}; 2532 \\export fn entry() void { 2533 \\ const x: Foo = .c; 2534 \\} 2535 , &[_][]const u8{ 2536 "tmp.zig:6:20: error: enum 'Foo' has no field named 'c'", 2537 "tmp.zig:1:13: note: 'Foo' declared here", 2538 }); 2539 2540 cases.add("discarding error value", 2541 \\export fn entry() void { 2542 \\ _ = foo(); 2543 \\} 2544 \\fn foo() !void { 2545 \\ return error.OutOfMemory; 2546 \\} 2547 , &[_][]const u8{ 2548 "tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`", 2549 }); 2550 2551 cases.add("volatile on global assembly", 2552 \\comptime { 2553 \\ asm volatile (""); 2554 \\} 2555 , &[_][]const u8{ 2556 "tmp.zig:2:9: error: volatile is meaningless on global assembly", 2557 }); 2558 2559 cases.add("invalid multiple dereferences", 2560 \\export fn a() void { 2561 \\ var box = Box{ .field = 0 }; 2562 \\ box.*.field = 1; 2563 \\} 2564 \\export fn b() void { 2565 \\ var box = Box{ .field = 0 }; 2566 \\ var boxPtr = &box; 2567 \\ boxPtr.*.*.field = 1; 2568 \\} 2569 \\pub const Box = struct { 2570 \\ field: i32, 2571 \\}; 2572 , &[_][]const u8{ 2573 "tmp.zig:3:8: error: attempt to dereference non-pointer type 'Box'", 2574 "tmp.zig:8:13: error: attempt to dereference non-pointer type 'Box'", 2575 }); 2576 2577 cases.add("usingnamespace with wrong type", 2578 \\usingnamespace void; 2579 , &[_][]const u8{ 2580 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'", 2581 }); 2582 2583 cases.add("ignored expression in while continuation", 2584 \\export fn a() void { 2585 \\ while (true) : (bad()) {} 2586 \\} 2587 \\export fn b() void { 2588 \\ var x: anyerror!i32 = 1234; 2589 \\ while (x) |_| : (bad()) {} else |_| {} 2590 \\} 2591 \\export fn c() void { 2592 \\ var x: ?i32 = 1234; 2593 \\ while (x) |_| : (bad()) {} 2594 \\} 2595 \\fn bad() anyerror!void { 2596 \\ return error.Bad; 2597 \\} 2598 , &[_][]const u8{ 2599 "tmp.zig:2:24: error: error is ignored. consider using `try`, `catch`, or `if`", 2600 "tmp.zig:6:25: error: error is ignored. consider using `try`, `catch`, or `if`", 2601 "tmp.zig:10:25: error: error is ignored. consider using `try`, `catch`, or `if`", 2602 }); 2603 2604 cases.add("empty while loop body", 2605 \\export fn a() void { 2606 \\ while(true); 2607 \\} 2608 , &[_][]const u8{ 2609 "tmp.zig:2:16: error: expected loop body, found ';'", 2610 }); 2611 2612 cases.add("empty for loop body", 2613 \\export fn a() void { 2614 \\ for(undefined) |x|; 2615 \\} 2616 , &[_][]const u8{ 2617 "tmp.zig:2:23: error: expected loop body, found ';'", 2618 }); 2619 2620 cases.add("empty if body", 2621 \\export fn a() void { 2622 \\ if(true); 2623 \\} 2624 , &[_][]const u8{ 2625 "tmp.zig:2:13: error: expected if body, found ';'", 2626 }); 2627 2628 cases.add("import outside package path", 2629 \\comptime{ 2630 \\ _ = @import("../a.zig"); 2631 \\} 2632 , &[_][]const u8{ 2633 "tmp.zig:2:9: error: import of file outside package path: '../a.zig'", 2634 }); 2635 2636 cases.add("bogus compile var", 2637 \\const x = @import("builtin").bogus; 2638 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); } 2639 , &[_][]const u8{ 2640 "tmp.zig:1:29: error: container 'builtin' has no member called 'bogus'", 2641 }); 2642 2643 cases.add("wrong panic signature, runtime function", 2644 \\test "" {} 2645 \\ 2646 \\pub fn panic() void {} 2647 \\ 2648 , &[_][]const u8{ 2649 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn() void'", 2650 }); 2651 2652 cases.add("wrong panic signature, generic function", 2653 \\pub fn panic(comptime msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { 2654 \\ while (true) {} 2655 \\} 2656 , &[_][]const u8{ 2657 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,anytype) anytype'", 2658 "note: only one of the functions is generic", 2659 }); 2660 2661 cases.add("direct struct loop", 2662 \\const A = struct { a : A, }; 2663 \\export fn entry() usize { return @sizeOf(A); } 2664 , &[_][]const u8{ 2665 "tmp.zig:1:11: error: struct 'A' depends on itself", 2666 }); 2667 2668 cases.add("indirect struct loop", 2669 \\const A = struct { b : B, }; 2670 \\const B = struct { c : C, }; 2671 \\const C = struct { a : A, }; 2672 \\export fn entry() usize { return @sizeOf(A); } 2673 , &[_][]const u8{ 2674 "tmp.zig:1:11: error: struct 'A' depends on itself", 2675 }); 2676 2677 cases.add("instantiating an undefined value for an invalid struct that contains itself", 2678 \\const Foo = struct { 2679 \\ x: Foo, 2680 \\}; 2681 \\ 2682 \\var foo: Foo = undefined; 2683 \\ 2684 \\export fn entry() usize { 2685 \\ return @sizeOf(@TypeOf(foo.x)); 2686 \\} 2687 , &[_][]const u8{ 2688 "tmp.zig:1:13: error: struct 'Foo' depends on itself", 2689 "tmp.zig:8:28: note: referenced here", 2690 }); 2691 2692 cases.add("enum field value references enum", 2693 \\pub const Foo = extern enum { 2694 \\ A = Foo.B, 2695 \\ C = D, 2696 \\}; 2697 \\export fn entry() void { 2698 \\ var s: Foo = Foo.E; 2699 \\} 2700 , &[_][]const u8{ 2701 "tmp.zig:1:17: error: enum 'Foo' depends on itself", 2702 }); 2703 2704 cases.add("top level decl dependency loop", 2705 \\const a : @TypeOf(b) = 0; 2706 \\const b : @TypeOf(a) = 0; 2707 \\export fn entry() void { 2708 \\ const c = a + b; 2709 \\} 2710 , &[_][]const u8{ 2711 "tmp.zig:2:19: error: dependency loop detected", 2712 "tmp.zig:1:19: note: referenced here", 2713 "tmp.zig:4:15: note: referenced here", 2714 }); 2715 2716 cases.addTest("not an enum type", 2717 \\export fn entry() void { 2718 \\ var self: Error = undefined; 2719 \\ switch (self) { 2720 \\ InvalidToken => |x| return x.token, 2721 \\ ExpectedVarDeclOrFn => |x| return x.token, 2722 \\ } 2723 \\} 2724 \\const Error = union(enum) { 2725 \\ A: InvalidToken, 2726 \\ B: ExpectedVarDeclOrFn, 2727 \\}; 2728 \\const InvalidToken = struct {}; 2729 \\const ExpectedVarDeclOrFn = struct {}; 2730 , &[_][]const u8{ 2731 "tmp.zig:4:9: error: expected type '@TagType(Error)', found 'type'", 2732 }); 2733 2734 cases.addTest("binary OR operator on error sets", 2735 \\pub const A = error.A; 2736 \\pub const AB = A | error.B; 2737 \\export fn entry() void { 2738 \\ var x: AB = undefined; 2739 \\} 2740 , &[_][]const u8{ 2741 "tmp.zig:2:18: error: invalid operands to binary expression: 'error{A}' and 'error{B}'", 2742 }); 2743 2744 if (std.Target.current.os.tag == .linux) { 2745 cases.addTest("implicit dependency on libc", 2746 \\extern "c" fn exit(u8) void; 2747 \\export fn entry() void { 2748 \\ exit(0); 2749 \\} 2750 , &[_][]const u8{ 2751 "tmp.zig:3:5: error: dependency on libc must be explicitly specified in the build command", 2752 }); 2753 2754 cases.addTest("libc headers note", 2755 \\const c = @cImport(@cInclude("stdio.h")); 2756 \\export fn entry() void { 2757 \\ _ = c.printf("hello, world!\n"); 2758 \\} 2759 , &[_][]const u8{ 2760 "tmp.zig:1:11: error: C import failed", 2761 "tmp.zig:1:11: note: libc headers not available; compilation does not link against libc", 2762 }); 2763 } 2764 2765 cases.addTest("comptime vector overflow shows the index", 2766 \\comptime { 2767 \\ var a: @import("std").meta.Vector(4, u8) = [_]u8{ 1, 2, 255, 4 }; 2768 \\ var b: @import("std").meta.Vector(4, u8) = [_]u8{ 5, 6, 1, 8 }; 2769 \\ var x = a + b; 2770 \\} 2771 , &[_][]const u8{ 2772 "tmp.zig:4:15: error: operation caused overflow", 2773 "tmp.zig:4:15: note: when computing vector element at index 2", 2774 }); 2775 2776 cases.addTest("packed struct with fields of not allowed types", 2777 \\const A = packed struct { 2778 \\ x: anyerror, 2779 \\}; 2780 \\const B = packed struct { 2781 \\ x: [2]u24, 2782 \\}; 2783 \\const C = packed struct { 2784 \\ x: [1]anyerror, 2785 \\}; 2786 \\const D = packed struct { 2787 \\ x: [1]S, 2788 \\}; 2789 \\const E = packed struct { 2790 \\ x: [1]U, 2791 \\}; 2792 \\const F = packed struct { 2793 \\ x: ?anyerror, 2794 \\}; 2795 \\const G = packed struct { 2796 \\ x: Enum, 2797 \\}; 2798 \\export fn entry1() void { 2799 \\ var a: A = undefined; 2800 \\} 2801 \\export fn entry2() void { 2802 \\ var b: B = undefined; 2803 \\} 2804 \\export fn entry3() void { 2805 \\ var r: C = undefined; 2806 \\} 2807 \\export fn entry4() void { 2808 \\ var d: D = undefined; 2809 \\} 2810 \\export fn entry5() void { 2811 \\ var e: E = undefined; 2812 \\} 2813 \\export fn entry6() void { 2814 \\ var f: F = undefined; 2815 \\} 2816 \\export fn entry7() void { 2817 \\ var g: G = undefined; 2818 \\} 2819 \\const S = struct { 2820 \\ x: i32, 2821 \\}; 2822 \\const U = struct { 2823 \\ A: i32, 2824 \\ B: u32, 2825 \\}; 2826 \\const Enum = enum { 2827 \\ A, 2828 \\ B, 2829 \\}; 2830 , &[_][]const u8{ 2831 "tmp.zig:2:5: error: type 'anyerror' not allowed in packed struct; no guaranteed in-memory representation", 2832 "tmp.zig:5:5: error: array of 'u24' not allowed in packed struct due to padding bits", 2833 "tmp.zig:8:5: error: type 'anyerror' not allowed in packed struct; no guaranteed in-memory representation", 2834 "tmp.zig:11:5: error: non-packed, non-extern struct 'S' not allowed in packed struct; no guaranteed in-memory representation", 2835 "tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation", 2836 "tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation", 2837 "tmp.zig:20:5: error: type 'Enum' not allowed in packed struct; no guaranteed in-memory representation", 2838 "tmp.zig:50:14: note: enum declaration does not specify an integer tag type", 2839 }); 2840 2841 cases.addCase(x: { 2842 var tc = cases.create("deduplicate undeclared identifier", 2843 \\export fn a() void { 2844 \\ x += 1; 2845 \\} 2846 \\export fn b() void { 2847 \\ x += 1; 2848 \\} 2849 , &[_][]const u8{ 2850 "tmp.zig:2:5: error: use of undeclared identifier 'x'", 2851 }); 2852 tc.expect_exact = true; 2853 break :x tc; 2854 }); 2855 2856 cases.add("export generic function", 2857 \\export fn foo(num: anytype) i32 { 2858 \\ return 0; 2859 \\} 2860 , &[_][]const u8{ 2861 "tmp.zig:1:15: error: parameter of type 'anytype' not allowed in function with calling convention 'C'", 2862 }); 2863 2864 cases.add("C pointer to c_void", 2865 \\export fn a() void { 2866 \\ var x: *c_void = undefined; 2867 \\ var y: [*c]c_void = x; 2868 \\} 2869 , &[_][]const u8{ 2870 "tmp.zig:3:16: error: C pointers cannot point to opaque types", 2871 }); 2872 2873 cases.add("directly embedding opaque type in struct and union", 2874 \\const O = opaque {}; 2875 \\const Foo = struct { 2876 \\ o: O, 2877 \\}; 2878 \\const Bar = union { 2879 \\ One: i32, 2880 \\ Two: O, 2881 \\}; 2882 \\export fn a() void { 2883 \\ var foo: Foo = undefined; 2884 \\} 2885 \\export fn b() void { 2886 \\ var bar: Bar = undefined; 2887 \\} 2888 \\export fn c() void { 2889 \\ var baz: *opaque {} = undefined; 2890 \\ const qux = .{baz.*}; 2891 \\} 2892 , &[_][]const u8{ 2893 "tmp.zig:3:5: error: opaque types have unknown size and therefore cannot be directly embedded in structs", 2894 "tmp.zig:7:5: error: opaque types have unknown size and therefore cannot be directly embedded in unions", 2895 "tmp.zig:17:22: error: opaque types have unknown size and therefore cannot be directly embedded in structs", 2896 }); 2897 2898 cases.add("implicit cast between C pointer and Zig pointer - bad const/align/child", 2899 \\export fn a() void { 2900 \\ var x: [*c]u8 = undefined; 2901 \\ var y: *align(4) u8 = x; 2902 \\} 2903 \\export fn b() void { 2904 \\ var x: [*c]const u8 = undefined; 2905 \\ var y: *u8 = x; 2906 \\} 2907 \\export fn c() void { 2908 \\ var x: [*c]u8 = undefined; 2909 \\ var y: *u32 = x; 2910 \\} 2911 \\export fn d() void { 2912 \\ var y: *align(1) u32 = undefined; 2913 \\ var x: [*c]u32 = y; 2914 \\} 2915 \\export fn e() void { 2916 \\ var y: *const u8 = undefined; 2917 \\ var x: [*c]u8 = y; 2918 \\} 2919 \\export fn f() void { 2920 \\ var y: *u8 = undefined; 2921 \\ var x: [*c]u32 = y; 2922 \\} 2923 , &[_][]const u8{ 2924 "tmp.zig:3:27: error: cast increases pointer alignment", 2925 "tmp.zig:7:18: error: cast discards const qualifier", 2926 "tmp.zig:11:19: error: expected type '*u32', found '[*c]u8'", 2927 "tmp.zig:11:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'", 2928 "tmp.zig:15:22: error: cast increases pointer alignment", 2929 "tmp.zig:19:21: error: cast discards const qualifier", 2930 "tmp.zig:23:22: error: expected type '[*c]u32', found '*u8'", 2931 }); 2932 2933 cases.add("implicit casting null c pointer to zig pointer", 2934 \\comptime { 2935 \\ var c_ptr: [*c]u8 = 0; 2936 \\ var zig_ptr: *u8 = c_ptr; 2937 \\} 2938 , &[_][]const u8{ 2939 "tmp.zig:3:24: error: null pointer casted to type '*u8'", 2940 }); 2941 2942 cases.add("implicit casting undefined c pointer to zig pointer", 2943 \\comptime { 2944 \\ var c_ptr: [*c]u8 = undefined; 2945 \\ var zig_ptr: *u8 = c_ptr; 2946 \\} 2947 , &[_][]const u8{ 2948 "tmp.zig:3:24: error: use of undefined value here causes undefined behavior", 2949 }); 2950 2951 cases.add("implicit casting C pointers which would mess up null semantics", 2952 \\export fn entry() void { 2953 \\ var slice: []const u8 = "aoeu"; 2954 \\ const opt_many_ptr: [*]const u8 = slice.ptr; 2955 \\ var ptr_opt_many_ptr = &opt_many_ptr; 2956 \\ var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr; 2957 \\ ptr_opt_many_ptr = c_ptr; 2958 \\} 2959 \\export fn entry2() void { 2960 \\ var buf: [4]u8 = "aoeu".*; 2961 \\ var slice: []u8 = &buf; 2962 \\ var opt_many_ptr: [*]u8 = slice.ptr; 2963 \\ var ptr_opt_many_ptr = &opt_many_ptr; 2964 \\ var c_ptr: [*c][*c]const u8 = ptr_opt_many_ptr; 2965 \\} 2966 , &[_][]const u8{ 2967 "tmp.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'", 2968 "tmp.zig:6:24: note: pointer type child '[*c]const u8' cannot cast into pointer type child '[*]const u8'", 2969 "tmp.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'", 2970 "tmp.zig:13:35: error: expected type '[*c][*c]const u8', found '*[*]u8'", 2971 "tmp.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]const u8'", 2972 "tmp.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'", 2973 }); 2974 2975 cases.add("implicit casting too big integers to C pointers", 2976 \\export fn a() void { 2977 \\ var ptr: [*c]u8 = (1 << 64) + 1; 2978 \\} 2979 \\export fn b() void { 2980 \\ var x: u65 = 0x1234; 2981 \\ var ptr: [*c]u8 = x; 2982 \\} 2983 , &[_][]const u8{ 2984 "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be coerced to type 'usize'", 2985 "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'", 2986 }); 2987 2988 cases.add("C pointer pointing to non C ABI compatible type or has align attr", 2989 \\const Foo = struct {}; 2990 \\export fn a() void { 2991 \\ const T = [*c]Foo; 2992 \\ var t: T = undefined; 2993 \\} 2994 , &[_][]const u8{ 2995 "tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'", 2996 }); 2997 2998 cases.addCase(x: { 2999 var tc = cases.create("compile log statement warning deduplication in generic fn", 3000 \\export fn entry() void { 3001 \\ inner(1); 3002 \\ inner(2); 3003 \\} 3004 \\fn inner(comptime n: usize) void { 3005 \\ comptime var i = 0; 3006 \\ inline while (i < n) : (i += 1) { @compileLog("!@#$"); } 3007 \\} 3008 , &[_][]const u8{ 3009 "tmp.zig:7:39: error: found compile log statement", 3010 }); 3011 tc.expect_exact = true; 3012 break :x tc; 3013 }); 3014 3015 cases.add("assign to invalid dereference", 3016 \\export fn entry() void { 3017 \\ 'a'.* = 1; 3018 \\} 3019 , &[_][]const u8{ 3020 "tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'", 3021 }); 3022 3023 cases.add("take slice of invalid dereference", 3024 \\export fn entry() void { 3025 \\ const x = 'a'.*[0..]; 3026 \\} 3027 , &[_][]const u8{ 3028 "tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'", 3029 }); 3030 3031 cases.add("@truncate undefined value", 3032 \\export fn entry() void { 3033 \\ var z = @truncate(u8, @as(u16, undefined)); 3034 \\} 3035 , &[_][]const u8{ 3036 "tmp.zig:2:27: error: use of undefined value here causes undefined behavior", 3037 }); 3038 3039 cases.addTest("return invalid type from test", 3040 \\test "example" { return 1; } 3041 , &[_][]const u8{ 3042 "tmp.zig:1:25: error: expected type 'void', found 'comptime_int'", 3043 }); 3044 3045 cases.add("threadlocal qualifier on const", 3046 \\threadlocal const x: i32 = 1234; 3047 \\export fn entry() i32 { 3048 \\ return x; 3049 \\} 3050 , &[_][]const u8{ 3051 "tmp.zig:1:13: error: threadlocal variable cannot be constant", 3052 }); 3053 3054 cases.add("@bitCast same size but bit count mismatch", 3055 \\export fn entry(byte: u8) void { 3056 \\ var oops = @bitCast(u7, byte); 3057 \\} 3058 , &[_][]const u8{ 3059 "tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits", 3060 }); 3061 3062 cases.add("@bitCast with different sizes inside an expression", 3063 \\export fn entry() void { 3064 \\ var foo = (@bitCast(u8, @as(f32, 1.0)) == 0xf); 3065 \\} 3066 , &[_][]const u8{ 3067 "tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4", 3068 }); 3069 3070 cases.add("attempted `&&`", 3071 \\export fn entry(a: bool, b: bool) i32 { 3072 \\ if (a && b) { 3073 \\ return 1234; 3074 \\ } 3075 \\ return 5678; 3076 \\} 3077 , &[_][]const u8{ 3078 "tmp.zig:2:12: error: `&&` is invalid. Note that `and` is boolean AND", 3079 }); 3080 3081 cases.add("attempted `||` on boolean values", 3082 \\export fn entry(a: bool, b: bool) i32 { 3083 \\ if (a || b) { 3084 \\ return 1234; 3085 \\ } 3086 \\ return 5678; 3087 \\} 3088 , &[_][]const u8{ 3089 "tmp.zig:2:9: error: expected error set type, found 'bool'", 3090 "tmp.zig:2:11: note: `||` merges error sets; `or` performs boolean OR", 3091 }); 3092 3093 cases.add("compile log a pointer to an opaque value", 3094 \\export fn entry() void { 3095 \\ @compileLog(@ptrCast(*const c_void, &entry)); 3096 \\} 3097 , &[_][]const u8{ 3098 "tmp.zig:2:5: error: found compile log statement", 3099 }); 3100 3101 cases.add("duplicate boolean switch value", 3102 \\comptime { 3103 \\ const x = switch (true) { 3104 \\ true => false, 3105 \\ false => true, 3106 \\ true => false, 3107 \\ }; 3108 \\} 3109 \\comptime { 3110 \\ const x = switch (true) { 3111 \\ false => true, 3112 \\ true => false, 3113 \\ false => true, 3114 \\ }; 3115 \\} 3116 , &[_][]const u8{ 3117 "tmp.zig:5:9: error: duplicate switch value", 3118 "tmp.zig:12:9: error: duplicate switch value", 3119 }); 3120 3121 cases.add("missing boolean switch value", 3122 \\comptime { 3123 \\ const x = switch (true) { 3124 \\ true => false, 3125 \\ }; 3126 \\} 3127 \\comptime { 3128 \\ const x = switch (true) { 3129 \\ false => true, 3130 \\ }; 3131 \\} 3132 , &[_][]const u8{ 3133 "tmp.zig:2:15: error: switch must handle all possibilities", 3134 "tmp.zig:7:15: error: switch must handle all possibilities", 3135 }); 3136 3137 cases.add("reading past end of pointer casted array", 3138 \\comptime { 3139 \\ const array: [4]u8 = "aoeu".*; 3140 \\ const sub_array = array[1..]; 3141 \\ const int_ptr = @ptrCast(*const u24, sub_array); 3142 \\ const deref = int_ptr.*; 3143 \\} 3144 , &[_][]const u8{ 3145 "tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes", 3146 }); 3147 3148 cases.add("error note for function parameter incompatibility", 3149 \\fn do_the_thing(func: fn (arg: i32) void) void {} 3150 \\fn bar(arg: bool) void {} 3151 \\export fn entry() void { 3152 \\ do_the_thing(bar); 3153 \\} 3154 , &[_][]const u8{ 3155 "tmp.zig:4:18: error: expected type 'fn(i32) void', found 'fn(bool) void", 3156 "tmp.zig:4:18: note: parameter 0: 'bool' cannot cast into 'i32'", 3157 }); 3158 cases.add("cast negative value to unsigned integer", 3159 \\comptime { 3160 \\ const value: i32 = -1; 3161 \\ const unsigned = @intCast(u32, value); 3162 \\} 3163 \\export fn entry1() void { 3164 \\ const value: i32 = -1; 3165 \\ const unsigned: u32 = value; 3166 \\} 3167 , &[_][]const u8{ 3168 "tmp.zig:3:22: error: attempt to cast negative value to unsigned integer", 3169 "tmp.zig:7:27: error: cannot cast negative value -1 to unsigned integer type 'u32'", 3170 }); 3171 3172 cases.add("integer cast truncates bits", 3173 \\export fn entry1() void { 3174 \\ const spartan_count: u16 = 300; 3175 \\ const byte = @intCast(u8, spartan_count); 3176 \\} 3177 \\export fn entry2() void { 3178 \\ const spartan_count: u16 = 300; 3179 \\ const byte: u8 = spartan_count; 3180 \\} 3181 \\export fn entry3() void { 3182 \\ var spartan_count: u16 = 300; 3183 \\ var byte: u8 = spartan_count; 3184 \\} 3185 \\export fn entry4() void { 3186 \\ var signed: i8 = -1; 3187 \\ var unsigned: u64 = signed; 3188 \\} 3189 , &[_][]const u8{ 3190 "tmp.zig:3:18: error: cast from 'u16' to 'u8' truncates bits", 3191 "tmp.zig:7:22: error: integer value 300 cannot be coerced to type 'u8'", 3192 "tmp.zig:11:20: error: expected type 'u8', found 'u16'", 3193 "tmp.zig:11:20: note: unsigned 8-bit int cannot represent all possible unsigned 16-bit values", 3194 "tmp.zig:15:25: error: expected type 'u64', found 'i8'", 3195 "tmp.zig:15:25: note: unsigned 64-bit int cannot represent all possible signed 8-bit values", 3196 }); 3197 3198 cases.add("comptime implicit cast f64 to f32", 3199 \\export fn entry() void { 3200 \\ const x: f64 = 16777217; 3201 \\ const y: f32 = x; 3202 \\} 3203 , &[_][]const u8{ 3204 "tmp.zig:3:20: error: cast of value 16777217.000000 to type 'f32' loses information", 3205 }); 3206 3207 cases.add("implicit cast from f64 to f32", 3208 \\var x: f64 = 1.0; 3209 \\var y: f32 = x; 3210 \\ 3211 \\export fn entry() usize { return @sizeOf(@TypeOf(y)); } 3212 , &[_][]const u8{ 3213 "tmp.zig:2:14: error: expected type 'f32', found 'f64'", 3214 }); 3215 3216 cases.add("exceeded maximum bit width of integer", 3217 \\export fn entry1() void { 3218 \\ const T = u65536; 3219 \\} 3220 \\export fn entry2() void { 3221 \\ var x: i65536 = 1; 3222 \\} 3223 , &[_][]const u8{ 3224 "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535", 3225 }); 3226 3227 cases.add("compile error when evaluating return type of inferred error set", 3228 \\const Car = struct { 3229 \\ foo: *SymbolThatDoesNotExist, 3230 \\ pub fn init() !Car {} 3231 \\}; 3232 \\export fn entry() void { 3233 \\ const car = Car.init(); 3234 \\} 3235 , &[_][]const u8{ 3236 "tmp.zig:2:11: error: use of undeclared identifier 'SymbolThatDoesNotExist'", 3237 }); 3238 3239 cases.add("don't implicit cast double pointer to *c_void", 3240 \\export fn entry() void { 3241 \\ var a: u32 = 1; 3242 \\ var ptr: *align(@alignOf(u32)) c_void = &a; 3243 \\ var b: *u32 = @ptrCast(*u32, ptr); 3244 \\ var ptr2: *c_void = &b; 3245 \\} 3246 , &[_][]const u8{ 3247 "tmp.zig:5:26: error: expected type '*c_void', found '**u32'", 3248 }); 3249 3250 cases.add("runtime index into comptime type slice", 3251 \\const Struct = struct { 3252 \\ a: u32, 3253 \\}; 3254 \\fn getIndex() usize { 3255 \\ return 2; 3256 \\} 3257 \\export fn entry() void { 3258 \\ const index = getIndex(); 3259 \\ const field = @typeInfo(Struct).Struct.fields[index]; 3260 \\} 3261 , &[_][]const u8{ 3262 "tmp.zig:9:51: error: values of type 'std.builtin.StructField' must be comptime known, but index value is runtime known", 3263 }); 3264 3265 cases.add("compile log statement inside function which must be comptime evaluated", 3266 \\fn Foo(comptime T: type) type { 3267 \\ @compileLog(@typeName(T)); 3268 \\ return T; 3269 \\} 3270 \\export fn entry() void { 3271 \\ _ = Foo(i32); 3272 \\ _ = @typeName(Foo(i32)); 3273 \\} 3274 , &[_][]const u8{ 3275 "tmp.zig:2:5: error: found compile log statement", 3276 }); 3277 3278 cases.add("comptime slice of an undefined slice", 3279 \\comptime { 3280 \\ var a: []u8 = undefined; 3281 \\ var b = a[0..10]; 3282 \\} 3283 , &[_][]const u8{ 3284 "tmp.zig:3:14: error: slice of undefined", 3285 }); 3286 3287 cases.add("implicit cast const array to mutable slice", 3288 \\export fn entry() void { 3289 \\ const buffer: [1]u8 = [_]u8{8}; 3290 \\ const sliceA: []u8 = &buffer; 3291 \\} 3292 , &[_][]const u8{ 3293 "tmp.zig:3:27: error: expected type '[]u8', found '*const [1]u8'", 3294 }); 3295 3296 cases.add("deref slice and get len field", 3297 \\export fn entry() void { 3298 \\ var a: []u8 = undefined; 3299 \\ _ = a.*.len; 3300 \\} 3301 , &[_][]const u8{ 3302 "tmp.zig:3:10: error: attempt to dereference non-pointer type '[]u8'", 3303 }); 3304 3305 cases.add("@ptrCast a 0 bit type to a non- 0 bit type", 3306 \\export fn entry() bool { 3307 \\ var x: u0 = 0; 3308 \\ const p = @ptrCast(?*u0, &x); 3309 \\ return p == null; 3310 \\} 3311 , &[_][]const u8{ 3312 "tmp.zig:3:15: error: '*u0' and '?*u0' do not have the same in-memory representation", 3313 "tmp.zig:3:31: note: '*u0' has no in-memory bits", 3314 "tmp.zig:3:24: note: '?*u0' has in-memory bits", 3315 }); 3316 3317 cases.add("comparing a non-optional pointer against null", 3318 \\export fn entry() void { 3319 \\ var x: i32 = 1; 3320 \\ _ = &x == null; 3321 \\} 3322 , &[_][]const u8{ 3323 "tmp.zig:3:12: error: comparison of '*i32' with null", 3324 }); 3325 3326 cases.add("non error sets used in merge error sets operator", 3327 \\export fn foo() void { 3328 \\ const Errors = u8 || u16; 3329 \\} 3330 \\export fn bar() void { 3331 \\ const Errors = error{} || u16; 3332 \\} 3333 , &[_][]const u8{ 3334 "tmp.zig:2:20: error: expected error set type, found type 'u8'", 3335 "tmp.zig:2:23: note: `||` merges error sets; `or` performs boolean OR", 3336 "tmp.zig:5:31: error: expected error set type, found type 'u16'", 3337 "tmp.zig:5:28: note: `||` merges error sets; `or` performs boolean OR", 3338 }); 3339 3340 cases.add("variable initialization compile error then referenced", 3341 \\fn Undeclared() type { 3342 \\ return T; 3343 \\} 3344 \\fn Gen() type { 3345 \\ const X = Undeclared(); 3346 \\ return struct { 3347 \\ x: X, 3348 \\ }; 3349 \\} 3350 \\export fn entry() void { 3351 \\ const S = Gen(); 3352 \\} 3353 , &[_][]const u8{ 3354 "tmp.zig:2:12: error: use of undeclared identifier 'T'", 3355 }); 3356 3357 cases.add("refer to the type of a generic function", 3358 \\export fn entry() void { 3359 \\ const Func = fn (type) void; 3360 \\ const f: Func = undefined; 3361 \\ f(i32); 3362 \\} 3363 , &[_][]const u8{ 3364 "tmp.zig:4:5: error: use of undefined value here causes undefined behavior", 3365 }); 3366 3367 cases.add("accessing runtime parameter from outer function", 3368 \\fn outer(y: u32) fn (u32) u32 { 3369 \\ const st = struct { 3370 \\ fn get(z: u32) u32 { 3371 \\ return z + y; 3372 \\ } 3373 \\ }; 3374 \\ return st.get; 3375 \\} 3376 \\export fn entry() void { 3377 \\ var func = outer(10); 3378 \\ var x = func(3); 3379 \\} 3380 , &[_][]const u8{ 3381 "tmp.zig:4:24: error: 'y' not accessible from inner function", 3382 "tmp.zig:3:28: note: crossed function definition here", 3383 "tmp.zig:1:10: note: declared here", 3384 }); 3385 3386 cases.add("non int passed to @intToFloat", 3387 \\export fn entry() void { 3388 \\ const x = @intToFloat(f32, 1.1); 3389 \\} 3390 , &[_][]const u8{ 3391 "tmp.zig:2:32: error: expected int type, found 'comptime_float'", 3392 }); 3393 3394 cases.add("non float passed to @floatToInt", 3395 \\export fn entry() void { 3396 \\ const x = @floatToInt(i32, @as(i32, 54)); 3397 \\} 3398 , &[_][]const u8{ 3399 "tmp.zig:2:32: error: expected float type, found 'i32'", 3400 }); 3401 3402 cases.add("out of range comptime_int passed to @floatToInt", 3403 \\export fn entry() void { 3404 \\ const x = @floatToInt(i8, 200); 3405 \\} 3406 , &[_][]const u8{ 3407 "tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'", 3408 }); 3409 3410 cases.add("load too many bytes from comptime reinterpreted pointer", 3411 \\export fn entry() void { 3412 \\ const float: f32 = 5.99999999999994648725e-01; 3413 \\ const float_ptr = &float; 3414 \\ const int_ptr = @ptrCast(*const i64, float_ptr); 3415 \\ const int_val = int_ptr.*; 3416 \\} 3417 , &[_][]const u8{ 3418 "tmp.zig:5:28: error: attempt to read 8 bytes from pointer to f32 which is 4 bytes", 3419 }); 3420 3421 cases.add("invalid type used in array type", 3422 \\const Item = struct { 3423 \\ field: SomeNonexistentType, 3424 \\}; 3425 \\var items: [100]Item = undefined; 3426 \\export fn entry() void { 3427 \\ const a = items[0]; 3428 \\} 3429 , &[_][]const u8{ 3430 "tmp.zig:2:12: error: use of undeclared identifier 'SomeNonexistentType'", 3431 }); 3432 3433 cases.add("comptime continue inside runtime catch", 3434 \\export fn entry(c: bool) void { 3435 \\ const ints = [_]u8{ 1, 2 }; 3436 \\ inline for (ints) |_| { 3437 \\ bad() catch |_| continue; 3438 \\ } 3439 \\} 3440 \\fn bad() !void { 3441 \\ return error.Bad; 3442 \\} 3443 , &[_][]const u8{ 3444 "tmp.zig:4:25: error: comptime control flow inside runtime block", 3445 "tmp.zig:4:15: note: runtime block created here", 3446 }); 3447 3448 cases.add("comptime continue inside runtime switch", 3449 \\export fn entry() void { 3450 \\ var p: i32 = undefined; 3451 \\ comptime var q = true; 3452 \\ inline while (q) { 3453 \\ switch (p) { 3454 \\ 11 => continue, 3455 \\ else => {}, 3456 \\ } 3457 \\ q = false; 3458 \\ } 3459 \\} 3460 , &[_][]const u8{ 3461 "tmp.zig:6:19: error: comptime control flow inside runtime block", 3462 "tmp.zig:5:9: note: runtime block created here", 3463 }); 3464 3465 cases.add("comptime continue inside runtime while error", 3466 \\export fn entry() void { 3467 \\ var p: anyerror!usize = undefined; 3468 \\ comptime var q = true; 3469 \\ outer: inline while (q) { 3470 \\ while (p) |_| { 3471 \\ continue :outer; 3472 \\ } else |_| {} 3473 \\ q = false; 3474 \\ } 3475 \\} 3476 , &[_][]const u8{ 3477 "tmp.zig:6:13: error: comptime control flow inside runtime block", 3478 "tmp.zig:5:9: note: runtime block created here", 3479 }); 3480 3481 cases.add("comptime continue inside runtime while optional", 3482 \\export fn entry() void { 3483 \\ var p: ?usize = undefined; 3484 \\ comptime var q = true; 3485 \\ outer: inline while (q) { 3486 \\ while (p) |_| continue :outer; 3487 \\ q = false; 3488 \\ } 3489 \\} 3490 , &[_][]const u8{ 3491 "tmp.zig:5:23: error: comptime control flow inside runtime block", 3492 "tmp.zig:5:9: note: runtime block created here", 3493 }); 3494 3495 cases.add("comptime continue inside runtime while bool", 3496 \\export fn entry() void { 3497 \\ var p: usize = undefined; 3498 \\ comptime var q = true; 3499 \\ outer: inline while (q) { 3500 \\ while (p == 11) continue :outer; 3501 \\ q = false; 3502 \\ } 3503 \\} 3504 , &[_][]const u8{ 3505 "tmp.zig:5:25: error: comptime control flow inside runtime block", 3506 "tmp.zig:5:9: note: runtime block created here", 3507 }); 3508 3509 cases.add("comptime continue inside runtime if error", 3510 \\export fn entry() void { 3511 \\ var p: anyerror!i32 = undefined; 3512 \\ comptime var q = true; 3513 \\ inline while (q) { 3514 \\ if (p) |_| continue else |_| {} 3515 \\ q = false; 3516 \\ } 3517 \\} 3518 , &[_][]const u8{ 3519 "tmp.zig:5:20: error: comptime control flow inside runtime block", 3520 "tmp.zig:5:9: note: runtime block created here", 3521 }); 3522 3523 cases.add("comptime continue inside runtime if optional", 3524 \\export fn entry() void { 3525 \\ var p: ?i32 = undefined; 3526 \\ comptime var q = true; 3527 \\ inline while (q) { 3528 \\ if (p) |_| continue; 3529 \\ q = false; 3530 \\ } 3531 \\} 3532 , &[_][]const u8{ 3533 "tmp.zig:5:20: error: comptime control flow inside runtime block", 3534 "tmp.zig:5:9: note: runtime block created here", 3535 }); 3536 3537 cases.add("comptime continue inside runtime if bool", 3538 \\export fn entry() void { 3539 \\ var p: usize = undefined; 3540 \\ comptime var q = true; 3541 \\ inline while (q) { 3542 \\ if (p == 11) continue; 3543 \\ q = false; 3544 \\ } 3545 \\} 3546 , &[_][]const u8{ 3547 "tmp.zig:5:22: error: comptime control flow inside runtime block", 3548 "tmp.zig:5:9: note: runtime block created here", 3549 }); 3550 3551 cases.add("switch with invalid expression parameter", 3552 \\export fn entry() void { 3553 \\ Test(i32); 3554 \\} 3555 \\fn Test(comptime T: type) void { 3556 \\ const x = switch (T) { 3557 \\ []u8 => |x| 123, 3558 \\ i32 => |x| 456, 3559 \\ else => unreachable, 3560 \\ }; 3561 \\} 3562 , &[_][]const u8{ 3563 "tmp.zig:7:17: error: switch on type 'type' provides no expression parameter", 3564 }); 3565 3566 cases.add("function prototype with no body", 3567 \\fn foo() void; 3568 \\export fn entry() void { 3569 \\ foo(); 3570 \\} 3571 , &[_][]const u8{ 3572 "tmp.zig:1:1: error: non-extern function has no body", 3573 }); 3574 3575 cases.add("@frame() called outside of function definition", 3576 \\var handle_undef: anyframe = undefined; 3577 \\var handle_dummy: anyframe = @frame(); 3578 \\export fn entry() bool { 3579 \\ return handle_undef == handle_dummy; 3580 \\} 3581 , &[_][]const u8{ 3582 "tmp.zig:2:30: error: @frame() called outside of function definition", 3583 }); 3584 3585 cases.add("`_` is not a declarable symbol", 3586 \\export fn f1() usize { 3587 \\ var _: usize = 2; 3588 \\ return _; 3589 \\} 3590 , &[_][]const u8{ 3591 "tmp.zig:2:5: error: `_` is not a declarable symbol", 3592 }); 3593 3594 cases.add("`_` should not be usable inside for", 3595 \\export fn returns() void { 3596 \\ for ([_]void{}) |_, i| { 3597 \\ for ([_]void{}) |_, j| { 3598 \\ return _; 3599 \\ } 3600 \\ } 3601 \\} 3602 , &[_][]const u8{ 3603 "tmp.zig:4:20: error: `_` may only be used to assign things to", 3604 }); 3605 3606 cases.add("`_` should not be usable inside while", 3607 \\export fn returns() void { 3608 \\ while (optionalReturn()) |_| { 3609 \\ while (optionalReturn()) |_| { 3610 \\ return _; 3611 \\ } 3612 \\ } 3613 \\} 3614 \\fn optionalReturn() ?u32 { 3615 \\ return 1; 3616 \\} 3617 , &[_][]const u8{ 3618 "tmp.zig:4:20: error: `_` may only be used to assign things to", 3619 }); 3620 3621 cases.add("`_` should not be usable inside while else", 3622 \\export fn returns() void { 3623 \\ while (optionalReturnError()) |_| { 3624 \\ while (optionalReturnError()) |_| { 3625 \\ return; 3626 \\ } else |_| { 3627 \\ if (_ == error.optionalReturnError) return; 3628 \\ } 3629 \\ } 3630 \\} 3631 \\fn optionalReturnError() !?u32 { 3632 \\ return error.optionalReturnError; 3633 \\} 3634 , &[_][]const u8{ 3635 "tmp.zig:6:17: error: `_` may only be used to assign things to", 3636 }); 3637 3638 cases.add("while loop body expression ignored", 3639 \\fn returns() usize { 3640 \\ return 2; 3641 \\} 3642 \\export fn f1() void { 3643 \\ while (true) returns(); 3644 \\} 3645 \\export fn f2() void { 3646 \\ var x: ?i32 = null; 3647 \\ while (x) |_| returns(); 3648 \\} 3649 \\export fn f3() void { 3650 \\ var x: anyerror!i32 = error.Bad; 3651 \\ while (x) |_| returns() else |_| unreachable; 3652 \\} 3653 , &[_][]const u8{ 3654 "tmp.zig:5:25: error: expression value is ignored", 3655 "tmp.zig:9:26: error: expression value is ignored", 3656 "tmp.zig:13:26: error: expression value is ignored", 3657 }); 3658 3659 cases.add("missing parameter name of generic function", 3660 \\fn dump(anytype) void {} 3661 \\export fn entry() void { 3662 \\ var a: u8 = 9; 3663 \\ dump(a); 3664 \\} 3665 , &[_][]const u8{ 3666 "tmp.zig:1:9: error: missing parameter name", 3667 }); 3668 3669 cases.add("non-inline for loop on a type that requires comptime", 3670 \\const Foo = struct { 3671 \\ name: []const u8, 3672 \\ T: type, 3673 \\}; 3674 \\export fn entry() void { 3675 \\ const xx: [2]Foo = undefined; 3676 \\ for (xx) |f| {} 3677 \\} 3678 , &[_][]const u8{ 3679 "tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known", 3680 }); 3681 3682 cases.add("generic fn as parameter without comptime keyword", 3683 \\fn f(_: fn (anytype) void) void {} 3684 \\fn g(_: anytype) void {} 3685 \\export fn entry() void { 3686 \\ f(g); 3687 \\} 3688 , &[_][]const u8{ 3689 "tmp.zig:1:9: error: parameter of type 'fn(anytype) anytype' must be declared comptime", 3690 }); 3691 3692 cases.add("optional pointer to void in extern struct", 3693 \\const Foo = extern struct { 3694 \\ x: ?*const void, 3695 \\}; 3696 \\const Bar = extern struct { 3697 \\ foo: Foo, 3698 \\ y: i32, 3699 \\}; 3700 \\export fn entry(bar: *Bar) void {} 3701 , &[_][]const u8{ 3702 "tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void'", 3703 }); 3704 3705 cases.add("use of comptime-known undefined function value", 3706 \\const Cmd = struct { 3707 \\ exec: fn () void, 3708 \\}; 3709 \\export fn entry() void { 3710 \\ const command = Cmd{ .exec = undefined }; 3711 \\ command.exec(); 3712 \\} 3713 , &[_][]const u8{ 3714 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior", 3715 }); 3716 3717 cases.add("use of comptime-known undefined function value", 3718 \\const Cmd = struct { 3719 \\ exec: fn () void, 3720 \\}; 3721 \\export fn entry() void { 3722 \\ const command = Cmd{ .exec = undefined }; 3723 \\ command.exec(); 3724 \\} 3725 , &[_][]const u8{ 3726 "tmp.zig:6:12: error: use of undefined value here causes undefined behavior", 3727 }); 3728 3729 cases.add("bad @alignCast at comptime", 3730 \\comptime { 3731 \\ const ptr = @intToPtr(*align(1) i32, 0x1); 3732 \\ const aligned = @alignCast(4, ptr); 3733 \\} 3734 , &[_][]const u8{ 3735 "tmp.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes", 3736 }); 3737 3738 cases.add("@ptrToInt on *void", 3739 \\export fn entry() bool { 3740 \\ return @ptrToInt(&{}) == @ptrToInt(&{}); 3741 \\} 3742 , &[_][]const u8{ 3743 "tmp.zig:2:23: error: pointer to size 0 type has no address", 3744 }); 3745 3746 cases.add("@popCount - non-integer", 3747 \\export fn entry(x: f32) u32 { 3748 \\ return @popCount(f32, x); 3749 \\} 3750 , &[_][]const u8{ 3751 "tmp.zig:2:22: error: expected integer type, found 'f32'", 3752 }); 3753 3754 cases.addCase(x: { 3755 const tc = cases.create("wrong same named struct", 3756 \\const a = @import("a.zig"); 3757 \\const b = @import("b.zig"); 3758 \\ 3759 \\export fn entry() void { 3760 \\ var a1: a.Foo = undefined; 3761 \\ bar(&a1); 3762 \\} 3763 \\ 3764 \\fn bar(x: *b.Foo) void {} 3765 , &[_][]const u8{ 3766 "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'", 3767 "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", 3768 "a.zig:1:17: note: a.Foo declared here", 3769 "b.zig:1:17: note: b.Foo declared here", 3770 }); 3771 3772 tc.addSourceFile("a.zig", 3773 \\pub const Foo = struct { 3774 \\ x: i32, 3775 \\}; 3776 ); 3777 3778 tc.addSourceFile("b.zig", 3779 \\pub const Foo = struct { 3780 \\ z: f64, 3781 \\}; 3782 ); 3783 3784 break :x tc; 3785 }); 3786 3787 cases.add("@floatToInt comptime safety", 3788 \\comptime { 3789 \\ _ = @floatToInt(i8, @as(f32, -129.1)); 3790 \\} 3791 \\comptime { 3792 \\ _ = @floatToInt(u8, @as(f32, -1.1)); 3793 \\} 3794 \\comptime { 3795 \\ _ = @floatToInt(u8, @as(f32, 256.1)); 3796 \\} 3797 , &[_][]const u8{ 3798 "tmp.zig:2:9: error: integer value '-129' cannot be stored in type 'i8'", 3799 "tmp.zig:5:9: error: integer value '-1' cannot be stored in type 'u8'", 3800 "tmp.zig:8:9: error: integer value '256' cannot be stored in type 'u8'", 3801 }); 3802 3803 cases.add("use c_void as return type of fn ptr", 3804 \\export fn entry() void { 3805 \\ const a: fn () c_void = undefined; 3806 \\} 3807 , &[_][]const u8{ 3808 "tmp.zig:2:20: error: return type cannot be opaque", 3809 }); 3810 3811 cases.add("use implicit casts to assign null to non-nullable pointer", 3812 \\export fn entry() void { 3813 \\ var x: i32 = 1234; 3814 \\ var p: *i32 = &x; 3815 \\ var pp: *?*i32 = &p; 3816 \\ pp.* = null; 3817 \\ var y = p.*; 3818 \\} 3819 , &[_][]const u8{ 3820 "tmp.zig:4:23: error: expected type '*?*i32', found '**i32'", 3821 }); 3822 3823 cases.add("attempted implicit cast from T to [*]const T", 3824 \\export fn entry() void { 3825 \\ const x: [*]const bool = true; 3826 \\} 3827 , &[_][]const u8{ 3828 "tmp.zig:2:30: error: expected type '[*]const bool', found 'bool'", 3829 }); 3830 3831 cases.add("dereference unknown length pointer", 3832 \\export fn entry(x: [*]i32) i32 { 3833 \\ return x.*; 3834 \\} 3835 , &[_][]const u8{ 3836 "tmp.zig:2:13: error: index syntax required for unknown-length pointer type '[*]i32'", 3837 }); 3838 3839 cases.add("field access of unknown length pointer", 3840 \\const Foo = extern struct { 3841 \\ a: i32, 3842 \\}; 3843 \\ 3844 \\export fn entry(foo: [*]Foo) void { 3845 \\ foo.a += 1; 3846 \\} 3847 , &[_][]const u8{ 3848 "tmp.zig:6:8: error: type '[*]Foo' does not support field access", 3849 }); 3850 3851 cases.add("unknown length pointer to opaque", 3852 \\export const T = [*]opaque {}; 3853 , &[_][]const u8{ 3854 "tmp.zig:1:21: error: unknown-length pointer to opaque", 3855 }); 3856 3857 cases.add("error when evaluating return type", 3858 \\const Foo = struct { 3859 \\ map: @as(i32, i32), 3860 \\ 3861 \\ fn init() Foo { 3862 \\ return undefined; 3863 \\ } 3864 \\}; 3865 \\export fn entry() void { 3866 \\ var rule_set = try Foo.init(); 3867 \\} 3868 , &[_][]const u8{ 3869 "tmp.zig:2:19: error: expected type 'i32', found 'type'", 3870 }); 3871 3872 cases.add("slicing single-item pointer", 3873 \\export fn entry(ptr: *i32) void { 3874 \\ const slice = ptr[0..2]; 3875 \\} 3876 , &[_][]const u8{ 3877 "tmp.zig:2:22: error: slice of single-item pointer", 3878 }); 3879 3880 cases.add("indexing single-item pointer", 3881 \\export fn entry(ptr: *i32) i32 { 3882 \\ return ptr[1]; 3883 \\} 3884 , &[_][]const u8{ 3885 "tmp.zig:2:15: error: index of single-item pointer", 3886 }); 3887 3888 cases.add("nested error set mismatch", 3889 \\const NextError = error{NextError}; 3890 \\const OtherError = error{OutOfMemory}; 3891 \\ 3892 \\export fn entry() void { 3893 \\ const a: ?NextError!i32 = foo(); 3894 \\} 3895 \\ 3896 \\fn foo() ?OtherError!i32 { 3897 \\ return null; 3898 \\} 3899 , &[_][]const u8{ 3900 "tmp.zig:5:34: error: expected type '?NextError!i32', found '?OtherError!i32'", 3901 "tmp.zig:5:34: note: optional type child 'OtherError!i32' cannot cast into optional type child 'NextError!i32'", 3902 "tmp.zig:5:34: note: error set 'OtherError' cannot cast into error set 'NextError'", 3903 "tmp.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set", 3904 }); 3905 3906 cases.add("invalid deref on switch target", 3907 \\comptime { 3908 \\ var tile = Tile.Empty; 3909 \\ switch (tile.*) { 3910 \\ Tile.Empty => {}, 3911 \\ Tile.Filled => {}, 3912 \\ } 3913 \\} 3914 \\const Tile = enum { 3915 \\ Empty, 3916 \\ Filled, 3917 \\}; 3918 , &[_][]const u8{ 3919 "tmp.zig:3:17: error: attempt to dereference non-pointer type 'Tile'", 3920 }); 3921 3922 cases.add("invalid field access in comptime", 3923 \\comptime { var x = doesnt_exist.whatever; } 3924 , &[_][]const u8{ 3925 "tmp.zig:1:20: error: use of undeclared identifier 'doesnt_exist'", 3926 }); 3927 3928 cases.add("suspend inside suspend block", 3929 \\export fn entry() void { 3930 \\ _ = async foo(); 3931 \\} 3932 \\fn foo() void { 3933 \\ suspend { 3934 \\ suspend { 3935 \\ } 3936 \\ } 3937 \\} 3938 , &[_][]const u8{ 3939 "tmp.zig:6:9: error: cannot suspend inside suspend block", 3940 "tmp.zig:5:5: note: other suspend block here", 3941 }); 3942 3943 cases.add("assign inline fn to non-comptime var", 3944 \\export fn entry() void { 3945 \\ var a = b; 3946 \\} 3947 \\inline fn b() void { } 3948 , &[_][]const u8{ 3949 "tmp.zig:2:5: error: functions marked inline must be stored in const or comptime var", 3950 "tmp.zig:4:1: note: declared here", 3951 }); 3952 3953 cases.add("wrong type passed to @panic", 3954 \\export fn entry() void { 3955 \\ var e = error.Foo; 3956 \\ @panic(e); 3957 \\} 3958 , &[_][]const u8{ 3959 "tmp.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'", 3960 }); 3961 3962 cases.add("@tagName used on union with no associated enum tag", 3963 \\const FloatInt = extern union { 3964 \\ Float: f32, 3965 \\ Int: i32, 3966 \\}; 3967 \\export fn entry() void { 3968 \\ var fi = FloatInt{.Float = 123.45}; 3969 \\ var tagName = @tagName(fi); 3970 \\} 3971 , &[_][]const u8{ 3972 "tmp.zig:7:19: error: union has no associated enum", 3973 "tmp.zig:1:18: note: declared here", 3974 }); 3975 3976 cases.add("returning error from void async function", 3977 \\export fn entry() void { 3978 \\ _ = async amain(); 3979 \\} 3980 \\fn amain() callconv(.Async) void { 3981 \\ return error.ShouldBeCompileError; 3982 \\} 3983 , &[_][]const u8{ 3984 "tmp.zig:5:17: error: expected type 'void', found 'error{ShouldBeCompileError}'", 3985 }); 3986 3987 cases.add("var makes structs required to be comptime known", 3988 \\export fn entry() void { 3989 \\ const S = struct{v: anytype}; 3990 \\ var s = S{.v=@as(i32, 10)}; 3991 \\} 3992 , &[_][]const u8{ 3993 "tmp.zig:3:4: error: variable of type 'S' must be const or comptime", 3994 }); 3995 3996 cases.add("@ptrCast discards const qualifier", 3997 \\export fn entry() void { 3998 \\ const x: i32 = 1234; 3999 \\ const y = @ptrCast(*i32, &x); 4000 \\} 4001 , &[_][]const u8{ 4002 "tmp.zig:3:15: error: cast discards const qualifier", 4003 }); 4004 4005 cases.add("comptime slice of undefined pointer non-zero len", 4006 \\export fn entry() void { 4007 \\ const slice = @as([*]i32, undefined)[0..1]; 4008 \\} 4009 , &[_][]const u8{ 4010 "tmp.zig:2:41: error: non-zero length slice of undefined pointer", 4011 }); 4012 4013 cases.add("type checking function pointers", 4014 \\fn a(b: fn (*const u8) void) void { 4015 \\ b('a'); 4016 \\} 4017 \\fn c(d: u8) void {} 4018 \\export fn entry() void { 4019 \\ a(c); 4020 \\} 4021 , &[_][]const u8{ 4022 "tmp.zig:6:7: error: expected type 'fn(*const u8) void', found 'fn(u8) void'", 4023 }); 4024 4025 cases.add("no else prong on switch on global error set", 4026 \\export fn entry() void { 4027 \\ foo(error.A); 4028 \\} 4029 \\fn foo(a: anyerror) void { 4030 \\ switch (a) { 4031 \\ error.A => {}, 4032 \\ } 4033 \\} 4034 , &[_][]const u8{ 4035 "tmp.zig:5:5: error: else prong required when switching on type 'anyerror'", 4036 }); 4037 4038 cases.add("error not handled in switch", 4039 \\export fn entry() void { 4040 \\ foo(452) catch |err| switch (err) { 4041 \\ error.Foo => {}, 4042 \\ }; 4043 \\} 4044 \\fn foo(x: i32) !void { 4045 \\ switch (x) { 4046 \\ 0 ... 10 => return error.Foo, 4047 \\ 11 ... 20 => return error.Bar, 4048 \\ 21 ... 30 => return error.Baz, 4049 \\ else => {}, 4050 \\ } 4051 \\} 4052 , &[_][]const u8{ 4053 "tmp.zig:2:26: error: error.Baz not handled in switch", 4054 "tmp.zig:2:26: error: error.Bar not handled in switch", 4055 }); 4056 4057 cases.add("duplicate error in switch", 4058 \\export fn entry() void { 4059 \\ foo(452) catch |err| switch (err) { 4060 \\ error.Foo => {}, 4061 \\ error.Bar => {}, 4062 \\ error.Foo => {}, 4063 \\ else => {}, 4064 \\ }; 4065 \\} 4066 \\fn foo(x: i32) !void { 4067 \\ switch (x) { 4068 \\ 0 ... 10 => return error.Foo, 4069 \\ 11 ... 20 => return error.Bar, 4070 \\ else => {}, 4071 \\ } 4072 \\} 4073 , &[_][]const u8{ 4074 "tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo'", 4075 "tmp.zig:3:14: note: other value is here", 4076 }); 4077 4078 cases.add("invalid cast from integral type to enum", 4079 \\const E = enum(usize) { One, Two }; 4080 \\ 4081 \\export fn entry() void { 4082 \\ foo(1); 4083 \\} 4084 \\ 4085 \\fn foo(x: usize) void { 4086 \\ switch (x) { 4087 \\ E.One => {}, 4088 \\ } 4089 \\} 4090 , &[_][]const u8{ 4091 "tmp.zig:9:10: error: expected type 'usize', found 'E'", 4092 }); 4093 4094 cases.add("range operator in switch used on error set", 4095 \\export fn entry() void { 4096 \\ try foo(452) catch |err| switch (err) { 4097 \\ error.A ... error.B => {}, 4098 \\ else => {}, 4099 \\ }; 4100 \\} 4101 \\fn foo(x: i32) !void { 4102 \\ switch (x) { 4103 \\ 0 ... 10 => return error.Foo, 4104 \\ 11 ... 20 => return error.Bar, 4105 \\ else => {}, 4106 \\ } 4107 \\} 4108 , &[_][]const u8{ 4109 "tmp.zig:3:17: error: operator not allowed for errors", 4110 }); 4111 4112 cases.add("inferring error set of function pointer", 4113 \\comptime { 4114 \\ const z: ?fn()!void = null; 4115 \\} 4116 , &[_][]const u8{ 4117 "tmp.zig:2:15: error: inferring error set of return type valid only for function definitions", 4118 }); 4119 4120 cases.add("access non-existent member of error set", 4121 \\const Foo = error{A}; 4122 \\comptime { 4123 \\ const z = Foo.Bar; 4124 \\} 4125 , &[_][]const u8{ 4126 "tmp.zig:3:18: error: no error named 'Bar' in 'Foo'", 4127 }); 4128 4129 cases.add("error union operator with non error set LHS", 4130 \\comptime { 4131 \\ const z = i32!i32; 4132 \\ var x: z = undefined; 4133 \\} 4134 , &[_][]const u8{ 4135 "tmp.zig:2:15: error: expected error set type, found type 'i32'", 4136 }); 4137 4138 cases.add("error equality but sets have no common members", 4139 \\const Set1 = error{A, C}; 4140 \\const Set2 = error{B, D}; 4141 \\export fn entry() void { 4142 \\ foo(Set1.A); 4143 \\} 4144 \\fn foo(x: Set1) void { 4145 \\ if (x == Set2.B) { 4146 \\ 4147 \\ } 4148 \\} 4149 , &[_][]const u8{ 4150 "tmp.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors", 4151 }); 4152 4153 cases.add("only equality binary operator allowed for error sets", 4154 \\comptime { 4155 \\ const z = error.A > error.B; 4156 \\} 4157 , &[_][]const u8{ 4158 "tmp.zig:2:23: error: operator not allowed for errors", 4159 }); 4160 4161 cases.add("explicit error set cast known at comptime violates error sets", 4162 \\const Set1 = error {A, B}; 4163 \\const Set2 = error {A, C}; 4164 \\comptime { 4165 \\ var x = Set1.B; 4166 \\ var y = @errSetCast(Set2, x); 4167 \\} 4168 , &[_][]const u8{ 4169 "tmp.zig:5:13: error: error.B not a member of error set 'Set2'", 4170 }); 4171 4172 cases.add("cast error union of global error set to error union of smaller error set", 4173 \\const SmallErrorSet = error{A}; 4174 \\export fn entry() void { 4175 \\ var x: SmallErrorSet!i32 = foo(); 4176 \\} 4177 \\fn foo() anyerror!i32 { 4178 \\ return error.B; 4179 \\} 4180 , &[_][]const u8{ 4181 "tmp.zig:3:35: error: expected type 'SmallErrorSet!i32', found 'anyerror!i32'", 4182 "tmp.zig:3:35: note: error set 'anyerror' cannot cast into error set 'SmallErrorSet'", 4183 "tmp.zig:3:35: note: cannot cast global error set into smaller set", 4184 }); 4185 4186 cases.add("cast global error set to error set", 4187 \\const SmallErrorSet = error{A}; 4188 \\export fn entry() void { 4189 \\ var x: SmallErrorSet = foo(); 4190 \\} 4191 \\fn foo() anyerror { 4192 \\ return error.B; 4193 \\} 4194 , &[_][]const u8{ 4195 "tmp.zig:3:31: error: expected type 'SmallErrorSet', found 'anyerror'", 4196 "tmp.zig:3:31: note: cannot cast global error set into smaller set", 4197 }); 4198 cases.add("recursive inferred error set", 4199 \\export fn entry() void { 4200 \\ foo() catch unreachable; 4201 \\} 4202 \\fn foo() !void { 4203 \\ try foo(); 4204 \\} 4205 , &[_][]const u8{ 4206 "tmp.zig:5:5: error: cannot resolve inferred error set '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set': function 'foo' not fully analyzed yet", 4207 }); 4208 4209 cases.add("implicit cast of error set not a subset", 4210 \\const Set1 = error{A, B}; 4211 \\const Set2 = error{A, C}; 4212 \\export fn entry() void { 4213 \\ foo(Set1.B); 4214 \\} 4215 \\fn foo(set1: Set1) void { 4216 \\ var x: Set2 = set1; 4217 \\} 4218 , &[_][]const u8{ 4219 "tmp.zig:7:19: error: expected type 'Set2', found 'Set1'", 4220 "tmp.zig:1:23: note: 'error.B' not a member of destination error set", 4221 }); 4222 4223 cases.add("int to err global invalid number", 4224 \\const Set1 = error{ 4225 \\ A, 4226 \\ B, 4227 \\}; 4228 \\comptime { 4229 \\ var x: u16 = 3; 4230 \\ var y = @intToError(x); 4231 \\} 4232 , &[_][]const u8{ 4233 "tmp.zig:7:13: error: integer value 3 represents no error", 4234 }); 4235 4236 cases.add("int to err non global invalid number", 4237 \\const Set1 = error{ 4238 \\ A, 4239 \\ B, 4240 \\}; 4241 \\const Set2 = error{ 4242 \\ A, 4243 \\ C, 4244 \\}; 4245 \\comptime { 4246 \\ var x = @errorToInt(Set1.B); 4247 \\ var y = @errSetCast(Set2, @intToError(x)); 4248 \\} 4249 , &[_][]const u8{ 4250 "tmp.zig:11:13: error: error.B not a member of error set 'Set2'", 4251 }); 4252 4253 cases.add("duplicate error value in error set", 4254 \\const Foo = error { 4255 \\ Bar, 4256 \\ Bar, 4257 \\}; 4258 \\export fn entry() void { 4259 \\ const a: Foo = undefined; 4260 \\} 4261 , &[_][]const u8{ 4262 "tmp.zig:3:5: error: duplicate error: 'Bar'", 4263 "tmp.zig:2:5: note: other error here", 4264 }); 4265 4266 cases.add("cast negative integer literal to usize", 4267 \\export fn entry() void { 4268 \\ const x = @as(usize, -10); 4269 \\} 4270 , &[_][]const u8{ 4271 "tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'", 4272 }); 4273 4274 cases.add("use invalid number literal as array index", 4275 \\var v = 25; 4276 \\export fn entry() void { 4277 \\ var arr: [v]u8 = undefined; 4278 \\} 4279 , &[_][]const u8{ 4280 "tmp.zig:1:1: error: unable to infer variable type", 4281 }); 4282 4283 cases.add("duplicate struct field", 4284 \\const Foo = struct { 4285 \\ Bar: i32, 4286 \\ Bar: usize, 4287 \\}; 4288 \\export fn entry() void { 4289 \\ const a: Foo = undefined; 4290 \\} 4291 , &[_][]const u8{ 4292 "tmp.zig:3:5: error: duplicate struct field: 'Bar'", 4293 "tmp.zig:2:5: note: other field here", 4294 }); 4295 4296 cases.add("duplicate union field", 4297 \\const Foo = union { 4298 \\ Bar: i32, 4299 \\ Bar: usize, 4300 \\}; 4301 \\export fn entry() void { 4302 \\ const a: Foo = undefined; 4303 \\} 4304 , &[_][]const u8{ 4305 "tmp.zig:3:5: error: duplicate union field: 'Bar'", 4306 "tmp.zig:2:5: note: other field here", 4307 }); 4308 4309 cases.add("duplicate enum field", 4310 \\const Foo = enum { 4311 \\ Bar, 4312 \\ Bar, 4313 \\}; 4314 \\ 4315 \\export fn entry() void { 4316 \\ const a: Foo = undefined; 4317 \\} 4318 , &[_][]const u8{ 4319 "tmp.zig:3:5: error: duplicate enum field: 'Bar'", 4320 "tmp.zig:2:5: note: other field here", 4321 }); 4322 4323 cases.add("calling function with naked calling convention", 4324 \\export fn entry() void { 4325 \\ foo(); 4326 \\} 4327 \\fn foo() callconv(.Naked) void { } 4328 , &[_][]const u8{ 4329 "tmp.zig:2:5: error: unable to call function with naked calling convention", 4330 "tmp.zig:4:1: note: declared here", 4331 }); 4332 4333 cases.add("function with invalid return type", 4334 \\export fn foo() boid {} 4335 , &[_][]const u8{ 4336 "tmp.zig:1:17: error: use of undeclared identifier 'boid'", 4337 }); 4338 4339 cases.add("function with non-extern non-packed enum parameter", 4340 \\const Foo = enum { A, B, C }; 4341 \\export fn entry(foo: Foo) void { } 4342 , &[_][]const u8{ 4343 "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", 4344 }); 4345 4346 cases.add("function with non-extern non-packed struct parameter", 4347 \\const Foo = struct { 4348 \\ A: i32, 4349 \\ B: f32, 4350 \\ C: bool, 4351 \\}; 4352 \\export fn entry(foo: Foo) void { } 4353 , &[_][]const u8{ 4354 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", 4355 }); 4356 4357 cases.add("function with non-extern non-packed union parameter", 4358 \\const Foo = union { 4359 \\ A: i32, 4360 \\ B: f32, 4361 \\ C: bool, 4362 \\}; 4363 \\export fn entry(foo: Foo) void { } 4364 , &[_][]const u8{ 4365 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", 4366 }); 4367 4368 cases.add("switch on enum with 1 field with no prongs", 4369 \\const Foo = enum { M }; 4370 \\ 4371 \\export fn entry() void { 4372 \\ var f = Foo.M; 4373 \\ switch (f) {} 4374 \\} 4375 , &[_][]const u8{ 4376 "tmp.zig:5:5: error: enumeration value 'Foo.M' not handled in switch", 4377 }); 4378 4379 cases.add("shift by negative comptime integer", 4380 \\comptime { 4381 \\ var a = 1 >> -1; 4382 \\} 4383 , &[_][]const u8{ 4384 "tmp.zig:2:18: error: shift by negative value -1", 4385 }); 4386 4387 cases.add("@panic called at compile time", 4388 \\export fn entry() void { 4389 \\ comptime { 4390 \\ @panic("aoeu",); 4391 \\ } 4392 \\} 4393 , &[_][]const u8{ 4394 "tmp.zig:3:9: error: encountered @panic at compile-time", 4395 }); 4396 4397 cases.add("wrong return type for main", 4398 \\pub fn main() f32 { } 4399 , &[_][]const u8{ 4400 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'", 4401 }); 4402 4403 cases.add("double ?? on main return value", 4404 \\pub fn main() ??void { 4405 \\} 4406 , &[_][]const u8{ 4407 "error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'", 4408 }); 4409 4410 cases.add("bad identifier in function with struct defined inside function which references local const", 4411 \\export fn entry() void { 4412 \\ const BlockKind = u32; 4413 \\ 4414 \\ const Block = struct { 4415 \\ kind: BlockKind, 4416 \\ }; 4417 \\ 4418 \\ bogus; 4419 \\} 4420 , &[_][]const u8{ 4421 "tmp.zig:8:5: error: use of undeclared identifier 'bogus'", 4422 }); 4423 4424 cases.add("labeled break not found", 4425 \\export fn entry() void { 4426 \\ blah: while (true) { 4427 \\ while (true) { 4428 \\ break :outer; 4429 \\ } 4430 \\ } 4431 \\} 4432 , &[_][]const u8{ 4433 "tmp.zig:4:13: error: label not found: 'outer'", 4434 }); 4435 4436 cases.add("labeled continue not found", 4437 \\export fn entry() void { 4438 \\ var i: usize = 0; 4439 \\ blah: while (i < 10) : (i += 1) { 4440 \\ while (true) { 4441 \\ continue :outer; 4442 \\ } 4443 \\ } 4444 \\} 4445 , &[_][]const u8{ 4446 "tmp.zig:5:13: error: labeled loop not found: 'outer'", 4447 }); 4448 4449 cases.add("attempt to use 0 bit type in extern fn", 4450 \\extern fn foo(ptr: fn(*void) callconv(.C) void) void; 4451 \\ 4452 \\export fn entry() void { 4453 \\ foo(bar); 4454 \\} 4455 \\ 4456 \\fn bar(x: *void) callconv(.C) void { } 4457 \\export fn entry2() void { 4458 \\ bar(&{}); 4459 \\} 4460 , &[_][]const u8{ 4461 "tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'", 4462 "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'", 4463 }); 4464 4465 cases.add("implicit semicolon - block statement", 4466 \\export fn entry() void { 4467 \\ {} 4468 \\ var good = {}; 4469 \\ ({}) 4470 \\ var bad = {}; 4471 \\} 4472 , &[_][]const u8{ 4473 "tmp.zig:5:5: error: expected token ';', found 'var'", 4474 }); 4475 4476 cases.add("implicit semicolon - block expr", 4477 \\export fn entry() void { 4478 \\ _ = {}; 4479 \\ var good = {}; 4480 \\ _ = {} 4481 \\ var bad = {}; 4482 \\} 4483 , &[_][]const u8{ 4484 "tmp.zig:5:5: error: expected token ';', found 'var'", 4485 }); 4486 4487 cases.add("implicit semicolon - comptime statement", 4488 \\export fn entry() void { 4489 \\ comptime {} 4490 \\ var good = {}; 4491 \\ comptime ({}) 4492 \\ var bad = {}; 4493 \\} 4494 , &[_][]const u8{ 4495 "tmp.zig:5:5: error: expected token ';', found 'var'", 4496 }); 4497 4498 cases.add("implicit semicolon - comptime expression", 4499 \\export fn entry() void { 4500 \\ _ = comptime {}; 4501 \\ var good = {}; 4502 \\ _ = comptime {} 4503 \\ var bad = {}; 4504 \\} 4505 , &[_][]const u8{ 4506 "tmp.zig:5:5: error: expected token ';', found 'var'", 4507 }); 4508 4509 cases.add("implicit semicolon - defer", 4510 \\export fn entry() void { 4511 \\ defer {} 4512 \\ var good = {}; 4513 \\ defer ({}) 4514 \\ var bad = {}; 4515 \\} 4516 , &[_][]const u8{ 4517 "tmp.zig:5:5: error: expected token ';', found 'var'", 4518 }); 4519 4520 cases.add("implicit semicolon - if statement", 4521 \\export fn entry() void { 4522 \\ if(true) {} 4523 \\ var good = {}; 4524 \\ if(true) ({}) 4525 \\ var bad = {}; 4526 \\} 4527 , &[_][]const u8{ 4528 "tmp.zig:5:5: error: expected token ';', found 'var'", 4529 }); 4530 4531 cases.add("implicit semicolon - if expression", 4532 \\export fn entry() void { 4533 \\ _ = if(true) {}; 4534 \\ var good = {}; 4535 \\ _ = if(true) {} 4536 \\ var bad = {}; 4537 \\} 4538 , &[_][]const u8{ 4539 "tmp.zig:5:5: error: expected token ';', found 'var'", 4540 }); 4541 4542 cases.add("implicit semicolon - if-else statement", 4543 \\export fn entry() void { 4544 \\ if(true) {} else {} 4545 \\ var good = {}; 4546 \\ if(true) ({}) else ({}) 4547 \\ var bad = {}; 4548 \\} 4549 , &[_][]const u8{ 4550 "tmp.zig:5:5: error: expected token ';', found 'var'", 4551 }); 4552 4553 cases.add("implicit semicolon - if-else expression", 4554 \\export fn entry() void { 4555 \\ _ = if(true) {} else {}; 4556 \\ var good = {}; 4557 \\ _ = if(true) {} else {} 4558 \\ var bad = {}; 4559 \\} 4560 , &[_][]const u8{ 4561 "tmp.zig:5:5: error: expected token ';', found 'var'", 4562 }); 4563 4564 cases.add("implicit semicolon - if-else-if statement", 4565 \\export fn entry() void { 4566 \\ if(true) {} else if(true) {} 4567 \\ var good = {}; 4568 \\ if(true) ({}) else if(true) ({}) 4569 \\ var bad = {}; 4570 \\} 4571 , &[_][]const u8{ 4572 "tmp.zig:5:5: error: expected token ';', found 'var'", 4573 }); 4574 4575 cases.add("implicit semicolon - if-else-if expression", 4576 \\export fn entry() void { 4577 \\ _ = if(true) {} else if(true) {}; 4578 \\ var good = {}; 4579 \\ _ = if(true) {} else if(true) {} 4580 \\ var bad = {}; 4581 \\} 4582 , &[_][]const u8{ 4583 "tmp.zig:5:5: error: expected token ';', found 'var'", 4584 }); 4585 4586 cases.add("implicit semicolon - if-else-if-else statement", 4587 \\export fn entry() void { 4588 \\ if(true) {} else if(true) {} else {} 4589 \\ var good = {}; 4590 \\ if(true) ({}) else if(true) ({}) else ({}) 4591 \\ var bad = {}; 4592 \\} 4593 , &[_][]const u8{ 4594 "tmp.zig:5:5: error: expected token ';', found 'var'", 4595 }); 4596 4597 cases.add("implicit semicolon - if-else-if-else expression", 4598 \\export fn entry() void { 4599 \\ _ = if(true) {} else if(true) {} else {}; 4600 \\ var good = {}; 4601 \\ _ = if(true) {} else if(true) {} else {} 4602 \\ var bad = {}; 4603 \\} 4604 , &[_][]const u8{ 4605 "tmp.zig:5:5: error: expected token ';', found 'var'", 4606 }); 4607 4608 cases.add("implicit semicolon - test statement", 4609 \\export fn entry() void { 4610 \\ if (foo()) |_| {} 4611 \\ var good = {}; 4612 \\ if (foo()) |_| ({}) 4613 \\ var bad = {}; 4614 \\} 4615 , &[_][]const u8{ 4616 "tmp.zig:5:5: error: expected token ';', found 'var'", 4617 }); 4618 4619 cases.add("implicit semicolon - test expression", 4620 \\export fn entry() void { 4621 \\ _ = if (foo()) |_| {}; 4622 \\ var good = {}; 4623 \\ _ = if (foo()) |_| {} 4624 \\ var bad = {}; 4625 \\} 4626 , &[_][]const u8{ 4627 "tmp.zig:5:5: error: expected token ';', found 'var'", 4628 }); 4629 4630 cases.add("implicit semicolon - while statement", 4631 \\export fn entry() void { 4632 \\ while(true) {} 4633 \\ var good = {}; 4634 \\ while(true) ({}) 4635 \\ var bad = {}; 4636 \\} 4637 , &[_][]const u8{ 4638 "tmp.zig:5:5: error: expected token ';', found 'var'", 4639 }); 4640 4641 cases.add("implicit semicolon - while expression", 4642 \\export fn entry() void { 4643 \\ _ = while(true) {}; 4644 \\ var good = {}; 4645 \\ _ = while(true) {} 4646 \\ var bad = {}; 4647 \\} 4648 , &[_][]const u8{ 4649 "tmp.zig:5:5: error: expected token ';', found 'var'", 4650 }); 4651 4652 cases.add("implicit semicolon - while-continue statement", 4653 \\export fn entry() void { 4654 \\ while(true):({}) {} 4655 \\ var good = {}; 4656 \\ while(true):({}) ({}) 4657 \\ var bad = {}; 4658 \\} 4659 , &[_][]const u8{ 4660 "tmp.zig:5:5: error: expected token ';', found 'var'", 4661 }); 4662 4663 cases.add("implicit semicolon - while-continue expression", 4664 \\export fn entry() void { 4665 \\ _ = while(true):({}) {}; 4666 \\ var good = {}; 4667 \\ _ = while(true):({}) {} 4668 \\ var bad = {}; 4669 \\} 4670 , &[_][]const u8{ 4671 "tmp.zig:5:5: error: expected token ';', found 'var'", 4672 }); 4673 4674 cases.add("implicit semicolon - for statement", 4675 \\export fn entry() void { 4676 \\ for(foo()) |_| {} 4677 \\ var good = {}; 4678 \\ for(foo()) |_| ({}) 4679 \\ var bad = {}; 4680 \\} 4681 , &[_][]const u8{ 4682 "tmp.zig:5:5: error: expected token ';', found 'var'", 4683 }); 4684 4685 cases.add("implicit semicolon - for expression", 4686 \\export fn entry() void { 4687 \\ _ = for(foo()) |_| {}; 4688 \\ var good = {}; 4689 \\ _ = for(foo()) |_| {} 4690 \\ var bad = {}; 4691 \\} 4692 , &[_][]const u8{ 4693 "tmp.zig:5:5: error: expected token ';', found 'var'", 4694 }); 4695 4696 cases.add("multiple function definitions", 4697 \\fn a() void {} 4698 \\fn a() void {} 4699 \\export fn entry() void { a(); } 4700 , &[_][]const u8{ 4701 "tmp.zig:2:1: error: redefinition of 'a'", 4702 }); 4703 4704 cases.add("unreachable with return", 4705 \\fn a() noreturn {return;} 4706 \\export fn entry() void { a(); } 4707 , &[_][]const u8{ 4708 "tmp.zig:1:18: error: expected type 'noreturn', found 'void'", 4709 }); 4710 4711 cases.add("control reaches end of non-void function", 4712 \\fn a() i32 {} 4713 \\export fn entry() void { _ = a(); } 4714 , &[_][]const u8{ 4715 "tmp.zig:1:12: error: expected type 'i32', found 'void'", 4716 }); 4717 4718 cases.add("undefined function call", 4719 \\export fn a() void { 4720 \\ b(); 4721 \\} 4722 , &[_][]const u8{ 4723 "tmp.zig:2:5: error: use of undeclared identifier 'b'", 4724 }); 4725 4726 cases.add("wrong number of arguments", 4727 \\export fn a() void { 4728 \\ b(1); 4729 \\} 4730 \\fn b(a: i32, b: i32, c: i32) void { } 4731 , &[_][]const u8{ 4732 "tmp.zig:2:6: error: expected 3 argument(s), found 1", 4733 }); 4734 4735 cases.add("invalid type", 4736 \\fn a() bogus {} 4737 \\export fn entry() void { _ = a(); } 4738 , &[_][]const u8{ 4739 "tmp.zig:1:8: error: use of undeclared identifier 'bogus'", 4740 }); 4741 4742 cases.add("pointer to noreturn", 4743 \\fn a() *noreturn {} 4744 \\export fn entry() void { _ = a(); } 4745 , &[_][]const u8{ 4746 "tmp.zig:1:9: error: pointer to noreturn not allowed", 4747 }); 4748 4749 cases.add("unreachable code", 4750 \\export fn a() void { 4751 \\ return; 4752 \\ b(); 4753 \\} 4754 \\ 4755 \\fn b() void {} 4756 , &[_][]const u8{ 4757 "tmp.zig:3:5: error: unreachable code", 4758 }); 4759 4760 cases.add("bad import", 4761 \\const bogus = @import("bogus-does-not-exist.zig",); 4762 \\export fn entry() void { bogus.bogo(); } 4763 , &[_][]const u8{ 4764 "tmp.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'", 4765 }); 4766 4767 cases.add("undeclared identifier", 4768 \\export fn a() void { 4769 \\ return 4770 \\ b + 4771 \\ c; 4772 \\} 4773 , &[_][]const u8{ 4774 "tmp.zig:3:5: error: use of undeclared identifier 'b'", 4775 }); 4776 4777 cases.add("parameter redeclaration", 4778 \\fn f(a : i32, a : i32) void { 4779 \\} 4780 \\export fn entry() void { f(1, 2); } 4781 , &[_][]const u8{ 4782 "tmp.zig:1:15: error: redeclaration of variable 'a'", 4783 }); 4784 4785 cases.add("local variable redeclaration", 4786 \\export fn f() void { 4787 \\ const a : i32 = 0; 4788 \\ const a = 0; 4789 \\} 4790 , &[_][]const u8{ 4791 "tmp.zig:3:5: error: redeclaration of variable 'a'", 4792 }); 4793 4794 cases.add("local variable redeclares parameter", 4795 \\fn f(a : i32) void { 4796 \\ const a = 0; 4797 \\} 4798 \\export fn entry() void { f(1); } 4799 , &[_][]const u8{ 4800 "tmp.zig:2:5: error: redeclaration of variable 'a'", 4801 }); 4802 4803 cases.add("variable has wrong type", 4804 \\export fn f() i32 { 4805 \\ const a = "a"; 4806 \\ return a; 4807 \\} 4808 , &[_][]const u8{ 4809 "tmp.zig:3:12: error: expected type 'i32', found '*const [1:0]u8'", 4810 }); 4811 4812 cases.add("if condition is bool, not int", 4813 \\export fn f() void { 4814 \\ if (0) {} 4815 \\} 4816 , &[_][]const u8{ 4817 "tmp.zig:2:9: error: expected type 'bool', found 'comptime_int'", 4818 }); 4819 4820 cases.add("assign unreachable", 4821 \\export fn f() void { 4822 \\ const a = return; 4823 \\} 4824 , &[_][]const u8{ 4825 "tmp.zig:2:5: error: unreachable code", 4826 }); 4827 4828 cases.add("unreachable variable", 4829 \\export fn f() void { 4830 \\ const a: noreturn = {}; 4831 \\} 4832 , &[_][]const u8{ 4833 "tmp.zig:2:25: error: expected type 'noreturn', found 'void'", 4834 }); 4835 4836 cases.add("unreachable parameter", 4837 \\fn f(a: noreturn) void {} 4838 \\export fn entry() void { f(); } 4839 , &[_][]const u8{ 4840 "tmp.zig:1:9: error: parameter of type 'noreturn' not allowed", 4841 }); 4842 4843 cases.add("assign to constant variable", 4844 \\export fn f() void { 4845 \\ const a = 3; 4846 \\ a = 4; 4847 \\} 4848 , &[_][]const u8{ 4849 "tmp.zig:3:9: error: cannot assign to constant", 4850 }); 4851 4852 cases.add("use of undeclared identifier", 4853 \\export fn f() void { 4854 \\ b = 3; 4855 \\} 4856 , &[_][]const u8{ 4857 "tmp.zig:2:5: error: use of undeclared identifier 'b'", 4858 }); 4859 4860 cases.add("const is a statement, not an expression", 4861 \\export fn f() void { 4862 \\ (const a = 0); 4863 \\} 4864 , &[_][]const u8{ 4865 "tmp.zig:2:6: error: invalid token: 'const'", 4866 }); 4867 4868 cases.add("array access of undeclared identifier", 4869 \\export fn f() void { 4870 \\ i[i] = i[i]; 4871 \\} 4872 , &[_][]const u8{ 4873 "tmp.zig:2:5: error: use of undeclared identifier 'i'", 4874 }); 4875 4876 cases.add("array access of non array", 4877 \\export fn f() void { 4878 \\ var bad : bool = undefined; 4879 \\ bad[0] = bad[0]; 4880 \\} 4881 \\export fn g() void { 4882 \\ var bad : bool = undefined; 4883 \\ _ = bad[0]; 4884 \\} 4885 , &[_][]const u8{ 4886 "tmp.zig:3:8: error: array access of non-array type 'bool'", 4887 "tmp.zig:7:12: error: array access of non-array type 'bool'", 4888 }); 4889 4890 cases.add("array access with non integer index", 4891 \\export fn f() void { 4892 \\ var array = "aoeu"; 4893 \\ var bad = false; 4894 \\ array[bad] = array[bad]; 4895 \\} 4896 \\export fn g() void { 4897 \\ var array = "aoeu"; 4898 \\ var bad = false; 4899 \\ _ = array[bad]; 4900 \\} 4901 , &[_][]const u8{ 4902 "tmp.zig:4:11: error: expected type 'usize', found 'bool'", 4903 "tmp.zig:9:15: error: expected type 'usize', found 'bool'", 4904 }); 4905 4906 cases.add("write to const global variable", 4907 \\const x : i32 = 99; 4908 \\fn f() void { 4909 \\ x = 1; 4910 \\} 4911 \\export fn entry() void { f(); } 4912 , &[_][]const u8{ 4913 "tmp.zig:3:9: error: cannot assign to constant", 4914 }); 4915 4916 cases.add("missing else clause", 4917 \\fn f(b: bool) void { 4918 \\ const x : i32 = if (b) h: { break :h 1; }; 4919 \\} 4920 \\fn g(b: bool) void { 4921 \\ const y = if (b) h: { break :h @as(i32, 1); }; 4922 \\} 4923 \\export fn entry() void { f(true); g(true); } 4924 , &[_][]const u8{ 4925 "tmp.zig:2:21: error: expected type 'i32', found 'void'", 4926 "tmp.zig:5:15: error: incompatible types: 'i32' and 'void'", 4927 }); 4928 4929 cases.add("invalid struct field", 4930 \\const A = struct { x : i32, }; 4931 \\export fn f() void { 4932 \\ var a : A = undefined; 4933 \\ a.foo = 1; 4934 \\ const y = a.bar; 4935 \\} 4936 \\export fn g() void { 4937 \\ var a : A = undefined; 4938 \\ const y = a.bar; 4939 \\} 4940 , &[_][]const u8{ 4941 "tmp.zig:4:6: error: no member named 'foo' in struct 'A'", 4942 "tmp.zig:9:16: error: no member named 'bar' in struct 'A'", 4943 }); 4944 4945 cases.add("redefinition of struct", 4946 \\const A = struct { x : i32, }; 4947 \\const A = struct { y : i32, }; 4948 , &[_][]const u8{ 4949 "tmp.zig:2:1: error: redefinition of 'A'", 4950 }); 4951 4952 cases.add("redefinition of enums", 4953 \\const A = enum {}; 4954 \\const A = enum {}; 4955 , &[_][]const u8{ 4956 "tmp.zig:2:1: error: redefinition of 'A'", 4957 }); 4958 4959 cases.add("redefinition of global variables", 4960 \\var a : i32 = 1; 4961 \\var a : i32 = 2; 4962 , &[_][]const u8{ 4963 "tmp.zig:2:1: error: redefinition of 'a'", 4964 "tmp.zig:1:1: note: previous definition is here", 4965 }); 4966 4967 cases.add("duplicate field in struct value expression", 4968 \\const A = struct { 4969 \\ x : i32, 4970 \\ y : i32, 4971 \\ z : i32, 4972 \\}; 4973 \\export fn f() void { 4974 \\ const a = A { 4975 \\ .z = 1, 4976 \\ .y = 2, 4977 \\ .x = 3, 4978 \\ .z = 4, 4979 \\ }; 4980 \\} 4981 , &[_][]const u8{ 4982 "tmp.zig:11:9: error: duplicate field", 4983 }); 4984 4985 cases.add("missing field in struct value expression", 4986 \\const A = struct { 4987 \\ x : i32, 4988 \\ y : i32, 4989 \\ z : i32, 4990 \\}; 4991 \\export fn f() void { 4992 \\ // we want the error on the '{' not the 'A' because 4993 \\ // the A could be a complicated expression 4994 \\ const a = A { 4995 \\ .z = 4, 4996 \\ .y = 2, 4997 \\ }; 4998 \\} 4999 , &[_][]const u8{ 5000 "tmp.zig:9:17: error: missing field: 'x'", 5001 }); 5002 5003 cases.add("invalid field in struct value expression", 5004 \\const A = struct { 5005 \\ x : i32, 5006 \\ y : i32, 5007 \\ z : i32, 5008 \\}; 5009 \\export fn f() void { 5010 \\ const a = A { 5011 \\ .z = 4, 5012 \\ .y = 2, 5013 \\ .foo = 42, 5014 \\ }; 5015 \\} 5016 , &[_][]const u8{ 5017 "tmp.zig:10:9: error: no member named 'foo' in struct 'A'", 5018 }); 5019 5020 cases.add("invalid break expression", 5021 \\export fn f() void { 5022 \\ break; 5023 \\} 5024 , &[_][]const u8{ 5025 "tmp.zig:2:5: error: break expression outside loop", 5026 }); 5027 5028 cases.add("invalid continue expression", 5029 \\export fn f() void { 5030 \\ continue; 5031 \\} 5032 , &[_][]const u8{ 5033 "tmp.zig:2:5: error: continue expression outside loop", 5034 }); 5035 5036 cases.add("invalid maybe type", 5037 \\export fn f() void { 5038 \\ if (true) |x| { } 5039 \\} 5040 , &[_][]const u8{ 5041 "tmp.zig:2:9: error: expected optional type, found 'bool'", 5042 }); 5043 5044 cases.add("cast unreachable", 5045 \\fn f() i32 { 5046 \\ return @as(i32, return 1); 5047 \\} 5048 \\export fn entry() void { _ = f(); } 5049 , &[_][]const u8{ 5050 "tmp.zig:2:12: error: unreachable code", 5051 }); 5052 5053 cases.add("invalid builtin fn", 5054 \\fn f() @bogus(foo) { 5055 \\} 5056 \\export fn entry() void { _ = f(); } 5057 , &[_][]const u8{ 5058 "tmp.zig:1:8: error: invalid builtin function: 'bogus'", 5059 }); 5060 5061 cases.add("noalias on non pointer param", 5062 \\fn f(noalias x: i32) void {} 5063 \\export fn entry() void { f(1234); } 5064 , &[_][]const u8{ 5065 "tmp.zig:1:6: error: noalias on non-pointer parameter", 5066 }); 5067 5068 cases.add("struct init syntax for array", 5069 \\const foo = [3]u16{ .x = 1024 }; 5070 \\comptime { 5071 \\ _ = foo; 5072 \\} 5073 , &[_][]const u8{ 5074 "tmp.zig:1:21: error: type '[3]u16' does not support struct initialization syntax", 5075 }); 5076 5077 cases.add("type variables must be constant", 5078 \\var foo = u8; 5079 \\export fn entry() foo { 5080 \\ return 1; 5081 \\} 5082 , &[_][]const u8{ 5083 "tmp.zig:1:1: error: variable of type 'type' must be constant", 5084 }); 5085 5086 cases.add("variables shadowing types", 5087 \\const Foo = struct {}; 5088 \\const Bar = struct {}; 5089 \\ 5090 \\fn f(Foo: i32) void { 5091 \\ var Bar : i32 = undefined; 5092 \\} 5093 \\ 5094 \\export fn entry() void { 5095 \\ f(1234); 5096 \\} 5097 , &[_][]const u8{ 5098 "tmp.zig:4:6: error: redefinition of 'Foo'", 5099 "tmp.zig:1:1: note: previous definition is here", 5100 "tmp.zig:5:5: error: redefinition of 'Bar'", 5101 "tmp.zig:2:1: note: previous definition is here", 5102 }); 5103 5104 cases.add("switch expression - missing enumeration prong", 5105 \\const Number = enum { 5106 \\ One, 5107 \\ Two, 5108 \\ Three, 5109 \\ Four, 5110 \\}; 5111 \\fn f(n: Number) i32 { 5112 \\ switch (n) { 5113 \\ Number.One => 1, 5114 \\ Number.Two => 2, 5115 \\ Number.Three => @as(i32, 3), 5116 \\ } 5117 \\} 5118 \\ 5119 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 5120 , &[_][]const u8{ 5121 "tmp.zig:8:5: error: enumeration value 'Number.Four' not handled in switch", 5122 }); 5123 5124 cases.add("switch expression - duplicate enumeration prong", 5125 \\const Number = enum { 5126 \\ One, 5127 \\ Two, 5128 \\ Three, 5129 \\ Four, 5130 \\}; 5131 \\fn f(n: Number) i32 { 5132 \\ switch (n) { 5133 \\ Number.One => 1, 5134 \\ Number.Two => 2, 5135 \\ Number.Three => @as(i32, 3), 5136 \\ Number.Four => 4, 5137 \\ Number.Two => 2, 5138 \\ } 5139 \\} 5140 \\ 5141 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 5142 , &[_][]const u8{ 5143 "tmp.zig:13:15: error: duplicate switch value", 5144 "tmp.zig:10:15: note: other value is here", 5145 }); 5146 5147 cases.add("switch expression - duplicate enumeration prong when else present", 5148 \\const Number = enum { 5149 \\ One, 5150 \\ Two, 5151 \\ Three, 5152 \\ Four, 5153 \\}; 5154 \\fn f(n: Number) i32 { 5155 \\ switch (n) { 5156 \\ Number.One => 1, 5157 \\ Number.Two => 2, 5158 \\ Number.Three => @as(i32, 3), 5159 \\ Number.Four => 4, 5160 \\ Number.Two => 2, 5161 \\ else => 10, 5162 \\ } 5163 \\} 5164 \\ 5165 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 5166 , &[_][]const u8{ 5167 "tmp.zig:13:15: error: duplicate switch value", 5168 "tmp.zig:10:15: note: other value is here", 5169 }); 5170 5171 cases.add("switch expression - multiple else prongs", 5172 \\fn f(x: u32) void { 5173 \\ const value: bool = switch (x) { 5174 \\ 1234 => false, 5175 \\ else => true, 5176 \\ else => true, 5177 \\ }; 5178 \\} 5179 \\export fn entry() void { 5180 \\ f(1234); 5181 \\} 5182 , &[_][]const u8{ 5183 "tmp.zig:5:9: error: multiple else prongs in switch expression", 5184 }); 5185 5186 cases.add("switch expression - non exhaustive integer prongs", 5187 \\fn foo(x: u8) void { 5188 \\ switch (x) { 5189 \\ 0 => {}, 5190 \\ } 5191 \\} 5192 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 5193 , &[_][]const u8{ 5194 "tmp.zig:2:5: error: switch must handle all possibilities", 5195 }); 5196 5197 cases.add("switch expression - duplicate or overlapping integer value", 5198 \\fn foo(x: u8) u8 { 5199 \\ return switch (x) { 5200 \\ 0 ... 100 => @as(u8, 0), 5201 \\ 101 ... 200 => 1, 5202 \\ 201, 203 ... 207 => 2, 5203 \\ 206 ... 255 => 3, 5204 \\ }; 5205 \\} 5206 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 5207 , &[_][]const u8{ 5208 "tmp.zig:6:9: error: duplicate switch value", 5209 "tmp.zig:5:14: note: previous value is here", 5210 }); 5211 5212 cases.add("switch expression - duplicate type", 5213 \\fn foo(comptime T: type, x: T) u8 { 5214 \\ return switch (T) { 5215 \\ u32 => 0, 5216 \\ u64 => 1, 5217 \\ u32 => 2, 5218 \\ else => 3, 5219 \\ }; 5220 \\} 5221 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); } 5222 , &[_][]const u8{ 5223 "tmp.zig:5:9: error: duplicate switch value", 5224 "tmp.zig:3:9: note: previous value is here", 5225 }); 5226 5227 cases.add("switch expression - duplicate type (struct alias)", 5228 \\const Test = struct { 5229 \\ bar: i32, 5230 \\}; 5231 \\const Test2 = Test; 5232 \\fn foo(comptime T: type, x: T) u8 { 5233 \\ return switch (T) { 5234 \\ Test => 0, 5235 \\ u64 => 1, 5236 \\ Test2 => 2, 5237 \\ else => 3, 5238 \\ }; 5239 \\} 5240 \\export fn entry() usize { return @sizeOf(@TypeOf(foo(u32, 0))); } 5241 , &[_][]const u8{ 5242 "tmp.zig:9:9: error: duplicate switch value", 5243 "tmp.zig:7:9: note: previous value is here", 5244 }); 5245 5246 cases.add("switch expression - switch on pointer type with no else", 5247 \\fn foo(x: *u8) void { 5248 \\ switch (x) { 5249 \\ &y => {}, 5250 \\ } 5251 \\} 5252 \\const y: u8 = 100; 5253 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 5254 , &[_][]const u8{ 5255 "tmp.zig:2:5: error: else prong required when switching on type '*u8'", 5256 }); 5257 5258 cases.add("global variable initializer must be constant expression", 5259 \\extern fn foo() i32; 5260 \\const x = foo(); 5261 \\export fn entry() i32 { return x; } 5262 , &[_][]const u8{ 5263 "tmp.zig:2:11: error: unable to evaluate constant expression", 5264 }); 5265 5266 cases.add("array concatenation with wrong type", 5267 \\const src = "aoeu"; 5268 \\const derp: usize = 1234; 5269 \\const a = derp ++ "foo"; 5270 \\ 5271 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); } 5272 , &[_][]const u8{ 5273 "tmp.zig:3:11: error: expected array, found 'usize'", 5274 }); 5275 5276 cases.add("non compile time array concatenation", 5277 \\fn f() []u8 { 5278 \\ return s ++ "foo"; 5279 \\} 5280 \\var s: [10]u8 = undefined; 5281 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 5282 , &[_][]const u8{ 5283 "tmp.zig:2:12: error: unable to evaluate constant expression", 5284 }); 5285 5286 cases.add("@cImport with bogus include", 5287 \\const c = @cImport(@cInclude("bogus.h")); 5288 \\export fn entry() usize { return @sizeOf(@TypeOf(c.bogo)); } 5289 , &[_][]const u8{ 5290 "tmp.zig:1:11: error: C import failed", 5291 ".h:1:10: note: 'bogus.h' file not found", 5292 }); 5293 5294 cases.add("address of number literal", 5295 \\const x = 3; 5296 \\const y = &x; 5297 \\fn foo() *const i32 { return y; } 5298 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 5299 , &[_][]const u8{ 5300 "tmp.zig:3:30: error: expected type '*const i32', found '*const comptime_int'", 5301 }); 5302 5303 cases.add("integer overflow error", 5304 \\const x : u8 = 300; 5305 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); } 5306 , &[_][]const u8{ 5307 "tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'", 5308 }); 5309 5310 cases.add("invalid shift amount error", 5311 \\const x : u8 = 2; 5312 \\fn f() u16 { 5313 \\ return x << 8; 5314 \\} 5315 \\export fn entry() u16 { return f(); } 5316 , &[_][]const u8{ 5317 "tmp.zig:3:17: error: integer value 8 cannot be coerced to type 'u3'", 5318 }); 5319 5320 cases.add("missing function call param", 5321 \\const Foo = struct { 5322 \\ a: i32, 5323 \\ b: i32, 5324 \\ 5325 \\ fn member_a(foo: *const Foo) i32 { 5326 \\ return foo.a; 5327 \\ } 5328 \\ fn member_b(foo: *const Foo) i32 { 5329 \\ return foo.b; 5330 \\ } 5331 \\}; 5332 \\ 5333 \\const member_fn_type = @TypeOf(Foo.member_a); 5334 \\const members = [_]member_fn_type { 5335 \\ Foo.member_a, 5336 \\ Foo.member_b, 5337 \\}; 5338 \\ 5339 \\fn f(foo: *const Foo, index: usize) void { 5340 \\ const result = members[index](); 5341 \\} 5342 \\ 5343 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 5344 , &[_][]const u8{ 5345 "tmp.zig:20:34: error: expected 1 argument(s), found 0", 5346 }); 5347 5348 cases.add("missing function name", 5349 \\fn () void {} 5350 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 5351 , &[_][]const u8{ 5352 "tmp.zig:1:1: error: missing function name", 5353 }); 5354 5355 cases.add("missing param name", 5356 \\fn f(i32) void {} 5357 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 5358 , &[_][]const u8{ 5359 "tmp.zig:1:6: error: missing parameter name", 5360 }); 5361 5362 cases.add("wrong function type", 5363 \\const fns = [_]fn() void { a, b, c }; 5364 \\fn a() i32 {return 0;} 5365 \\fn b() i32 {return 1;} 5366 \\fn c() i32 {return 2;} 5367 \\export fn entry() usize { return @sizeOf(@TypeOf(fns)); } 5368 , &[_][]const u8{ 5369 "tmp.zig:1:28: error: expected type 'fn() void', found 'fn() i32'", 5370 }); 5371 5372 cases.add("extern function pointer mismatch", 5373 \\const fns = [_](fn(i32)i32) { a, b, c }; 5374 \\pub fn a(x: i32) i32 {return x + 0;} 5375 \\pub fn b(x: i32) i32 {return x + 1;} 5376 \\export fn c(x: i32) i32 {return x + 2;} 5377 \\ 5378 \\export fn entry() usize { return @sizeOf(@TypeOf(fns)); } 5379 , &[_][]const u8{ 5380 "tmp.zig:1:37: error: expected type 'fn(i32) i32', found 'fn(i32) callconv(.C) i32'", 5381 }); 5382 5383 cases.add("colliding invalid top level functions", 5384 \\fn func() bogus {} 5385 \\fn func() bogus {} 5386 \\export fn entry() usize { return @sizeOf(@TypeOf(func)); } 5387 , &[_][]const u8{ 5388 "tmp.zig:2:1: error: redefinition of 'func'", 5389 }); 5390 5391 cases.add("non constant expression in array size", 5392 \\const Foo = struct { 5393 \\ y: [get()]u8, 5394 \\}; 5395 \\var global_var: usize = 1; 5396 \\fn get() usize { return global_var; } 5397 \\ 5398 \\export fn entry() usize { return @sizeOf(@TypeOf(Foo)); } 5399 , &[_][]const u8{ 5400 "tmp.zig:5:25: error: cannot store runtime value in compile time variable", 5401 "tmp.zig:2:12: note: called from here", 5402 }); 5403 5404 cases.add("addition with non numbers", 5405 \\const Foo = struct { 5406 \\ field: i32, 5407 \\}; 5408 \\const x = Foo {.field = 1} + Foo {.field = 2}; 5409 \\ 5410 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); } 5411 , &[_][]const u8{ 5412 "tmp.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'", 5413 }); 5414 5415 cases.add("division by zero", 5416 \\const lit_int_x = 1 / 0; 5417 \\const lit_float_x = 1.0 / 0.0; 5418 \\const int_x = @as(u32, 1) / @as(u32, 0); 5419 \\const float_x = @as(f32, 1.0) / @as(f32, 0.0); 5420 \\ 5421 \\export fn entry1() usize { return @sizeOf(@TypeOf(lit_int_x)); } 5422 \\export fn entry2() usize { return @sizeOf(@TypeOf(lit_float_x)); } 5423 \\export fn entry3() usize { return @sizeOf(@TypeOf(int_x)); } 5424 \\export fn entry4() usize { return @sizeOf(@TypeOf(float_x)); } 5425 , &[_][]const u8{ 5426 "tmp.zig:1:21: error: division by zero", 5427 "tmp.zig:2:25: error: division by zero", 5428 "tmp.zig:3:27: error: division by zero", 5429 "tmp.zig:4:31: error: division by zero", 5430 }); 5431 5432 cases.add("normal string with newline", 5433 \\const foo = "a 5434 \\b"; 5435 \\ 5436 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 5437 , &[_][]const u8{ 5438 "tmp.zig:1:15: error: newline not allowed in string literal", 5439 }); 5440 5441 cases.add("invalid comparison for function pointers", 5442 \\fn foo() void {} 5443 \\const invalid = foo > foo; 5444 \\ 5445 \\export fn entry() usize { return @sizeOf(@TypeOf(invalid)); } 5446 , &[_][]const u8{ 5447 "tmp.zig:2:21: error: operator not allowed for type 'fn() void'", 5448 }); 5449 5450 cases.add("generic function instance with non-constant expression", 5451 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; } 5452 \\fn test1(a: i32, b: i32) i32 { 5453 \\ return foo(a, b); 5454 \\} 5455 \\ 5456 \\export fn entry() usize { return @sizeOf(@TypeOf(test1)); } 5457 , &[_][]const u8{ 5458 "tmp.zig:3:16: error: runtime value cannot be passed to comptime arg", 5459 }); 5460 5461 cases.add("assign null to non-optional pointer", 5462 \\const a: *u8 = null; 5463 \\ 5464 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); } 5465 , &[_][]const u8{ 5466 "tmp.zig:1:16: error: expected type '*u8', found '(null)'", 5467 }); 5468 5469 cases.add("indexing an array of size zero", 5470 \\const array = [_]u8{}; 5471 \\export fn foo() void { 5472 \\ const pointer = &array[0]; 5473 \\} 5474 , &[_][]const u8{ 5475 "tmp.zig:3:27: error: accessing a zero length array is not allowed", 5476 }); 5477 5478 cases.add("indexing an array of size zero with runtime index", 5479 \\const array = [_]u8{}; 5480 \\export fn foo() void { 5481 \\ var index: usize = 0; 5482 \\ const pointer = &array[index]; 5483 \\} 5484 , &[_][]const u8{ 5485 "tmp.zig:4:27: error: accessing a zero length array is not allowed", 5486 }); 5487 5488 cases.add("compile time division by zero", 5489 \\const y = foo(0); 5490 \\fn foo(x: u32) u32 { 5491 \\ return 1 / x; 5492 \\} 5493 \\ 5494 \\export fn entry() usize { return @sizeOf(@TypeOf(y)); } 5495 , &[_][]const u8{ 5496 "tmp.zig:3:14: error: division by zero", 5497 "tmp.zig:1:14: note: referenced here", 5498 }); 5499 5500 cases.add("branch on undefined value", 5501 \\const x = if (undefined) true else false; 5502 \\ 5503 \\export fn entry() usize { return @sizeOf(@TypeOf(x)); } 5504 , &[_][]const u8{ 5505 "tmp.zig:1:15: error: use of undefined value here causes undefined behavior", 5506 }); 5507 5508 cases.add("div on undefined value", 5509 \\comptime { 5510 \\ var a: i64 = undefined; 5511 \\ _ = a / a; 5512 \\} 5513 , &[_][]const u8{ 5514 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5515 }); 5516 5517 cases.add("div assign on undefined value", 5518 \\comptime { 5519 \\ var a: i64 = undefined; 5520 \\ a /= a; 5521 \\} 5522 , &[_][]const u8{ 5523 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5524 }); 5525 5526 cases.add("mod on undefined value", 5527 \\comptime { 5528 \\ var a: i64 = undefined; 5529 \\ _ = a % a; 5530 \\} 5531 , &[_][]const u8{ 5532 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5533 }); 5534 5535 cases.add("mod assign on undefined value", 5536 \\comptime { 5537 \\ var a: i64 = undefined; 5538 \\ a %= a; 5539 \\} 5540 , &[_][]const u8{ 5541 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5542 }); 5543 5544 cases.add("add on undefined value", 5545 \\comptime { 5546 \\ var a: i64 = undefined; 5547 \\ _ = a + a; 5548 \\} 5549 , &[_][]const u8{ 5550 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5551 }); 5552 5553 cases.add("add assign on undefined value", 5554 \\comptime { 5555 \\ var a: i64 = undefined; 5556 \\ a += a; 5557 \\} 5558 , &[_][]const u8{ 5559 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5560 }); 5561 5562 cases.add("add wrap on undefined value", 5563 \\comptime { 5564 \\ var a: i64 = undefined; 5565 \\ _ = a +% a; 5566 \\} 5567 , &[_][]const u8{ 5568 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5569 }); 5570 5571 cases.add("add wrap assign on undefined value", 5572 \\comptime { 5573 \\ var a: i64 = undefined; 5574 \\ a +%= a; 5575 \\} 5576 , &[_][]const u8{ 5577 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5578 }); 5579 5580 cases.add("sub on undefined value", 5581 \\comptime { 5582 \\ var a: i64 = undefined; 5583 \\ _ = a - a; 5584 \\} 5585 , &[_][]const u8{ 5586 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5587 }); 5588 5589 cases.add("sub assign on undefined value", 5590 \\comptime { 5591 \\ var a: i64 = undefined; 5592 \\ a -= a; 5593 \\} 5594 , &[_][]const u8{ 5595 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5596 }); 5597 5598 cases.add("sub wrap on undefined value", 5599 \\comptime { 5600 \\ var a: i64 = undefined; 5601 \\ _ = a -% a; 5602 \\} 5603 , &[_][]const u8{ 5604 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5605 }); 5606 5607 cases.add("sub wrap assign on undefined value", 5608 \\comptime { 5609 \\ var a: i64 = undefined; 5610 \\ a -%= a; 5611 \\} 5612 , &[_][]const u8{ 5613 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5614 }); 5615 5616 cases.add("mult on undefined value", 5617 \\comptime { 5618 \\ var a: i64 = undefined; 5619 \\ _ = a * a; 5620 \\} 5621 , &[_][]const u8{ 5622 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5623 }); 5624 5625 cases.add("mult assign on undefined value", 5626 \\comptime { 5627 \\ var a: i64 = undefined; 5628 \\ a *= a; 5629 \\} 5630 , &[_][]const u8{ 5631 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5632 }); 5633 5634 cases.add("mult wrap on undefined value", 5635 \\comptime { 5636 \\ var a: i64 = undefined; 5637 \\ _ = a *% a; 5638 \\} 5639 , &[_][]const u8{ 5640 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5641 }); 5642 5643 cases.add("mult wrap assign on undefined value", 5644 \\comptime { 5645 \\ var a: i64 = undefined; 5646 \\ a *%= a; 5647 \\} 5648 , &[_][]const u8{ 5649 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5650 }); 5651 5652 cases.add("shift left on undefined value", 5653 \\comptime { 5654 \\ var a: i64 = undefined; 5655 \\ _ = a << 2; 5656 \\} 5657 , &[_][]const u8{ 5658 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5659 }); 5660 5661 cases.add("shift left assign on undefined value", 5662 \\comptime { 5663 \\ var a: i64 = undefined; 5664 \\ a <<= 2; 5665 \\} 5666 , &[_][]const u8{ 5667 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5668 }); 5669 5670 cases.add("shift right on undefined value", 5671 \\comptime { 5672 \\ var a: i64 = undefined; 5673 \\ _ = a >> 2; 5674 \\} 5675 , &[_][]const u8{ 5676 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5677 }); 5678 5679 cases.add("shift left assign on undefined value", 5680 \\comptime { 5681 \\ var a: i64 = undefined; 5682 \\ a >>= 2; 5683 \\} 5684 , &[_][]const u8{ 5685 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5686 }); 5687 5688 cases.add("bin and on undefined value", 5689 \\comptime { 5690 \\ var a: i64 = undefined; 5691 \\ _ = a & a; 5692 \\} 5693 , &[_][]const u8{ 5694 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5695 }); 5696 5697 cases.add("bin and assign on undefined value", 5698 \\comptime { 5699 \\ var a: i64 = undefined; 5700 \\ a &= a; 5701 \\} 5702 , &[_][]const u8{ 5703 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5704 }); 5705 5706 cases.add("bin or on undefined value", 5707 \\comptime { 5708 \\ var a: i64 = undefined; 5709 \\ _ = a | a; 5710 \\} 5711 , &[_][]const u8{ 5712 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5713 }); 5714 5715 cases.add("bin or assign on undefined value", 5716 \\comptime { 5717 \\ var a: i64 = undefined; 5718 \\ a |= a; 5719 \\} 5720 , &[_][]const u8{ 5721 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5722 }); 5723 5724 cases.add("bin xor on undefined value", 5725 \\comptime { 5726 \\ var a: i64 = undefined; 5727 \\ _ = a ^ a; 5728 \\} 5729 , &[_][]const u8{ 5730 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5731 }); 5732 5733 cases.add("bin xor assign on undefined value", 5734 \\comptime { 5735 \\ var a: i64 = undefined; 5736 \\ a ^= a; 5737 \\} 5738 , &[_][]const u8{ 5739 "tmp.zig:3:5: error: use of undefined value here causes undefined behavior", 5740 }); 5741 5742 cases.add("comparison operators with undefined value", 5743 \\// operator == 5744 \\comptime { 5745 \\ var a: i64 = undefined; 5746 \\ var x: i32 = 0; 5747 \\ if (a == a) x += 1; 5748 \\} 5749 \\// operator != 5750 \\comptime { 5751 \\ var a: i64 = undefined; 5752 \\ var x: i32 = 0; 5753 \\ if (a != a) x += 1; 5754 \\} 5755 \\// operator > 5756 \\comptime { 5757 \\ var a: i64 = undefined; 5758 \\ var x: i32 = 0; 5759 \\ if (a > a) x += 1; 5760 \\} 5761 \\// operator < 5762 \\comptime { 5763 \\ var a: i64 = undefined; 5764 \\ var x: i32 = 0; 5765 \\ if (a < a) x += 1; 5766 \\} 5767 \\// operator >= 5768 \\comptime { 5769 \\ var a: i64 = undefined; 5770 \\ var x: i32 = 0; 5771 \\ if (a >= a) x += 1; 5772 \\} 5773 \\// operator <= 5774 \\comptime { 5775 \\ var a: i64 = undefined; 5776 \\ var x: i32 = 0; 5777 \\ if (a <= a) x += 1; 5778 \\} 5779 , &[_][]const u8{ 5780 "tmp.zig:5:11: error: use of undefined value here causes undefined behavior", 5781 "tmp.zig:11:11: error: use of undefined value here causes undefined behavior", 5782 "tmp.zig:17:11: error: use of undefined value here causes undefined behavior", 5783 "tmp.zig:23:11: error: use of undefined value here causes undefined behavior", 5784 "tmp.zig:29:11: error: use of undefined value here causes undefined behavior", 5785 "tmp.zig:35:11: error: use of undefined value here causes undefined behavior", 5786 }); 5787 5788 cases.add("and on undefined value", 5789 \\comptime { 5790 \\ var a: bool = undefined; 5791 \\ _ = a and a; 5792 \\} 5793 , &[_][]const u8{ 5794 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5795 }); 5796 5797 cases.add("or on undefined value", 5798 \\comptime { 5799 \\ var a: bool = undefined; 5800 \\ _ = a or a; 5801 \\} 5802 , &[_][]const u8{ 5803 "tmp.zig:3:9: error: use of undefined value here causes undefined behavior", 5804 }); 5805 5806 cases.add("negate on undefined value", 5807 \\comptime { 5808 \\ var a: i64 = undefined; 5809 \\ _ = -a; 5810 \\} 5811 , &[_][]const u8{ 5812 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior", 5813 }); 5814 5815 cases.add("negate wrap on undefined value", 5816 \\comptime { 5817 \\ var a: i64 = undefined; 5818 \\ _ = -%a; 5819 \\} 5820 , &[_][]const u8{ 5821 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior", 5822 }); 5823 5824 cases.add("bin not on undefined value", 5825 \\comptime { 5826 \\ var a: i64 = undefined; 5827 \\ _ = ~a; 5828 \\} 5829 , &[_][]const u8{ 5830 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior", 5831 }); 5832 5833 cases.add("bool not on undefined value", 5834 \\comptime { 5835 \\ var a: bool = undefined; 5836 \\ _ = !a; 5837 \\} 5838 , &[_][]const u8{ 5839 "tmp.zig:3:10: error: use of undefined value here causes undefined behavior", 5840 }); 5841 5842 cases.add("orelse on undefined value", 5843 \\comptime { 5844 \\ var a: ?bool = undefined; 5845 \\ _ = a orelse false; 5846 \\} 5847 , &[_][]const u8{ 5848 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior", 5849 }); 5850 5851 cases.add("catch on undefined value", 5852 \\comptime { 5853 \\ var a: anyerror!bool = undefined; 5854 \\ _ = a catch |err| false; 5855 \\} 5856 , &[_][]const u8{ 5857 "tmp.zig:3:11: error: use of undefined value here causes undefined behavior", 5858 }); 5859 5860 cases.add("deref on undefined value", 5861 \\comptime { 5862 \\ var a: *u8 = undefined; 5863 \\ _ = a.*; 5864 \\} 5865 , &[_][]const u8{ 5866 "tmp.zig:3:9: error: attempt to dereference undefined value", 5867 }); 5868 5869 cases.add("endless loop in function evaluation", 5870 \\const seventh_fib_number = fibbonaci(7); 5871 \\fn fibbonaci(x: i32) i32 { 5872 \\ return fibbonaci(x - 1) + fibbonaci(x - 2); 5873 \\} 5874 \\ 5875 \\export fn entry() usize { return @sizeOf(@TypeOf(seventh_fib_number)); } 5876 , &[_][]const u8{ 5877 "tmp.zig:3:21: error: evaluation exceeded 1000 backwards branches", 5878 "tmp.zig:1:37: note: referenced here", 5879 "tmp.zig:6:50: note: referenced here", 5880 }); 5881 5882 cases.add("@embedFile with bogus file", 5883 \\const resource = @embedFile("bogus.txt",); 5884 \\ 5885 \\export fn entry() usize { return @sizeOf(@TypeOf(resource)); } 5886 , &[_][]const u8{ 5887 "tmp.zig:1:29: error: unable to find '", 5888 "bogus.txt'", 5889 }); 5890 5891 cases.add("non-const expression in struct literal outside function", 5892 \\const Foo = struct { 5893 \\ x: i32, 5894 \\}; 5895 \\const a = Foo {.x = get_it()}; 5896 \\extern fn get_it() i32; 5897 \\ 5898 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); } 5899 , &[_][]const u8{ 5900 "tmp.zig:4:21: error: unable to evaluate constant expression", 5901 }); 5902 5903 cases.add("non-const expression function call with struct return value outside function", 5904 \\const Foo = struct { 5905 \\ x: i32, 5906 \\}; 5907 \\const a = get_it(); 5908 \\fn get_it() Foo { 5909 \\ global_side_effect = true; 5910 \\ return Foo {.x = 13}; 5911 \\} 5912 \\var global_side_effect = false; 5913 \\ 5914 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); } 5915 , &[_][]const u8{ 5916 "tmp.zig:6:26: error: unable to evaluate constant expression", 5917 "tmp.zig:4:17: note: referenced here", 5918 }); 5919 5920 cases.add("undeclared identifier error should mark fn as impure", 5921 \\export fn foo() void { 5922 \\ test_a_thing(); 5923 \\} 5924 \\fn test_a_thing() void { 5925 \\ bad_fn_call(); 5926 \\} 5927 , &[_][]const u8{ 5928 "tmp.zig:5:5: error: use of undeclared identifier 'bad_fn_call'", 5929 }); 5930 5931 cases.add("illegal comparison of types", 5932 \\fn bad_eql_1(a: []u8, b: []u8) bool { 5933 \\ return a == b; 5934 \\} 5935 \\const EnumWithData = union(enum) { 5936 \\ One: void, 5937 \\ Two: i32, 5938 \\}; 5939 \\fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool { 5940 \\ return a.* == b.*; 5941 \\} 5942 \\ 5943 \\export fn entry1() usize { return @sizeOf(@TypeOf(bad_eql_1)); } 5944 \\export fn entry2() usize { return @sizeOf(@TypeOf(bad_eql_2)); } 5945 , &[_][]const u8{ 5946 "tmp.zig:2:14: error: operator not allowed for type '[]u8'", 5947 "tmp.zig:9:16: error: operator not allowed for type 'EnumWithData'", 5948 }); 5949 5950 cases.add("non-const switch number literal", 5951 \\export fn foo() void { 5952 \\ const x = switch (bar()) { 5953 \\ 1, 2 => 1, 5954 \\ 3, 4 => 2, 5955 \\ else => 3, 5956 \\ }; 5957 \\} 5958 \\fn bar() i32 { 5959 \\ return 2; 5960 \\} 5961 , &[_][]const u8{ 5962 "tmp.zig:5:17: error: cannot store runtime value in type 'comptime_int'", 5963 }); 5964 5965 cases.add("atomic orderings of cmpxchg - failure stricter than success", 5966 \\const AtomicOrder = @import("builtin").AtomicOrder; 5967 \\export fn f() void { 5968 \\ var x: i32 = 1234; 5969 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {} 5970 \\} 5971 , &[_][]const u8{ 5972 "tmp.zig:4:81: error: failure atomic ordering must be no stricter than success", 5973 }); 5974 5975 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter", 5976 \\const AtomicOrder = @import("builtin").AtomicOrder; 5977 \\export fn f() void { 5978 \\ var x: i32 = 1234; 5979 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {} 5980 \\} 5981 , &[_][]const u8{ 5982 "tmp.zig:4:58: error: success atomic ordering must be Monotonic or stricter", 5983 }); 5984 5985 cases.add("negation overflow in function evaluation", 5986 \\const y = neg(-128); 5987 \\fn neg(x: i8) i8 { 5988 \\ return -x; 5989 \\} 5990 \\ 5991 \\export fn entry() usize { return @sizeOf(@TypeOf(y)); } 5992 , &[_][]const u8{ 5993 "tmp.zig:3:12: error: negation caused overflow", 5994 "tmp.zig:1:14: note: referenced here", 5995 }); 5996 5997 cases.add("add overflow in function evaluation", 5998 \\const y = add(65530, 10); 5999 \\fn add(a: u16, b: u16) u16 { 6000 \\ return a + b; 6001 \\} 6002 \\ 6003 \\export fn entry() usize { return @sizeOf(@TypeOf(y)); } 6004 , &[_][]const u8{ 6005 "tmp.zig:3:14: error: operation caused overflow", 6006 "tmp.zig:1:14: note: referenced here", 6007 }); 6008 6009 cases.add("sub overflow in function evaluation", 6010 \\const y = sub(10, 20); 6011 \\fn sub(a: u16, b: u16) u16 { 6012 \\ return a - b; 6013 \\} 6014 \\ 6015 \\export fn entry() usize { return @sizeOf(@TypeOf(y)); } 6016 , &[_][]const u8{ 6017 "tmp.zig:3:14: error: operation caused overflow", 6018 "tmp.zig:1:14: note: referenced here", 6019 }); 6020 6021 cases.add("mul overflow in function evaluation", 6022 \\const y = mul(300, 6000); 6023 \\fn mul(a: u16, b: u16) u16 { 6024 \\ return a * b; 6025 \\} 6026 \\ 6027 \\export fn entry() usize { return @sizeOf(@TypeOf(y)); } 6028 , &[_][]const u8{ 6029 "tmp.zig:3:14: error: operation caused overflow", 6030 "tmp.zig:1:14: note: referenced here", 6031 }); 6032 6033 cases.add("truncate sign mismatch", 6034 \\fn f() i8 { 6035 \\ var x: u32 = 10; 6036 \\ return @truncate(i8, x); 6037 \\} 6038 \\ 6039 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 6040 , &[_][]const u8{ 6041 "tmp.zig:3:26: error: expected signed integer type, found 'u32'", 6042 }); 6043 6044 cases.add("try in function with non error return type", 6045 \\export fn f() void { 6046 \\ try something(); 6047 \\} 6048 \\fn something() anyerror!void { } 6049 , &[_][]const u8{ 6050 "tmp.zig:2:5: error: expected type 'void', found 'anyerror'", 6051 }); 6052 6053 cases.add("invalid pointer for var type", 6054 \\extern fn ext() usize; 6055 \\var bytes: [ext()]u8 = undefined; 6056 \\export fn f() void { 6057 \\ for (bytes) |*b, i| { 6058 \\ b.* = @as(u8, i); 6059 \\ } 6060 \\} 6061 , &[_][]const u8{ 6062 "tmp.zig:2:13: error: unable to evaluate constant expression", 6063 }); 6064 6065 cases.add("export function with comptime parameter", 6066 \\export fn foo(comptime x: i32, y: i32) i32{ 6067 \\ return x + y; 6068 \\} 6069 , &[_][]const u8{ 6070 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'", 6071 }); 6072 6073 cases.add("extern function with comptime parameter", 6074 \\extern fn foo(comptime x: i32, y: i32) i32; 6075 \\fn f() i32 { 6076 \\ return foo(1, 2); 6077 \\} 6078 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 6079 , &[_][]const u8{ 6080 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'", 6081 }); 6082 6083 cases.add("non-pure function returns type", 6084 \\var a: u32 = 0; 6085 \\pub fn List(comptime T: type) type { 6086 \\ a += 1; 6087 \\ return SmallList(T, 8); 6088 \\} 6089 \\ 6090 \\pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type { 6091 \\ return struct { 6092 \\ items: []T, 6093 \\ length: usize, 6094 \\ prealloc_items: [STATIC_SIZE]T, 6095 \\ }; 6096 \\} 6097 \\ 6098 \\export fn function_with_return_type_type() void { 6099 \\ var list: List(i32) = undefined; 6100 \\ list.length = 10; 6101 \\} 6102 , &[_][]const u8{ 6103 "tmp.zig:3:7: error: unable to evaluate constant expression", 6104 "tmp.zig:16:19: note: referenced here", 6105 }); 6106 6107 cases.add("bogus method call on slice", 6108 \\var self = "aoeu"; 6109 \\fn f(m: []const u8) void { 6110 \\ m.copy(u8, self[0..], m); 6111 \\} 6112 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 6113 , &[_][]const u8{ 6114 "tmp.zig:3:6: error: no member named 'copy' in '[]const u8'", 6115 }); 6116 6117 cases.add("wrong number of arguments for method fn call", 6118 \\const Foo = struct { 6119 \\ fn method(self: *const Foo, a: i32) void {} 6120 \\}; 6121 \\fn f(foo: *const Foo) void { 6122 \\ 6123 \\ foo.method(1, 2); 6124 \\} 6125 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } 6126 , &[_][]const u8{ 6127 "tmp.zig:6:15: error: expected 2 argument(s), found 3", 6128 }); 6129 6130 cases.add("assign through constant pointer", 6131 \\export fn f() void { 6132 \\ var cstr = "Hat"; 6133 \\ cstr[0] = 'W'; 6134 \\} 6135 , &[_][]const u8{ 6136 "tmp.zig:3:13: error: cannot assign to constant", 6137 }); 6138 6139 cases.add("assign through constant slice", 6140 \\export fn f() void { 6141 \\ var cstr: []const u8 = "Hat"; 6142 \\ cstr[0] = 'W'; 6143 \\} 6144 , &[_][]const u8{ 6145 "tmp.zig:3:13: error: cannot assign to constant", 6146 }); 6147 6148 cases.add("main function with bogus args type", 6149 \\pub fn main(args: [][]bogus) !void {} 6150 , &[_][]const u8{ 6151 "tmp.zig:1:23: error: use of undeclared identifier 'bogus'", 6152 }); 6153 6154 cases.add("misspelled type with pointer only reference", 6155 \\const JasonHM = u8; 6156 \\const JasonList = *JsonNode; 6157 \\ 6158 \\const JsonOA = union(enum) { 6159 \\ JSONArray: JsonList, 6160 \\ JSONObject: JasonHM, 6161 \\}; 6162 \\ 6163 \\const JsonType = union(enum) { 6164 \\ JSONNull: void, 6165 \\ JSONInteger: isize, 6166 \\ JSONDouble: f64, 6167 \\ JSONBool: bool, 6168 \\ JSONString: []u8, 6169 \\ JSONArray: void, 6170 \\ JSONObject: void, 6171 \\}; 6172 \\ 6173 \\pub const JsonNode = struct { 6174 \\ kind: JsonType, 6175 \\ jobject: ?JsonOA, 6176 \\}; 6177 \\ 6178 \\fn foo() void { 6179 \\ var jll: JasonList = undefined; 6180 \\ jll.init(1234); 6181 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} }; 6182 \\} 6183 \\ 6184 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 6185 , &[_][]const u8{ 6186 "tmp.zig:5:16: error: use of undeclared identifier 'JsonList'", 6187 }); 6188 6189 cases.add("method call with first arg type primitive", 6190 \\const Foo = struct { 6191 \\ x: i32, 6192 \\ 6193 \\ fn init(x: i32) Foo { 6194 \\ return Foo { 6195 \\ .x = x, 6196 \\ }; 6197 \\ } 6198 \\}; 6199 \\ 6200 \\export fn f() void { 6201 \\ const derp = Foo.init(3); 6202 \\ 6203 \\ derp.init(); 6204 \\} 6205 , &[_][]const u8{ 6206 "tmp.zig:14:5: error: expected type 'i32', found 'Foo'", 6207 }); 6208 6209 cases.add("method call with first arg type wrong container", 6210 \\pub const List = struct { 6211 \\ len: usize, 6212 \\ allocator: *Allocator, 6213 \\ 6214 \\ pub fn init(allocator: *Allocator) List { 6215 \\ return List { 6216 \\ .len = 0, 6217 \\ .allocator = allocator, 6218 \\ }; 6219 \\ } 6220 \\}; 6221 \\ 6222 \\pub var global_allocator = Allocator { 6223 \\ .field = 1234, 6224 \\}; 6225 \\ 6226 \\pub const Allocator = struct { 6227 \\ field: i32, 6228 \\}; 6229 \\ 6230 \\export fn foo() void { 6231 \\ var x = List.init(&global_allocator); 6232 \\ x.init(); 6233 \\} 6234 , &[_][]const u8{ 6235 "tmp.zig:23:5: error: expected type '*Allocator', found '*List'", 6236 }); 6237 6238 cases.add("binary not on number literal", 6239 \\const TINY_QUANTUM_SHIFT = 4; 6240 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT; 6241 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1); 6242 \\ 6243 \\export fn entry() usize { return @sizeOf(@TypeOf(block_aligned_stuff)); } 6244 , &[_][]const u8{ 6245 "tmp.zig:3:60: error: unable to perform binary not operation on type 'comptime_int'", 6246 }); 6247 6248 cases.addCase(x: { 6249 const tc = cases.create("multiple files with private function error", 6250 \\const foo = @import("foo.zig",); 6251 \\ 6252 \\export fn callPrivFunction() void { 6253 \\ foo.privateFunction(); 6254 \\} 6255 , &[_][]const u8{ 6256 "tmp.zig:4:8: error: 'privateFunction' is private", 6257 "foo.zig:1:1: note: declared here", 6258 }); 6259 6260 tc.addSourceFile("foo.zig", 6261 \\fn privateFunction() void { } 6262 ); 6263 6264 break :x tc; 6265 }); 6266 6267 cases.addCase(x: { 6268 const tc = cases.create("multiple files with private member instance function (canonical invocation) error", 6269 \\const Foo = @import("foo.zig",).Foo; 6270 \\ 6271 \\export fn callPrivFunction() void { 6272 \\ var foo = Foo{}; 6273 \\ Foo.privateFunction(foo); 6274 \\} 6275 , &[_][]const u8{ 6276 "tmp.zig:5:8: error: 'privateFunction' is private", 6277 "foo.zig:2:5: note: declared here", 6278 }); 6279 6280 tc.addSourceFile("foo.zig", 6281 \\pub const Foo = struct { 6282 \\ fn privateFunction(self: *Foo) void { } 6283 \\}; 6284 ); 6285 6286 break :x tc; 6287 }); 6288 6289 cases.addCase(x: { 6290 const tc = cases.create("multiple files with private member instance function error", 6291 \\const Foo = @import("foo.zig",).Foo; 6292 \\ 6293 \\export fn callPrivFunction() void { 6294 \\ var foo = Foo{}; 6295 \\ foo.privateFunction(); 6296 \\} 6297 , &[_][]const u8{ 6298 "tmp.zig:5:8: error: 'privateFunction' is private", 6299 "foo.zig:2:5: note: declared here", 6300 }); 6301 6302 tc.addSourceFile("foo.zig", 6303 \\pub const Foo = struct { 6304 \\ fn privateFunction(self: *Foo) void { } 6305 \\}; 6306 ); 6307 6308 break :x tc; 6309 }); 6310 6311 cases.add("container init with non-type", 6312 \\const zero: i32 = 0; 6313 \\const a = zero{1}; 6314 \\ 6315 \\export fn entry() usize { return @sizeOf(@TypeOf(a)); } 6316 , &[_][]const u8{ 6317 "tmp.zig:2:11: error: expected type 'type', found 'i32'", 6318 }); 6319 6320 cases.add("assign to constant field", 6321 \\const Foo = struct { 6322 \\ field: i32, 6323 \\}; 6324 \\export fn derp() void { 6325 \\ const f = Foo {.field = 1234,}; 6326 \\ f.field = 0; 6327 \\} 6328 , &[_][]const u8{ 6329 "tmp.zig:6:15: error: cannot assign to constant", 6330 }); 6331 6332 cases.add("return from defer expression", 6333 \\pub fn testTrickyDefer() !void { 6334 \\ defer canFail() catch {}; 6335 \\ 6336 \\ defer try canFail(); 6337 \\ 6338 \\ const a = maybeInt() orelse return; 6339 \\} 6340 \\ 6341 \\fn canFail() anyerror!void { } 6342 \\ 6343 \\pub fn maybeInt() ?i32 { 6344 \\ return 0; 6345 \\} 6346 \\ 6347 \\export fn entry() usize { return @sizeOf(@TypeOf(testTrickyDefer)); } 6348 , &[_][]const u8{ 6349 "tmp.zig:4:11: error: cannot return from defer expression", 6350 }); 6351 6352 cases.add("assign too big number to u16", 6353 \\export fn foo() void { 6354 \\ var vga_mem: u16 = 0xB8000; 6355 \\} 6356 , &[_][]const u8{ 6357 "tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'", 6358 }); 6359 6360 cases.add("global variable alignment non power of 2", 6361 \\const some_data: [100]u8 align(3) = undefined; 6362 \\export fn entry() usize { return @sizeOf(@TypeOf(some_data)); } 6363 , &[_][]const u8{ 6364 "tmp.zig:1:32: error: alignment value 3 is not a power of 2", 6365 }); 6366 6367 cases.add("function alignment non power of 2", 6368 \\extern fn foo() align(3) void; 6369 \\export fn entry() void { return foo(); } 6370 , &[_][]const u8{ 6371 "tmp.zig:1:23: error: alignment value 3 is not a power of 2", 6372 }); 6373 6374 cases.add("compile log", 6375 \\export fn foo() void { 6376 \\ comptime bar(12, "hi",); 6377 \\} 6378 \\fn bar(a: i32, b: []const u8) void { 6379 \\ @compileLog("begin",); 6380 \\ @compileLog("a", a, "b", b); 6381 \\ @compileLog("end",); 6382 \\} 6383 , &[_][]const u8{ 6384 "tmp.zig:5:5: error: found compile log statement", 6385 "tmp.zig:6:5: error: found compile log statement", 6386 "tmp.zig:7:5: error: found compile log statement", 6387 }); 6388 6389 cases.add("casting bit offset pointer to regular pointer", 6390 \\const BitField = packed struct { 6391 \\ a: u3, 6392 \\ b: u3, 6393 \\ c: u2, 6394 \\}; 6395 \\ 6396 \\fn foo(bit_field: *const BitField) u3 { 6397 \\ return bar(&bit_field.b); 6398 \\} 6399 \\ 6400 \\fn bar(x: *const u3) u3 { 6401 \\ return x.*; 6402 \\} 6403 \\ 6404 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 6405 , &[_][]const u8{ 6406 "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'", 6407 }); 6408 6409 cases.add("referring to a struct that is invalid", 6410 \\const UsbDeviceRequest = struct { 6411 \\ Type: u8, 6412 \\}; 6413 \\ 6414 \\export fn foo() void { 6415 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8); 6416 \\} 6417 \\ 6418 \\fn assert(ok: bool) void { 6419 \\ if (!ok) unreachable; 6420 \\} 6421 , &[_][]const u8{ 6422 "tmp.zig:10:14: error: reached unreachable code", 6423 "tmp.zig:6:20: note: referenced here", 6424 }); 6425 6426 cases.add("control flow uses comptime var at runtime", 6427 \\export fn foo() void { 6428 \\ comptime var i = 0; 6429 \\ while (i < 5) : (i += 1) { 6430 \\ bar(); 6431 \\ } 6432 \\} 6433 \\ 6434 \\fn bar() void { } 6435 , &[_][]const u8{ 6436 "tmp.zig:3:5: error: control flow attempts to use compile-time variable at runtime", 6437 "tmp.zig:3:24: note: compile-time variable assigned here", 6438 }); 6439 6440 cases.add("ignored return value", 6441 \\export fn foo() void { 6442 \\ bar(); 6443 \\} 6444 \\fn bar() i32 { return 0; } 6445 , &[_][]const u8{ 6446 "tmp.zig:2:8: error: expression value is ignored", 6447 }); 6448 6449 cases.add("ignored assert-err-ok return value", 6450 \\export fn foo() void { 6451 \\ bar() catch unreachable; 6452 \\} 6453 \\fn bar() anyerror!i32 { return 0; } 6454 , &[_][]const u8{ 6455 "tmp.zig:2:11: error: expression value is ignored", 6456 }); 6457 6458 cases.add("ignored statement value", 6459 \\export fn foo() void { 6460 \\ 1; 6461 \\} 6462 , &[_][]const u8{ 6463 "tmp.zig:2:5: error: expression value is ignored", 6464 }); 6465 6466 cases.add("ignored comptime statement value", 6467 \\export fn foo() void { 6468 \\ comptime {1;} 6469 \\} 6470 , &[_][]const u8{ 6471 "tmp.zig:2:15: error: expression value is ignored", 6472 }); 6473 6474 cases.add("ignored comptime value", 6475 \\export fn foo() void { 6476 \\ comptime 1; 6477 \\} 6478 , &[_][]const u8{ 6479 "tmp.zig:2:5: error: expression value is ignored", 6480 }); 6481 6482 cases.add("ignored defered statement value", 6483 \\export fn foo() void { 6484 \\ defer {1;} 6485 \\} 6486 , &[_][]const u8{ 6487 "tmp.zig:2:12: error: expression value is ignored", 6488 }); 6489 6490 cases.add("ignored defered function call", 6491 \\export fn foo() void { 6492 \\ defer bar(); 6493 \\} 6494 \\fn bar() anyerror!i32 { return 0; } 6495 , &[_][]const u8{ 6496 "tmp.zig:2:14: error: error is ignored. consider using `try`, `catch`, or `if`", 6497 }); 6498 6499 cases.add("dereference an array", 6500 \\var s_buffer: [10]u8 = undefined; 6501 \\pub fn pass(in: []u8) []u8 { 6502 \\ var out = &s_buffer; 6503 \\ out.*.* = in[0]; 6504 \\ return out.*[0..1]; 6505 \\} 6506 \\ 6507 \\export fn entry() usize { return @sizeOf(@TypeOf(pass)); } 6508 , &[_][]const u8{ 6509 "tmp.zig:4:10: error: attempt to dereference non-pointer type '[10]u8'", 6510 }); 6511 6512 cases.add("pass const ptr to mutable ptr fn", 6513 \\fn foo() bool { 6514 \\ const a = @as([]const u8, "a",); 6515 \\ const b = &a; 6516 \\ return ptrEql(b, b); 6517 \\} 6518 \\fn ptrEql(a: *[]const u8, b: *[]const u8) bool { 6519 \\ return true; 6520 \\} 6521 \\ 6522 \\export fn entry() usize { return @sizeOf(@TypeOf(foo)); } 6523 , &[_][]const u8{ 6524 "tmp.zig:4:19: error: expected type '*[]const u8', found '*const []const u8'", 6525 }); 6526 6527 cases.addCase(x: { 6528 const tc = cases.create("export collision", 6529 \\const foo = @import("foo.zig",); 6530 \\ 6531 \\export fn bar() usize { 6532 \\ return foo.baz; 6533 \\} 6534 , &[_][]const u8{ 6535 "foo.zig:1:1: error: exported symbol collision: 'bar'", 6536 "tmp.zig:3:1: note: other symbol here", 6537 }); 6538 6539 tc.addSourceFile("foo.zig", 6540 \\export fn bar() void {} 6541 \\pub const baz = 1234; 6542 ); 6543 6544 break :x tc; 6545 }); 6546 6547 cases.add("implicit cast from array to mutable slice", 6548 \\var global_array: [10]i32 = undefined; 6549 \\fn foo(param: []i32) void {} 6550 \\export fn entry() void { 6551 \\ foo(global_array); 6552 \\} 6553 , &[_][]const u8{ 6554 "tmp.zig:4:9: error: expected type '[]i32', found '[10]i32'", 6555 }); 6556 6557 cases.add("ptrcast to non-pointer", 6558 \\export fn entry(a: *i32) usize { 6559 \\ return @ptrCast(usize, a); 6560 \\} 6561 , &[_][]const u8{ 6562 "tmp.zig:2:21: error: expected pointer, found 'usize'", 6563 }); 6564 6565 cases.add("asm at compile time", 6566 \\comptime { 6567 \\ doSomeAsm(); 6568 \\} 6569 \\ 6570 \\fn doSomeAsm() void { 6571 \\ asm volatile ( 6572 \\ \\.globl aoeu; 6573 \\ \\.type aoeu, @function; 6574 \\ \\.set aoeu, derp; 6575 \\ ); 6576 \\} 6577 , &[_][]const u8{ 6578 "tmp.zig:6:5: error: unable to evaluate constant expression", 6579 }); 6580 6581 cases.add("invalid member of builtin enum", 6582 \\const builtin = @import("builtin",); 6583 \\export fn entry() void { 6584 \\ const foo = builtin.Arch.x86; 6585 \\} 6586 , &[_][]const u8{ 6587 "tmp.zig:3:29: error: container 'std.target.Arch' has no member called 'x86'", 6588 }); 6589 6590 cases.add("int to ptr of 0 bits", 6591 \\export fn foo() void { 6592 \\ var x: usize = 0x1000; 6593 \\ var y: *void = @intToPtr(*void, x); 6594 \\} 6595 , &[_][]const u8{ 6596 "tmp.zig:3:30: error: type '*void' has 0 bits and cannot store information", 6597 }); 6598 6599 cases.add("@fieldParentPtr - non struct", 6600 \\const Foo = i32; 6601 \\export fn foo(a: *i32) *Foo { 6602 \\ return @fieldParentPtr(Foo, "a", a); 6603 \\} 6604 , &[_][]const u8{ 6605 "tmp.zig:3:28: error: expected struct type, found 'i32'", 6606 }); 6607 6608 cases.add("@fieldParentPtr - bad field name", 6609 \\const Foo = extern struct { 6610 \\ derp: i32, 6611 \\}; 6612 \\export fn foo(a: *i32) *Foo { 6613 \\ return @fieldParentPtr(Foo, "a", a); 6614 \\} 6615 , &[_][]const u8{ 6616 "tmp.zig:5:33: error: struct 'Foo' has no field 'a'", 6617 }); 6618 6619 cases.add("@fieldParentPtr - field pointer is not pointer", 6620 \\const Foo = extern struct { 6621 \\ a: i32, 6622 \\}; 6623 \\export fn foo(a: i32) *Foo { 6624 \\ return @fieldParentPtr(Foo, "a", a); 6625 \\} 6626 , &[_][]const u8{ 6627 "tmp.zig:5:38: error: expected pointer, found 'i32'", 6628 }); 6629 6630 cases.add("@fieldParentPtr - comptime field ptr not based on struct", 6631 \\const Foo = struct { 6632 \\ a: i32, 6633 \\ b: i32, 6634 \\}; 6635 \\const foo = Foo { .a = 1, .b = 2, }; 6636 \\ 6637 \\comptime { 6638 \\ const field_ptr = @intToPtr(*i32, 0x1234); 6639 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr); 6640 \\} 6641 , &[_][]const u8{ 6642 "tmp.zig:9:55: error: pointer value not based on parent struct", 6643 }); 6644 6645 cases.add("@fieldParentPtr - comptime wrong field index", 6646 \\const Foo = struct { 6647 \\ a: i32, 6648 \\ b: i32, 6649 \\}; 6650 \\const foo = Foo { .a = 1, .b = 2, }; 6651 \\ 6652 \\comptime { 6653 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a); 6654 \\} 6655 , &[_][]const u8{ 6656 "tmp.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'", 6657 }); 6658 6659 cases.add("@byteOffsetOf - non struct", 6660 \\const Foo = i32; 6661 \\export fn foo() usize { 6662 \\ return @byteOffsetOf(Foo, "a",); 6663 \\} 6664 , &[_][]const u8{ 6665 "tmp.zig:3:26: error: expected struct type, found 'i32'", 6666 }); 6667 6668 cases.add("@byteOffsetOf - bad field name", 6669 \\const Foo = struct { 6670 \\ derp: i32, 6671 \\}; 6672 \\export fn foo() usize { 6673 \\ return @byteOffsetOf(Foo, "a",); 6674 \\} 6675 , &[_][]const u8{ 6676 "tmp.zig:5:31: error: struct 'Foo' has no field 'a'", 6677 }); 6678 6679 cases.addExe("missing main fn in executable", 6680 \\ 6681 , &[_][]const u8{ 6682 "error: root source file has no member called 'main'", 6683 }); 6684 6685 cases.addExe("private main fn", 6686 \\fn main() void {} 6687 , &[_][]const u8{ 6688 "error: 'main' is private", 6689 "tmp.zig:1:1: note: declared here", 6690 }); 6691 6692 cases.add("setting a section on a local variable", 6693 \\export fn entry() i32 { 6694 \\ var foo: i32 linksection(".text2") = 1234; 6695 \\ return foo; 6696 \\} 6697 , &[_][]const u8{ 6698 "tmp.zig:2:30: error: cannot set section of local variable 'foo'", 6699 }); 6700 6701 cases.add("inner struct member shadowing outer struct member", 6702 \\fn A() type { 6703 \\ return struct { 6704 \\ b: B(), 6705 \\ 6706 \\ const Self = @This(); 6707 \\ 6708 \\ fn B() type { 6709 \\ return struct { 6710 \\ const Self = @This(); 6711 \\ }; 6712 \\ } 6713 \\ }; 6714 \\} 6715 \\comptime { 6716 \\ assert(A().B().Self != A().Self); 6717 \\} 6718 \\fn assert(ok: bool) void { 6719 \\ if (!ok) unreachable; 6720 \\} 6721 , &[_][]const u8{ 6722 "tmp.zig:9:17: error: redefinition of 'Self'", 6723 "tmp.zig:5:9: note: previous definition is here", 6724 }); 6725 6726 cases.add("while expected bool, got optional", 6727 \\export fn foo() void { 6728 \\ while (bar()) {} 6729 \\} 6730 \\fn bar() ?i32 { return 1; } 6731 , &[_][]const u8{ 6732 "tmp.zig:2:15: error: expected type 'bool', found '?i32'", 6733 }); 6734 6735 cases.add("while expected bool, got error union", 6736 \\export fn foo() void { 6737 \\ while (bar()) {} 6738 \\} 6739 \\fn bar() anyerror!i32 { return 1; } 6740 , &[_][]const u8{ 6741 "tmp.zig:2:15: error: expected type 'bool', found 'anyerror!i32'", 6742 }); 6743 6744 cases.add("while expected optional, got bool", 6745 \\export fn foo() void { 6746 \\ while (bar()) |x| {} 6747 \\} 6748 \\fn bar() bool { return true; } 6749 , &[_][]const u8{ 6750 "tmp.zig:2:15: error: expected optional type, found 'bool'", 6751 }); 6752 6753 cases.add("while expected optional, got error union", 6754 \\export fn foo() void { 6755 \\ while (bar()) |x| {} 6756 \\} 6757 \\fn bar() anyerror!i32 { return 1; } 6758 , &[_][]const u8{ 6759 "tmp.zig:2:15: error: expected optional type, found 'anyerror!i32'", 6760 }); 6761 6762 cases.add("while expected error union, got bool", 6763 \\export fn foo() void { 6764 \\ while (bar()) |x| {} else |err| {} 6765 \\} 6766 \\fn bar() bool { return true; } 6767 , &[_][]const u8{ 6768 "tmp.zig:2:15: error: expected error union type, found 'bool'", 6769 }); 6770 6771 cases.add("while expected error union, got optional", 6772 \\export fn foo() void { 6773 \\ while (bar()) |x| {} else |err| {} 6774 \\} 6775 \\fn bar() ?i32 { return 1; } 6776 , &[_][]const u8{ 6777 "tmp.zig:2:15: error: expected error union type, found '?i32'", 6778 }); 6779 6780 // TODO test this in stage2, but we won't even try in stage1 6781 //cases.add("inline fn calls itself indirectly", 6782 // \\export fn foo() void { 6783 // \\ bar(); 6784 // \\} 6785 // \\inline fn bar() void { 6786 // \\ baz(); 6787 // \\ quux(); 6788 // \\} 6789 // \\inline fn baz() void { 6790 // \\ bar(); 6791 // \\ quux(); 6792 // \\} 6793 // \\extern fn quux() void; 6794 //, &[_][]const u8{ 6795 // "tmp.zig:4:1: error: unable to inline function", 6796 //}); 6797 6798 //cases.add("save reference to inline function", 6799 // \\export fn foo() void { 6800 // \\ quux(@ptrToInt(bar)); 6801 // \\} 6802 // \\inline fn bar() void { } 6803 // \\extern fn quux(usize) void; 6804 //, &[_][]const u8{ 6805 // "tmp.zig:4:1: error: unable to inline function", 6806 //}); 6807 6808 cases.add("signed integer division", 6809 \\export fn foo(a: i32, b: i32) i32 { 6810 \\ return a / b; 6811 \\} 6812 , &[_][]const u8{ 6813 "tmp.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact", 6814 }); 6815 6816 cases.add("signed integer remainder division", 6817 \\export fn foo(a: i32, b: i32) i32 { 6818 \\ return a % b; 6819 \\} 6820 , &[_][]const u8{ 6821 "tmp.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod", 6822 }); 6823 6824 cases.add("compile-time division by zero", 6825 \\comptime { 6826 \\ const a: i32 = 1; 6827 \\ const b: i32 = 0; 6828 \\ const c = a / b; 6829 \\} 6830 , &[_][]const u8{ 6831 "tmp.zig:4:17: error: division by zero", 6832 }); 6833 6834 cases.add("compile-time remainder division by zero", 6835 \\comptime { 6836 \\ const a: i32 = 1; 6837 \\ const b: i32 = 0; 6838 \\ const c = a % b; 6839 \\} 6840 , &[_][]const u8{ 6841 "tmp.zig:4:17: error: division by zero", 6842 }); 6843 6844 cases.add("@setRuntimeSafety twice for same scope", 6845 \\export fn foo() void { 6846 \\ @setRuntimeSafety(false); 6847 \\ @setRuntimeSafety(false); 6848 \\} 6849 , &[_][]const u8{ 6850 "tmp.zig:3:5: error: runtime safety set twice for same scope", 6851 "tmp.zig:2:5: note: first set here", 6852 }); 6853 6854 cases.add("@setFloatMode twice for same scope", 6855 \\export fn foo() void { 6856 \\ @setFloatMode(@import("builtin").FloatMode.Optimized); 6857 \\ @setFloatMode(@import("builtin").FloatMode.Optimized); 6858 \\} 6859 , &[_][]const u8{ 6860 "tmp.zig:3:5: error: float mode set twice for same scope", 6861 "tmp.zig:2:5: note: first set here", 6862 }); 6863 6864 cases.add("array access of type", 6865 \\export fn foo() void { 6866 \\ var b: u8[40] = undefined; 6867 \\} 6868 , &[_][]const u8{ 6869 "tmp.zig:2:14: error: array access of non-array type 'type'", 6870 }); 6871 6872 cases.add("cannot break out of defer expression", 6873 \\export fn foo() void { 6874 \\ while (true) { 6875 \\ defer { 6876 \\ break; 6877 \\ } 6878 \\ } 6879 \\} 6880 , &[_][]const u8{ 6881 "tmp.zig:4:13: error: cannot break out of defer expression", 6882 }); 6883 6884 cases.add("cannot continue out of defer expression", 6885 \\export fn foo() void { 6886 \\ while (true) { 6887 \\ defer { 6888 \\ continue; 6889 \\ } 6890 \\ } 6891 \\} 6892 , &[_][]const u8{ 6893 "tmp.zig:4:13: error: cannot continue out of defer expression", 6894 }); 6895 6896 cases.add("calling a generic function only known at runtime", 6897 \\var foos = [_]fn(anytype) void { foo1, foo2 }; 6898 \\ 6899 \\fn foo1(arg: anytype) void {} 6900 \\fn foo2(arg: anytype) void {} 6901 \\ 6902 \\pub fn main() !void { 6903 \\ foos[0](true); 6904 \\} 6905 , &[_][]const u8{ 6906 "tmp.zig:7:9: error: calling a generic function requires compile-time known function value", 6907 }); 6908 6909 cases.add("@compileError shows traceback of references that caused it", 6910 \\const foo = @compileError("aoeu",); 6911 \\ 6912 \\const bar = baz + foo; 6913 \\const baz = 1; 6914 \\ 6915 \\export fn entry() i32 { 6916 \\ return bar; 6917 \\} 6918 , &[_][]const u8{ 6919 "tmp.zig:1:13: error: aoeu", 6920 "tmp.zig:3:19: note: referenced here", 6921 "tmp.zig:7:12: note: referenced here", 6922 }); 6923 6924 cases.add("float literal too large error", 6925 \\comptime { 6926 \\ const a = 0x1.0p18495; 6927 \\} 6928 , &[_][]const u8{ 6929 "tmp.zig:2:15: error: float literal out of range of any type", 6930 }); 6931 6932 cases.add("float literal too small error (denormal)", 6933 \\comptime { 6934 \\ const a = 0x1.0p-19000; 6935 \\} 6936 , &[_][]const u8{ 6937 "tmp.zig:2:15: error: float literal out of range of any type", 6938 }); 6939 6940 cases.add("explicit cast float literal to integer when there is a fraction component", 6941 \\export fn entry() i32 { 6942 \\ return @as(i32, 12.34); 6943 \\} 6944 , &[_][]const u8{ 6945 "tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'", 6946 }); 6947 6948 cases.add("non pointer given to @ptrToInt", 6949 \\export fn entry(x: i32) usize { 6950 \\ return @ptrToInt(x); 6951 \\} 6952 , &[_][]const u8{ 6953 "tmp.zig:2:22: error: expected pointer, found 'i32'", 6954 }); 6955 6956 cases.add("@shlExact shifts out 1 bits", 6957 \\comptime { 6958 \\ const x = @shlExact(@as(u8, 0b01010101), 2); 6959 \\} 6960 , &[_][]const u8{ 6961 "tmp.zig:2:15: error: operation caused overflow", 6962 }); 6963 6964 cases.add("@shrExact shifts out 1 bits", 6965 \\comptime { 6966 \\ const x = @shrExact(@as(u8, 0b10101010), 2); 6967 \\} 6968 , &[_][]const u8{ 6969 "tmp.zig:2:15: error: exact shift shifted out 1 bits", 6970 }); 6971 6972 cases.add("shifting without int type or comptime known", 6973 \\export fn entry(x: u8) u8 { 6974 \\ return 0x11 << x; 6975 \\} 6976 , &[_][]const u8{ 6977 "tmp.zig:2:17: error: LHS of shift must be a fixed-width integer type, or RHS must be compile-time known", 6978 }); 6979 6980 cases.add("shifting RHS is log2 of LHS int bit width", 6981 \\export fn entry(x: u8, y: u8) u8 { 6982 \\ return x << y; 6983 \\} 6984 , &[_][]const u8{ 6985 "tmp.zig:2:17: error: expected type 'u3', found 'u8'", 6986 }); 6987 6988 cases.add("globally shadowing a primitive type", 6989 \\const u16 = u8; 6990 \\export fn entry() void { 6991 \\ const a: u16 = 300; 6992 \\} 6993 , &[_][]const u8{ 6994 "tmp.zig:1:1: error: declaration shadows primitive type 'u16'", 6995 }); 6996 6997 cases.add("implicitly increasing pointer alignment", 6998 \\const Foo = packed struct { 6999 \\ a: u8, 7000 \\ b: u32, 7001 \\}; 7002 \\ 7003 \\export fn entry() void { 7004 \\ var foo = Foo { .a = 1, .b = 10 }; 7005 \\ bar(&foo.b); 7006 \\} 7007 \\ 7008 \\fn bar(x: *u32) void { 7009 \\ x.* += 1; 7010 \\} 7011 , &[_][]const u8{ 7012 "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'", 7013 }); 7014 7015 cases.add("implicitly increasing slice alignment", 7016 \\const Foo = packed struct { 7017 \\ a: u8, 7018 \\ b: u32, 7019 \\}; 7020 \\ 7021 \\export fn entry() void { 7022 \\ var foo = Foo { .a = 1, .b = 10 }; 7023 \\ foo.b += 1; 7024 \\ bar(@as(*[1]u32, &foo.b)[0..]); 7025 \\} 7026 \\ 7027 \\fn bar(x: []u32) void { 7028 \\ x[0] += 1; 7029 \\} 7030 , &[_][]const u8{ 7031 "tmp.zig:9:26: error: cast increases pointer alignment", 7032 "tmp.zig:9:26: note: '*align(1) u32' has alignment 1", 7033 "tmp.zig:9:26: note: '*[1]u32' has alignment 4", 7034 }); 7035 7036 cases.add("increase pointer alignment in @ptrCast", 7037 \\export fn entry() u32 { 7038 \\ var bytes: [4]u8 = [_]u8{0x01, 0x02, 0x03, 0x04}; 7039 \\ const ptr = @ptrCast(*u32, &bytes[0]); 7040 \\ return ptr.*; 7041 \\} 7042 , &[_][]const u8{ 7043 "tmp.zig:3:17: error: cast increases pointer alignment", 7044 "tmp.zig:3:38: note: '*u8' has alignment 1", 7045 "tmp.zig:3:26: note: '*u32' has alignment 4", 7046 }); 7047 7048 cases.add("@alignCast expects pointer or slice", 7049 \\export fn entry() void { 7050 \\ @alignCast(4, @as(u32, 3)); 7051 \\} 7052 , &[_][]const u8{ 7053 "tmp.zig:2:19: error: expected pointer or slice, found 'u32'", 7054 }); 7055 7056 cases.add("passing an under-aligned function pointer", 7057 \\export fn entry() void { 7058 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234); 7059 \\} 7060 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) i32, answer: i32) void { 7061 \\ if (ptr() != answer) unreachable; 7062 \\} 7063 \\fn alignedSmall() align(4) i32 { return 1234; } 7064 , &[_][]const u8{ 7065 "tmp.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'", 7066 }); 7067 7068 cases.add("passing a not-aligned-enough pointer to cmpxchg", 7069 \\const AtomicOrder = @import("builtin").AtomicOrder; 7070 \\export fn entry() bool { 7071 \\ var x: i32 align(1) = 1234; 7072 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {} 7073 \\ return x == 5678; 7074 \\} 7075 , &[_][]const u8{ 7076 "tmp.zig:4:32: error: expected type '*i32', found '*align(1) i32'", 7077 }); 7078 7079 cases.add("wrong size to an array literal", 7080 \\comptime { 7081 \\ const array = [2]u8{1, 2, 3}; 7082 \\} 7083 , &[_][]const u8{ 7084 "tmp.zig:2:31: error: index 2 outside array of size 2", 7085 }); 7086 7087 cases.add("wrong pointer coerced to pointer to opaque {}", 7088 \\const Derp = opaque {}; 7089 \\extern fn bar(d: *Derp) void; 7090 \\export fn foo() void { 7091 \\ var x = @as(u8, 1); 7092 \\ bar(@ptrCast(*c_void, &x)); 7093 \\} 7094 , &[_][]const u8{ 7095 "tmp.zig:5:9: error: expected type '*Derp', found '*c_void'", 7096 }); 7097 7098 cases.add("non-const variables of things that require const variables", 7099 \\export fn entry1() void { 7100 \\ var m2 = &2; 7101 \\} 7102 \\export fn entry2() void { 7103 \\ var a = undefined; 7104 \\} 7105 \\export fn entry3() void { 7106 \\ var b = 1; 7107 \\} 7108 \\export fn entry4() void { 7109 \\ var c = 1.0; 7110 \\} 7111 \\export fn entry5() void { 7112 \\ var d = null; 7113 \\} 7114 \\export fn entry6(opaque_: *Opaque) void { 7115 \\ var e = opaque_.*; 7116 \\} 7117 \\export fn entry7() void { 7118 \\ var f = i32; 7119 \\} 7120 \\export fn entry8() void { 7121 \\ var h = (Foo {}).bar; 7122 \\} 7123 \\export fn entry9() void { 7124 \\ var z: noreturn = return; 7125 \\} 7126 \\const Opaque = opaque {}; 7127 \\const Foo = struct { 7128 \\ fn bar(self: *const Foo) void {} 7129 \\}; 7130 , &[_][]const u8{ 7131 "tmp.zig:2:4: error: variable of type '*const comptime_int' must be const or comptime", 7132 "tmp.zig:5:4: error: variable of type '(undefined)' must be const or comptime", 7133 "tmp.zig:8:4: error: variable of type 'comptime_int' must be const or comptime", 7134 "tmp.zig:8:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type", 7135 "tmp.zig:11:4: error: variable of type 'comptime_float' must be const or comptime", 7136 "tmp.zig:11:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type", 7137 "tmp.zig:14:4: error: variable of type '(null)' must be const or comptime", 7138 "tmp.zig:17:4: error: variable of type 'Opaque' not allowed", 7139 "tmp.zig:20:4: error: variable of type 'type' must be const or comptime", 7140 "tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime", 7141 "tmp.zig:26:22: error: unreachable code", 7142 }); 7143 7144 cases.add("wrong types given to atomic order args in cmpxchg", 7145 \\export fn entry() void { 7146 \\ var x: i32 = 1234; 7147 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {} 7148 \\} 7149 , &[_][]const u8{ 7150 "tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'", 7151 }); 7152 7153 cases.add("wrong types given to @export", 7154 \\fn entry() callconv(.C) void { } 7155 \\comptime { 7156 \\ @export(entry, .{.name = "entry", .linkage = @as(u32, 1234) }); 7157 \\} 7158 , &[_][]const u8{ 7159 "tmp.zig:3:59: error: expected type 'std.builtin.GlobalLinkage', found 'comptime_int'", 7160 }); 7161 7162 cases.add("struct with invalid field", 7163 \\const std = @import("std",); 7164 \\const Allocator = std.mem.Allocator; 7165 \\const ArrayList = std.ArrayList; 7166 \\ 7167 \\const HeaderWeight = enum { 7168 \\ H1, H2, H3, H4, H5, H6, 7169 \\}; 7170 \\ 7171 \\const MdText = ArrayList(u8); 7172 \\ 7173 \\const MdNode = union(enum) { 7174 \\ Header: struct { 7175 \\ text: MdText, 7176 \\ weight: HeaderValue, 7177 \\ }, 7178 \\}; 7179 \\ 7180 \\export fn entry() void { 7181 \\ const a = MdNode.Header { 7182 \\ .text = MdText.init(&std.testing.allocator), 7183 \\ .weight = HeaderWeight.H1, 7184 \\ }; 7185 \\} 7186 , &[_][]const u8{ 7187 "tmp.zig:14:17: error: use of undeclared identifier 'HeaderValue'", 7188 }); 7189 7190 cases.add("@setAlignStack outside function", 7191 \\comptime { 7192 \\ @setAlignStack(16); 7193 \\} 7194 , &[_][]const u8{ 7195 "tmp.zig:2:5: error: @setAlignStack outside function", 7196 }); 7197 7198 cases.add("@setAlignStack in naked function", 7199 \\export fn entry() callconv(.Naked) void { 7200 \\ @setAlignStack(16); 7201 \\} 7202 , &[_][]const u8{ 7203 "tmp.zig:2:5: error: @setAlignStack in naked function", 7204 }); 7205 7206 cases.add("@setAlignStack in inline function", 7207 \\export fn entry() void { 7208 \\ foo(); 7209 \\} 7210 \\inline fn foo() void { 7211 \\ @setAlignStack(16); 7212 \\} 7213 , &[_][]const u8{ 7214 "tmp.zig:5:5: error: @setAlignStack in inline function", 7215 }); 7216 7217 cases.add("@setAlignStack set twice", 7218 \\export fn entry() void { 7219 \\ @setAlignStack(16); 7220 \\ @setAlignStack(16); 7221 \\} 7222 , &[_][]const u8{ 7223 "tmp.zig:3:5: error: alignstack set twice", 7224 "tmp.zig:2:5: note: first set here", 7225 }); 7226 7227 cases.add("@setAlignStack too big", 7228 \\export fn entry() void { 7229 \\ @setAlignStack(511 + 1); 7230 \\} 7231 , &[_][]const u8{ 7232 "tmp.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256", 7233 }); 7234 7235 cases.add("storing runtime value in compile time variable then using it", 7236 \\const Mode = @import("builtin").Mode; 7237 \\ 7238 \\fn Free(comptime filename: []const u8) TestCase { 7239 \\ return TestCase { 7240 \\ .filename = filename, 7241 \\ .problem_type = ProblemType.Free, 7242 \\ }; 7243 \\} 7244 \\ 7245 \\fn LibC(comptime filename: []const u8) TestCase { 7246 \\ return TestCase { 7247 \\ .filename = filename, 7248 \\ .problem_type = ProblemType.LinkLibC, 7249 \\ }; 7250 \\} 7251 \\ 7252 \\const TestCase = struct { 7253 \\ filename: []const u8, 7254 \\ problem_type: ProblemType, 7255 \\}; 7256 \\ 7257 \\const ProblemType = enum { 7258 \\ Free, 7259 \\ LinkLibC, 7260 \\}; 7261 \\ 7262 \\export fn entry() void { 7263 \\ const tests = [_]TestCase { 7264 \\ Free("001"), 7265 \\ Free("002"), 7266 \\ LibC("078"), 7267 \\ Free("116"), 7268 \\ Free("117"), 7269 \\ }; 7270 \\ 7271 \\ for ([_]Mode { Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast }) |mode| { 7272 \\ inline for (tests) |test_case| { 7273 \\ const foo = test_case.filename ++ ".zig"; 7274 \\ } 7275 \\ } 7276 \\} 7277 , &[_][]const u8{ 7278 "tmp.zig:37:29: error: cannot store runtime value in compile time variable", 7279 }); 7280 7281 cases.add("invalid legacy unicode escape", 7282 \\export fn entry() void { 7283 \\ const a = '\U1234'; 7284 \\} 7285 , &[_][]const u8{ 7286 "tmp.zig:2:17: error: invalid character: 'U'", 7287 }); 7288 7289 cases.add("invalid empty unicode escape", 7290 \\export fn entry() void { 7291 \\ const a = '\u{}'; 7292 \\} 7293 , &[_][]const u8{ 7294 "tmp.zig:2:19: error: empty unicode escape sequence", 7295 }); 7296 7297 cases.add("non-printable invalid character", "\xff\xfe" ++ 7298 \\fn test() bool {\r 7299 \\ true\r 7300 \\} 7301 , &[_][]const u8{ 7302 "tmp.zig:1:1: error: invalid character: '\\xff'", 7303 }); 7304 7305 cases.add("non-printable invalid character with escape alternative", "fn test() bool {\n" ++ 7306 "\ttrue\n" ++ 7307 "}\n", &[_][]const u8{ 7308 "tmp.zig:2:1: error: invalid character: '\\t'", 7309 }); 7310 7311 cases.add("calling var args extern function, passing array instead of pointer", 7312 \\export fn entry() void { 7313 \\ foo("hello".*,); 7314 \\} 7315 \\pub extern fn foo(format: *const u8, ...) void; 7316 , &[_][]const u8{ 7317 "tmp.zig:2:16: error: expected type '*const u8', found '[5:0]u8'", 7318 }); 7319 7320 cases.add("constant inside comptime function has compile error", 7321 \\const ContextAllocator = MemoryPool(usize); 7322 \\ 7323 \\pub fn MemoryPool(comptime T: type) type { 7324 \\ const free_list_t = @compileError("aoeu",); 7325 \\ 7326 \\ return struct { 7327 \\ free_list: free_list_t, 7328 \\ }; 7329 \\} 7330 \\ 7331 \\export fn entry() void { 7332 \\ var allocator: ContextAllocator = undefined; 7333 \\} 7334 , &[_][]const u8{ 7335 "tmp.zig:4:25: error: aoeu", 7336 "tmp.zig:1:36: note: referenced here", 7337 "tmp.zig:12:20: note: referenced here", 7338 }); 7339 7340 cases.add("specify enum tag type that is too small", 7341 \\const Small = enum (u2) { 7342 \\ One, 7343 \\ Two, 7344 \\ Three, 7345 \\ Four, 7346 \\ Five, 7347 \\}; 7348 \\ 7349 \\export fn entry() void { 7350 \\ var x = Small.One; 7351 \\} 7352 , &[_][]const u8{ 7353 "tmp.zig:6:5: error: enumeration value 4 too large for type 'u2'", 7354 }); 7355 7356 cases.add("specify non-integer enum tag type", 7357 \\const Small = enum (f32) { 7358 \\ One, 7359 \\ Two, 7360 \\ Three, 7361 \\}; 7362 \\ 7363 \\export fn entry() void { 7364 \\ var x = Small.One; 7365 \\} 7366 , &[_][]const u8{ 7367 "tmp.zig:1:21: error: expected integer, found 'f32'", 7368 }); 7369 7370 cases.add("implicitly casting enum to tag type", 7371 \\const Small = enum(u2) { 7372 \\ One, 7373 \\ Two, 7374 \\ Three, 7375 \\ Four, 7376 \\}; 7377 \\ 7378 \\export fn entry() void { 7379 \\ var x: u2 = Small.Two; 7380 \\} 7381 , &[_][]const u8{ 7382 "tmp.zig:9:22: error: expected type 'u2', found 'Small'", 7383 }); 7384 7385 cases.add("explicitly casting non tag type to enum", 7386 \\const Small = enum(u2) { 7387 \\ One, 7388 \\ Two, 7389 \\ Three, 7390 \\ Four, 7391 \\}; 7392 \\ 7393 \\export fn entry() void { 7394 \\ var y = @as(u3, 3); 7395 \\ var x = @intToEnum(Small, y); 7396 \\} 7397 , &[_][]const u8{ 7398 "tmp.zig:10:31: error: expected type 'u2', found 'u3'", 7399 }); 7400 7401 cases.add("union fields with value assignments", 7402 \\const MultipleChoice = union { 7403 \\ A: i32 = 20, 7404 \\}; 7405 \\export fn entry() void { 7406 \\ var x: MultipleChoice = undefined; 7407 \\} 7408 , &[_][]const u8{ 7409 "tmp.zig:2:14: error: untagged union field assignment", 7410 "tmp.zig:1:24: note: consider 'union(enum)' here", 7411 }); 7412 7413 cases.add("enum with 0 fields", 7414 \\const Foo = enum {}; 7415 \\export fn entry() usize { 7416 \\ return @sizeOf(Foo); 7417 \\} 7418 , &[_][]const u8{ 7419 "tmp.zig:1:13: error: enums must have 1 or more fields", 7420 }); 7421 7422 cases.add("union with 0 fields", 7423 \\const Foo = union {}; 7424 \\export fn entry() usize { 7425 \\ return @sizeOf(Foo); 7426 \\} 7427 , &[_][]const u8{ 7428 "tmp.zig:1:13: error: unions must have 1 or more fields", 7429 }); 7430 7431 cases.add("enum value already taken", 7432 \\const MultipleChoice = enum(u32) { 7433 \\ A = 20, 7434 \\ B = 40, 7435 \\ C = 60, 7436 \\ D = 1000, 7437 \\ E = 60, 7438 \\}; 7439 \\export fn entry() void { 7440 \\ var x = MultipleChoice.C; 7441 \\} 7442 , &[_][]const u8{ 7443 "tmp.zig:6:5: error: enum tag value 60 already taken", 7444 "tmp.zig:4:5: note: other occurrence here", 7445 }); 7446 7447 cases.add("union with specified enum omits field", 7448 \\const Letter = enum { 7449 \\ A, 7450 \\ B, 7451 \\ C, 7452 \\}; 7453 \\const Payload = union(Letter) { 7454 \\ A: i32, 7455 \\ B: f64, 7456 \\}; 7457 \\export fn entry() usize { 7458 \\ return @sizeOf(Payload); 7459 \\} 7460 , &[_][]const u8{ 7461 "tmp.zig:6:17: error: enum field missing: 'C'", 7462 "tmp.zig:4:5: note: declared here", 7463 }); 7464 7465 cases.add("@TagType when union has no attached enum", 7466 \\const Foo = union { 7467 \\ A: i32, 7468 \\}; 7469 \\export fn entry() void { 7470 \\ const x = @TagType(Foo); 7471 \\} 7472 , &[_][]const u8{ 7473 "tmp.zig:5:24: error: union 'Foo' has no tag", 7474 "tmp.zig:1:13: note: consider 'union(enum)' here", 7475 }); 7476 7477 cases.add("non-integer tag type to automatic union enum", 7478 \\const Foo = union(enum(f32)) { 7479 \\ A: i32, 7480 \\}; 7481 \\export fn entry() void { 7482 \\ const x = @TagType(Foo); 7483 \\} 7484 , &[_][]const u8{ 7485 "tmp.zig:1:24: error: expected integer tag type, found 'f32'", 7486 }); 7487 7488 cases.add("non-enum tag type passed to union", 7489 \\const Foo = union(u32) { 7490 \\ A: i32, 7491 \\}; 7492 \\export fn entry() void { 7493 \\ const x = @TagType(Foo); 7494 \\} 7495 , &[_][]const u8{ 7496 "tmp.zig:1:19: error: expected enum tag type, found 'u32'", 7497 }); 7498 7499 cases.add("union auto-enum value already taken", 7500 \\const MultipleChoice = union(enum(u32)) { 7501 \\ A = 20, 7502 \\ B = 40, 7503 \\ C = 60, 7504 \\ D = 1000, 7505 \\ E = 60, 7506 \\}; 7507 \\export fn entry() void { 7508 \\ var x = MultipleChoice { .C = {} }; 7509 \\} 7510 , &[_][]const u8{ 7511 "tmp.zig:6:9: error: enum tag value 60 already taken", 7512 "tmp.zig:4:9: note: other occurrence here", 7513 }); 7514 7515 cases.add("union enum field does not match enum", 7516 \\const Letter = enum { 7517 \\ A, 7518 \\ B, 7519 \\ C, 7520 \\}; 7521 \\const Payload = union(Letter) { 7522 \\ A: i32, 7523 \\ B: f64, 7524 \\ C: bool, 7525 \\ D: bool, 7526 \\}; 7527 \\export fn entry() void { 7528 \\ var a = Payload {.A = 1234}; 7529 \\} 7530 , &[_][]const u8{ 7531 "tmp.zig:10:5: error: enum field not found: 'D'", 7532 "tmp.zig:1:16: note: enum declared here", 7533 }); 7534 7535 cases.add("field type supplied in an enum", 7536 \\const Letter = enum { 7537 \\ A: void, 7538 \\ B, 7539 \\ C, 7540 \\}; 7541 \\export fn entry() void { 7542 \\ var b = Letter.B; 7543 \\} 7544 , &[_][]const u8{ 7545 "tmp.zig:2:8: error: structs and unions, not enums, support field types", 7546 "tmp.zig:1:16: note: consider 'union(enum)' here", 7547 }); 7548 7549 cases.add("struct field missing type", 7550 \\const Letter = struct { 7551 \\ A, 7552 \\}; 7553 \\export fn entry() void { 7554 \\ var a = Letter { .A = {} }; 7555 \\} 7556 , &[_][]const u8{ 7557 "tmp.zig:2:5: error: struct field missing type", 7558 }); 7559 7560 cases.add("extern union field missing type", 7561 \\const Letter = extern union { 7562 \\ A, 7563 \\}; 7564 \\export fn entry() void { 7565 \\ var a = Letter { .A = {} }; 7566 \\} 7567 , &[_][]const u8{ 7568 "tmp.zig:2:5: error: union field missing type", 7569 }); 7570 7571 cases.add("extern union given enum tag type", 7572 \\const Letter = enum { 7573 \\ A, 7574 \\ B, 7575 \\ C, 7576 \\}; 7577 \\const Payload = extern union(Letter) { 7578 \\ A: i32, 7579 \\ B: f64, 7580 \\ C: bool, 7581 \\}; 7582 \\export fn entry() void { 7583 \\ var a = Payload { .A = 1234 }; 7584 \\} 7585 , &[_][]const u8{ 7586 "tmp.zig:6:30: error: extern union does not support enum tag type", 7587 }); 7588 7589 cases.add("packed union given enum tag type", 7590 \\const Letter = enum { 7591 \\ A, 7592 \\ B, 7593 \\ C, 7594 \\}; 7595 \\const Payload = packed union(Letter) { 7596 \\ A: i32, 7597 \\ B: f64, 7598 \\ C: bool, 7599 \\}; 7600 \\export fn entry() void { 7601 \\ var a = Payload { .A = 1234 }; 7602 \\} 7603 , &[_][]const u8{ 7604 "tmp.zig:6:30: error: packed union does not support enum tag type", 7605 }); 7606 7607 cases.add("packed union with automatic layout field", 7608 \\const Foo = struct { 7609 \\ a: u32, 7610 \\ b: f32, 7611 \\}; 7612 \\const Payload = packed union { 7613 \\ A: Foo, 7614 \\ B: bool, 7615 \\}; 7616 \\export fn entry() void { 7617 \\ var a = Payload { .B = true }; 7618 \\} 7619 , &[_][]const u8{ 7620 "tmp.zig:6:5: error: non-packed, non-extern struct 'Foo' not allowed in packed union; no guaranteed in-memory representation", 7621 }); 7622 7623 cases.add("switch on union with no attached enum", 7624 \\const Payload = union { 7625 \\ A: i32, 7626 \\ B: f64, 7627 \\ C: bool, 7628 \\}; 7629 \\export fn entry() void { 7630 \\ const a = Payload { .A = 1234 }; 7631 \\ foo(a); 7632 \\} 7633 \\fn foo(a: *const Payload) void { 7634 \\ switch (a.*) { 7635 \\ Payload.A => {}, 7636 \\ else => unreachable, 7637 \\ } 7638 \\} 7639 , &[_][]const u8{ 7640 "tmp.zig:11:14: error: switch on union which has no attached enum", 7641 "tmp.zig:1:17: note: consider 'union(enum)' here", 7642 }); 7643 7644 cases.add("enum in field count range but not matching tag", 7645 \\const Foo = enum(u32) { 7646 \\ A = 10, 7647 \\ B = 11, 7648 \\}; 7649 \\export fn entry() void { 7650 \\ var x = @intToEnum(Foo, 0); 7651 \\} 7652 , &[_][]const u8{ 7653 "tmp.zig:6:13: error: enum 'Foo' has no tag matching integer value 0", 7654 "tmp.zig:1:13: note: 'Foo' declared here", 7655 }); 7656 7657 cases.add("comptime cast enum to union but field has payload", 7658 \\const Letter = enum { A, B, C }; 7659 \\const Value = union(Letter) { 7660 \\ A: i32, 7661 \\ B, 7662 \\ C, 7663 \\}; 7664 \\export fn entry() void { 7665 \\ var x: Value = Letter.A; 7666 \\} 7667 , &[_][]const u8{ 7668 "tmp.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'", 7669 "tmp.zig:3:5: note: field 'A' declared here", 7670 }); 7671 7672 cases.add("runtime cast to union which has non-void fields", 7673 \\const Letter = enum { A, B, C }; 7674 \\const Value = union(Letter) { 7675 \\ A: i32, 7676 \\ B, 7677 \\ C, 7678 \\}; 7679 \\export fn entry() void { 7680 \\ foo(Letter.A); 7681 \\} 7682 \\fn foo(l: Letter) void { 7683 \\ var x: Value = l; 7684 \\} 7685 , &[_][]const u8{ 7686 "tmp.zig:11:20: error: runtime cast to union 'Value' which has non-void fields", 7687 "tmp.zig:3:5: note: field 'A' has type 'i32'", 7688 }); 7689 7690 cases.add("taking byte offset of void field in struct", 7691 \\const Empty = struct { 7692 \\ val: void, 7693 \\}; 7694 \\export fn foo() void { 7695 \\ const fieldOffset = @byteOffsetOf(Empty, "val",); 7696 \\} 7697 , &[_][]const u8{ 7698 "tmp.zig:5:46: error: zero-bit field 'val' in struct 'Empty' has no offset", 7699 }); 7700 7701 cases.add("taking bit offset of void field in struct", 7702 \\const Empty = struct { 7703 \\ val: void, 7704 \\}; 7705 \\export fn foo() void { 7706 \\ const fieldOffset = @bitOffsetOf(Empty, "val",); 7707 \\} 7708 , &[_][]const u8{ 7709 "tmp.zig:5:45: error: zero-bit field 'val' in struct 'Empty' has no offset", 7710 }); 7711 7712 cases.add("invalid union field access in comptime", 7713 \\const Foo = union { 7714 \\ Bar: u8, 7715 \\ Baz: void, 7716 \\}; 7717 \\comptime { 7718 \\ var foo = Foo {.Baz = {}}; 7719 \\ const bar_val = foo.Bar; 7720 \\} 7721 , &[_][]const u8{ 7722 "tmp.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set", 7723 }); 7724 7725 cases.add("unsupported modifier at start of asm output constraint", 7726 \\export fn foo() void { 7727 \\ var bar: u32 = 3; 7728 \\ asm volatile ("" : [baz]"+r"(bar) : : ""); 7729 \\} 7730 , &[_][]const u8{ 7731 "tmp.zig:3:5: error: invalid modifier starting output constraint for 'baz': '+', only '=' is supported. Compiler TODO: see https://github.com/ziglang/zig/issues/215", 7732 }); 7733 7734 cases.add("comptime_int in asm input", 7735 \\export fn foo() void { 7736 \\ asm volatile ("" : : [bar]"r"(3) : ""); 7737 \\} 7738 , &[_][]const u8{ 7739 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_int", 7740 }); 7741 7742 cases.add("comptime_float in asm input", 7743 \\export fn foo() void { 7744 \\ asm volatile ("" : : [bar]"r"(3.17) : ""); 7745 \\} 7746 , &[_][]const u8{ 7747 "tmp.zig:2:35: error: expected sized integer or sized float, found comptime_float", 7748 }); 7749 7750 cases.add("runtime assignment to comptime struct type", 7751 \\const Foo = struct { 7752 \\ Bar: u8, 7753 \\ Baz: type, 7754 \\}; 7755 \\export fn f() void { 7756 \\ var x: u8 = 0; 7757 \\ const foo = Foo { .Bar = x, .Baz = u8 }; 7758 \\} 7759 , &[_][]const u8{ 7760 "tmp.zig:7:23: error: unable to evaluate constant expression", 7761 }); 7762 7763 cases.add("runtime assignment to comptime union type", 7764 \\const Foo = union { 7765 \\ Bar: u8, 7766 \\ Baz: type, 7767 \\}; 7768 \\export fn f() void { 7769 \\ var x: u8 = 0; 7770 \\ const foo = Foo { .Bar = x }; 7771 \\} 7772 , &[_][]const u8{ 7773 "tmp.zig:7:23: error: unable to evaluate constant expression", 7774 }); 7775 7776 cases.addTest("@shuffle with selected index past first vector length", 7777 \\export fn entry() void { 7778 \\ const v: @import("std").meta.Vector(4, u32) = [4]u32{ 10, 11, 12, 13 }; 7779 \\ const x: @import("std").meta.Vector(4, u32) = [4]u32{ 14, 15, 16, 17 }; 7780 \\ var z = @shuffle(u32, v, x, [8]i32{ 0, 1, 2, 3, 7, 6, 5, 4 }); 7781 \\} 7782 , &[_][]const u8{ 7783 "tmp.zig:4:39: error: mask index '4' has out-of-bounds selection", 7784 "tmp.zig:4:27: note: selected index '7' out of bounds of @Vector(4, u32)", 7785 "tmp.zig:4:30: note: selections from the second vector are specified with negative numbers", 7786 }); 7787 7788 cases.addTest("nested vectors", 7789 \\export fn entry() void { 7790 \\ const V1 = @import("std").meta.Vector(4, u8); 7791 \\ const V2 = @Type(@import("builtin").TypeInfo{ .Vector = .{ .len = 4, .child = V1 } }); 7792 \\ var v: V2 = undefined; 7793 \\} 7794 , &[_][]const u8{ 7795 "tmp.zig:3:49: error: vector element type must be integer, float, bool, or pointer; '@Vector(4, u8)' is invalid", 7796 "tmp.zig:3:16: note: referenced here", 7797 }); 7798 7799 cases.addTest("bad @splat type", 7800 \\export fn entry() void { 7801 \\ const c = 4; 7802 \\ var v = @splat(4, c); 7803 \\} 7804 , &[_][]const u8{ 7805 "tmp.zig:3:23: error: vector element type must be integer, float, bool, or pointer; 'comptime_int' is invalid", 7806 }); 7807 7808 cases.add("compileLog of tagged enum doesn't crash the compiler", 7809 \\const Bar = union(enum(u32)) { 7810 \\ X: i32 = 1 7811 \\}; 7812 \\ 7813 \\fn testCompileLog(x: Bar) void { 7814 \\ @compileLog(x); 7815 \\} 7816 \\ 7817 \\pub fn main () void { 7818 \\ comptime testCompileLog(Bar{.X = 123}); 7819 \\} 7820 , &[_][]const u8{ 7821 "tmp.zig:6:5: error: found compile log statement", 7822 }); 7823 7824 cases.add("attempted implicit cast from *const T to *[1]T", 7825 \\export fn entry(byte: u8) void { 7826 \\ const w: i32 = 1234; 7827 \\ var x: *const i32 = &w; 7828 \\ var y: *[1]i32 = x; 7829 \\ y[0] += 1; 7830 \\} 7831 , &[_][]const u8{ 7832 "tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'", 7833 "tmp.zig:4:22: note: cast discards const qualifier", 7834 }); 7835 7836 cases.add("attempted implicit cast from *const T to []T", 7837 \\export fn entry() void { 7838 \\ const u: u32 = 42; 7839 \\ const x: []u32 = &u; 7840 \\} 7841 , &[_][]const u8{ 7842 "tmp.zig:3:23: error: expected type '[]u32', found '*const u32'", 7843 }); 7844 7845 cases.add("for loop body expression ignored", 7846 \\fn returns() usize { 7847 \\ return 2; 7848 \\} 7849 \\export fn f1() void { 7850 \\ for ("hello") |_| returns(); 7851 \\} 7852 \\export fn f2() void { 7853 \\ var x: anyerror!i32 = error.Bad; 7854 \\ for ("hello") |_| returns() else unreachable; 7855 \\} 7856 , &[_][]const u8{ 7857 "tmp.zig:5:30: error: expression value is ignored", 7858 "tmp.zig:9:30: error: expression value is ignored", 7859 }); 7860 7861 cases.add("aligned variable of zero-bit type", 7862 \\export fn f() void { 7863 \\ var s: struct {} align(4) = undefined; 7864 \\} 7865 , &[_][]const u8{ 7866 "tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned", 7867 }); 7868 7869 cases.add("function returning opaque type", 7870 \\const FooType = opaque {}; 7871 \\export fn bar() !FooType { 7872 \\ return error.InvalidValue; 7873 \\} 7874 \\export fn bav() !@TypeOf(null) { 7875 \\ return error.InvalidValue; 7876 \\} 7877 \\export fn baz() !@TypeOf(undefined) { 7878 \\ return error.InvalidValue; 7879 \\} 7880 , &[_][]const u8{ 7881 "tmp.zig:2:18: error: Opaque return type 'FooType' not allowed", 7882 "tmp.zig:1:1: note: type declared here", 7883 "tmp.zig:5:18: error: Null return type '(null)' not allowed", 7884 "tmp.zig:8:18: error: Undefined return type '(undefined)' not allowed", 7885 }); 7886 7887 cases.add("generic function returning opaque type", 7888 \\const FooType = opaque {}; 7889 \\fn generic(comptime T: type) !T { 7890 \\ return undefined; 7891 \\} 7892 \\export fn bar() void { 7893 \\ _ = generic(FooType); 7894 \\} 7895 \\export fn bav() void { 7896 \\ _ = generic(@TypeOf(null)); 7897 \\} 7898 \\export fn baz() void { 7899 \\ _ = generic(@TypeOf(undefined)); 7900 \\} 7901 , &[_][]const u8{ 7902 "tmp.zig:6:16: error: call to generic function with Opaque return type 'FooType' not allowed", 7903 "tmp.zig:2:1: note: function declared here", 7904 "tmp.zig:1:1: note: type declared here", 7905 "tmp.zig:9:16: error: call to generic function with Null return type '(null)' not allowed", 7906 "tmp.zig:2:1: note: function declared here", 7907 "tmp.zig:12:16: error: call to generic function with Undefined return type '(undefined)' not allowed", 7908 "tmp.zig:2:1: note: function declared here", 7909 }); 7910 7911 cases.add("function parameter is opaque", 7912 \\const FooType = opaque {}; 7913 \\export fn entry1() void { 7914 \\ const someFuncPtr: fn (FooType) void = undefined; 7915 \\} 7916 \\ 7917 \\export fn entry2() void { 7918 \\ const someFuncPtr: fn (@TypeOf(null)) void = undefined; 7919 \\} 7920 \\ 7921 \\fn foo(p: FooType) void {} 7922 \\export fn entry3() void { 7923 \\ _ = foo; 7924 \\} 7925 \\ 7926 \\fn bar(p: @TypeOf(null)) void {} 7927 \\export fn entry4() void { 7928 \\ _ = bar; 7929 \\} 7930 , &[_][]const u8{ 7931 "tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed", 7932 "tmp.zig:7:28: error: parameter of type '(null)' not allowed", 7933 "tmp.zig:10:11: error: parameter of opaque type 'FooType' not allowed", 7934 "tmp.zig:15:11: error: parameter of type '(null)' not allowed", 7935 }); 7936 7937 cases.add( // fixed bug #2032 7938 "compile diagnostic string for top level decl type", 7939 \\export fn entry() void { 7940 \\ var foo: u32 = @This(){}; 7941 \\} 7942 , &[_][]const u8{ 7943 "tmp.zig:2:27: error: type 'u32' does not support array initialization", 7944 }); 7945 7946 cases.add("issue #2687: coerce from undefined array pointer to slice", 7947 \\export fn foo1() void { 7948 \\ const a: *[1]u8 = undefined; 7949 \\ var b: []u8 = a; 7950 \\} 7951 \\export fn foo2() void { 7952 \\ comptime { 7953 \\ var a: *[1]u8 = undefined; 7954 \\ var b: []u8 = a; 7955 \\ } 7956 \\} 7957 \\export fn foo3() void { 7958 \\ comptime { 7959 \\ const a: *[1]u8 = undefined; 7960 \\ var b: []u8 = a; 7961 \\ } 7962 \\} 7963 , &[_][]const u8{ 7964 "tmp.zig:3:19: error: use of undefined value here causes undefined behavior", 7965 "tmp.zig:8:23: error: use of undefined value here causes undefined behavior", 7966 "tmp.zig:14:23: error: use of undefined value here causes undefined behavior", 7967 }); 7968 7969 cases.add("issue #3818: bitcast from parray/slice to u16", 7970 \\export fn foo1() void { 7971 \\ var bytes = [_]u8{1, 2}; 7972 \\ const word: u16 = @bitCast(u16, bytes[0..]); 7973 \\} 7974 \\export fn foo2() void { 7975 \\ var bytes: []const u8 = &[_]u8{1, 2}; 7976 \\ const word: u16 = @bitCast(u16, bytes); 7977 \\} 7978 , &[_][]const u8{ 7979 "tmp.zig:3:42: error: unable to @bitCast from pointer type '*[2]u8'", 7980 "tmp.zig:7:32: error: destination type 'u16' has size 2 but source type '[]const u8' has size 16", 7981 "tmp.zig:7:37: note: referenced here", 7982 }); 7983 7984 cases.add("comptime slice-sentinel is out of bounds (unterminated)", 7985 \\export fn foo_array() void { 7986 \\ comptime { 7987 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 7988 \\ const slice = target[0..14 :0]; 7989 \\ } 7990 \\} 7991 \\export fn foo_ptr_array() void { 7992 \\ comptime { 7993 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 7994 \\ var target = &buf; 7995 \\ const slice = target[0..14 :0]; 7996 \\ } 7997 \\} 7998 \\export fn foo_vector_ConstPtrSpecialBaseArray() void { 7999 \\ comptime { 8000 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8001 \\ var target: [*]u8 = &buf; 8002 \\ const slice = target[0..14 :0]; 8003 \\ } 8004 \\} 8005 \\export fn foo_vector_ConstPtrSpecialRef() void { 8006 \\ comptime { 8007 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8008 \\ var target: [*]u8 = @ptrCast([*]u8, &buf); 8009 \\ const slice = target[0..14 :0]; 8010 \\ } 8011 \\} 8012 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void { 8013 \\ comptime { 8014 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8015 \\ var target: [*c]u8 = &buf; 8016 \\ const slice = target[0..14 :0]; 8017 \\ } 8018 \\} 8019 \\export fn foo_cvector_ConstPtrSpecialRef() void { 8020 \\ comptime { 8021 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8022 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf); 8023 \\ const slice = target[0..14 :0]; 8024 \\ } 8025 \\} 8026 \\export fn foo_slice() void { 8027 \\ comptime { 8028 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8029 \\ var target: []u8 = &buf; 8030 \\ const slice = target[0..14 :0]; 8031 \\ } 8032 \\} 8033 , &[_][]const u8{ 8034 ":4:29: error: slice-sentinel is out of bounds", 8035 ":11:29: error: slice-sentinel is out of bounds", 8036 ":18:29: error: slice-sentinel is out of bounds", 8037 ":25:29: error: slice-sentinel is out of bounds", 8038 ":32:29: error: slice-sentinel is out of bounds", 8039 ":39:29: error: slice-sentinel is out of bounds", 8040 ":46:29: error: slice-sentinel is out of bounds", 8041 }); 8042 8043 cases.add("comptime slice-sentinel is out of bounds (terminated)", 8044 \\export fn foo_array() void { 8045 \\ comptime { 8046 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8047 \\ const slice = target[0..15 :1]; 8048 \\ } 8049 \\} 8050 \\export fn foo_ptr_array() void { 8051 \\ comptime { 8052 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8053 \\ var target = &buf; 8054 \\ const slice = target[0..15 :0]; 8055 \\ } 8056 \\} 8057 \\export fn foo_vector_ConstPtrSpecialBaseArray() void { 8058 \\ comptime { 8059 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8060 \\ var target: [*]u8 = &buf; 8061 \\ const slice = target[0..15 :0]; 8062 \\ } 8063 \\} 8064 \\export fn foo_vector_ConstPtrSpecialRef() void { 8065 \\ comptime { 8066 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8067 \\ var target: [*]u8 = @ptrCast([*]u8, &buf); 8068 \\ const slice = target[0..15 :0]; 8069 \\ } 8070 \\} 8071 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void { 8072 \\ comptime { 8073 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8074 \\ var target: [*c]u8 = &buf; 8075 \\ const slice = target[0..15 :0]; 8076 \\ } 8077 \\} 8078 \\export fn foo_cvector_ConstPtrSpecialRef() void { 8079 \\ comptime { 8080 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8081 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf); 8082 \\ const slice = target[0..15 :0]; 8083 \\ } 8084 \\} 8085 \\export fn foo_slice() void { 8086 \\ comptime { 8087 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8088 \\ var target: []u8 = &buf; 8089 \\ const slice = target[0..15 :0]; 8090 \\ } 8091 \\} 8092 , &[_][]const u8{ 8093 ":4:29: error: out of bounds slice", 8094 ":11:29: error: out of bounds slice", 8095 ":18:29: error: out of bounds slice", 8096 ":25:29: error: out of bounds slice", 8097 ":32:29: error: out of bounds slice", 8098 ":39:29: error: out of bounds slice", 8099 ":46:29: error: out of bounds slice", 8100 }); 8101 8102 cases.add("comptime slice-sentinel does not match memory at target index (unterminated)", 8103 \\export fn foo_array() void { 8104 \\ comptime { 8105 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8106 \\ const slice = target[0..3 :0]; 8107 \\ } 8108 \\} 8109 \\export fn foo_ptr_array() void { 8110 \\ comptime { 8111 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8112 \\ var target = &buf; 8113 \\ const slice = target[0..3 :0]; 8114 \\ } 8115 \\} 8116 \\export fn foo_vector_ConstPtrSpecialBaseArray() void { 8117 \\ comptime { 8118 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8119 \\ var target: [*]u8 = &buf; 8120 \\ const slice = target[0..3 :0]; 8121 \\ } 8122 \\} 8123 \\export fn foo_vector_ConstPtrSpecialRef() void { 8124 \\ comptime { 8125 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8126 \\ var target: [*]u8 = @ptrCast([*]u8, &buf); 8127 \\ const slice = target[0..3 :0]; 8128 \\ } 8129 \\} 8130 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void { 8131 \\ comptime { 8132 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8133 \\ var target: [*c]u8 = &buf; 8134 \\ const slice = target[0..3 :0]; 8135 \\ } 8136 \\} 8137 \\export fn foo_cvector_ConstPtrSpecialRef() void { 8138 \\ comptime { 8139 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8140 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf); 8141 \\ const slice = target[0..3 :0]; 8142 \\ } 8143 \\} 8144 \\export fn foo_slice() void { 8145 \\ comptime { 8146 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8147 \\ var target: []u8 = &buf; 8148 \\ const slice = target[0..3 :0]; 8149 \\ } 8150 \\} 8151 , &[_][]const u8{ 8152 ":4:29: error: slice-sentinel does not match memory at target index", 8153 ":11:29: error: slice-sentinel does not match memory at target index", 8154 ":18:29: error: slice-sentinel does not match memory at target index", 8155 ":25:29: error: slice-sentinel does not match memory at target index", 8156 ":32:29: error: slice-sentinel does not match memory at target index", 8157 ":39:29: error: slice-sentinel does not match memory at target index", 8158 ":46:29: error: slice-sentinel does not match memory at target index", 8159 }); 8160 8161 cases.add("comptime slice-sentinel does not match memory at target index (terminated)", 8162 \\export fn foo_array() void { 8163 \\ comptime { 8164 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8165 \\ const slice = target[0..3 :0]; 8166 \\ } 8167 \\} 8168 \\export fn foo_ptr_array() void { 8169 \\ comptime { 8170 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8171 \\ var target = &buf; 8172 \\ const slice = target[0..3 :0]; 8173 \\ } 8174 \\} 8175 \\export fn foo_vector_ConstPtrSpecialBaseArray() void { 8176 \\ comptime { 8177 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8178 \\ var target: [*]u8 = &buf; 8179 \\ const slice = target[0..3 :0]; 8180 \\ } 8181 \\} 8182 \\export fn foo_vector_ConstPtrSpecialRef() void { 8183 \\ comptime { 8184 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8185 \\ var target: [*]u8 = @ptrCast([*]u8, &buf); 8186 \\ const slice = target[0..3 :0]; 8187 \\ } 8188 \\} 8189 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void { 8190 \\ comptime { 8191 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8192 \\ var target: [*c]u8 = &buf; 8193 \\ const slice = target[0..3 :0]; 8194 \\ } 8195 \\} 8196 \\export fn foo_cvector_ConstPtrSpecialRef() void { 8197 \\ comptime { 8198 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8199 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf); 8200 \\ const slice = target[0..3 :0]; 8201 \\ } 8202 \\} 8203 \\export fn foo_slice() void { 8204 \\ comptime { 8205 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8206 \\ var target: []u8 = &buf; 8207 \\ const slice = target[0..3 :0]; 8208 \\ } 8209 \\} 8210 , &[_][]const u8{ 8211 ":4:29: error: slice-sentinel does not match memory at target index", 8212 ":11:29: error: slice-sentinel does not match memory at target index", 8213 ":18:29: error: slice-sentinel does not match memory at target index", 8214 ":25:29: error: slice-sentinel does not match memory at target index", 8215 ":32:29: error: slice-sentinel does not match memory at target index", 8216 ":39:29: error: slice-sentinel does not match memory at target index", 8217 ":46:29: error: slice-sentinel does not match memory at target index", 8218 }); 8219 8220 cases.add("comptime slice-sentinel does not match target-sentinel", 8221 \\export fn foo_array() void { 8222 \\ comptime { 8223 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8224 \\ const slice = target[0..14 :255]; 8225 \\ } 8226 \\} 8227 \\export fn foo_ptr_array() void { 8228 \\ comptime { 8229 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8230 \\ var target = &buf; 8231 \\ const slice = target[0..14 :255]; 8232 \\ } 8233 \\} 8234 \\export fn foo_vector_ConstPtrSpecialBaseArray() void { 8235 \\ comptime { 8236 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8237 \\ var target: [*]u8 = &buf; 8238 \\ const slice = target[0..14 :255]; 8239 \\ } 8240 \\} 8241 \\export fn foo_vector_ConstPtrSpecialRef() void { 8242 \\ comptime { 8243 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8244 \\ var target: [*]u8 = @ptrCast([*]u8, &buf); 8245 \\ const slice = target[0..14 :255]; 8246 \\ } 8247 \\} 8248 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void { 8249 \\ comptime { 8250 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8251 \\ var target: [*c]u8 = &buf; 8252 \\ const slice = target[0..14 :255]; 8253 \\ } 8254 \\} 8255 \\export fn foo_cvector_ConstPtrSpecialRef() void { 8256 \\ comptime { 8257 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8258 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf); 8259 \\ const slice = target[0..14 :255]; 8260 \\ } 8261 \\} 8262 \\export fn foo_slice() void { 8263 \\ comptime { 8264 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; 8265 \\ var target: []u8 = &buf; 8266 \\ const slice = target[0..14 :255]; 8267 \\ } 8268 \\} 8269 , &[_][]const u8{ 8270 ":4:29: error: slice-sentinel does not match target-sentinel", 8271 ":11:29: error: slice-sentinel does not match target-sentinel", 8272 ":18:29: error: slice-sentinel does not match target-sentinel", 8273 ":25:29: error: slice-sentinel does not match target-sentinel", 8274 ":32:29: error: slice-sentinel does not match target-sentinel", 8275 ":39:29: error: slice-sentinel does not match target-sentinel", 8276 ":46:29: error: slice-sentinel does not match target-sentinel", 8277 }); 8278 8279 cases.add("issue #4207: coerce from non-terminated-slice to terminated-pointer", 8280 \\export fn foo() [*:0]const u8 { 8281 \\ var buffer: [64]u8 = undefined; 8282 \\ return buffer[0..]; 8283 \\} 8284 , &[_][]const u8{ 8285 ":3:18: error: expected type '[*:0]const u8', found '*[64]u8'", 8286 ":3:18: note: destination pointer requires a terminating '0' sentinel", 8287 }); 8288 8289 cases.add("issue #5221: invalid struct init type referenced by @typeInfo and passed into function", 8290 \\fn ignore(comptime param: anytype) void {} 8291 \\ 8292 \\export fn foo() void { 8293 \\ const MyStruct = struct { 8294 \\ wrong_type: []u8 = "foo", 8295 \\ }; 8296 \\ 8297 \\ comptime ignore(@typeInfo(MyStruct).Struct.fields[0]); 8298 \\} 8299 , &[_][]const u8{ 8300 ":5:28: error: expected type '[]u8', found '*const [3:0]u8'", 8301 }); 8302 8303 cases.add("integer underflow error", 8304 \\export fn entry() void { 8305 \\ _ = @intToPtr(*c_void, ~@as(usize, @import("std").math.maxInt(usize)) - 1); 8306 \\} 8307 , &[_][]const u8{ 8308 ":2:75: error: operation caused overflow", 8309 }); 8310 8311 cases.addCase(x: { 8312 var tc = cases.create("align(N) expr function pointers is a compile error", 8313 \\export fn foo() align(1) void { 8314 \\ return; 8315 \\} 8316 , &[_][]const u8{ 8317 "tmp.zig:1:23: error: align(N) expr is not allowed on function prototypes in wasm32/wasm64", 8318 }); 8319 tc.target = std.zig.CrossTarget{ 8320 .cpu_arch = .wasm32, 8321 .os_tag = .freestanding, 8322 .abi = .none, 8323 }; 8324 break :x tc; 8325 }); 8326 8327 cases.add("compare optional to non-optional with invalid types", 8328 \\export fn inconsistentChildType() void { 8329 \\ var x: ?i32 = undefined; 8330 \\ const y: comptime_int = 10; 8331 \\ _ = (x == y); 8332 \\} 8333 \\ 8334 \\export fn optionalToOptional() void { 8335 \\ var x: ?i32 = undefined; 8336 \\ var y: ?i32 = undefined; 8337 \\ _ = (x == y); 8338 \\} 8339 \\ 8340 \\export fn optionalVector() void { 8341 \\ var x: ?@Vector(10, i32) = undefined; 8342 \\ var y: @Vector(10, i32) = undefined; 8343 \\ _ = (x == y); 8344 \\} 8345 \\ 8346 \\export fn invalidChildType() void { 8347 \\ var x: ?[3]i32 = undefined; 8348 \\ var y: [3]i32 = undefined; 8349 \\ _ = (x == y); 8350 \\} 8351 , &[_][]const u8{ 8352 ":4:12: error: cannot compare types '?i32' and 'comptime_int'", 8353 ":4:12: note: optional child type 'i32' must be the same as non-optional type 'comptime_int'", 8354 ":10:12: error: cannot compare types '?i32' and '?i32'", 8355 ":10:12: note: optional to optional comparison is only supported for optional pointer types", 8356 ":16:12: error: TODO add comparison of optional vector", 8357 ":22:12: error: cannot compare types '?[3]i32' and '[3]i32'", 8358 ":22:12: note: operator not supported for type '[3]i32'", 8359 }); 8360 8361 cases.add("slice cannot have its bytes reinterpreted", 8362 \\export fn foo() void { 8363 \\ const bytes = [1]u8{ 0xfa } ** 16; 8364 \\ var value = @ptrCast(*const []const u8, &bytes).*; 8365 \\} 8366 , &[_][]const u8{ 8367 ":3:52: error: slice '[]const u8' cannot have its bytes reinterpreted", 8368 }); 8369 8370 cases.add("wasmMemorySize is a compile error in non-Wasm targets", 8371 \\export fn foo() void { 8372 \\ _ = @wasmMemorySize(0); 8373 \\ return; 8374 \\} 8375 , &[_][]const u8{ 8376 "tmp.zig:2:9: error: @wasmMemorySize is a wasm32 feature only", 8377 }); 8378 8379 cases.add("wasmMemoryGrow is a compile error in non-Wasm targets", 8380 \\export fn foo() void { 8381 \\ _ = @wasmMemoryGrow(0, 1); 8382 \\ return; 8383 \\} 8384 , &[_][]const u8{ 8385 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only", 8386 }); 8387 cases.add("Issue #5586: Make unary minus for unsigned types a compile error", 8388 \\export fn f1(x: u32) u32 { 8389 \\ const y = -%x; 8390 \\ return -y; 8391 \\} 8392 \\const V = @import("std").meta.Vector; 8393 \\export fn f2(x: V(4, u32)) V(4, u32) { 8394 \\ const y = -%x; 8395 \\ return -y; 8396 \\} 8397 , &[_][]const u8{ 8398 "tmp.zig:3:12: error: negation of type 'u32'", 8399 "tmp.zig:8:12: error: negation of type 'u32'", 8400 }); 8401 8402 cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.", 8403 \\export fn foo() void { 8404 \\ var u: ?*c_void = null; 8405 \\ var v: *c_void = undefined; 8406 \\ v = u; 8407 \\} 8408 , &[_][]const u8{ 8409 "tmp.zig:4:9: error: expected type '*c_void', found '?*c_void'", 8410 }); 8411 8412 cases.add("Issue #6823: don't allow .* to be followed by **", 8413 \\fn foo() void { 8414 \\ var sequence = "repeat".*** 10; 8415 \\} 8416 , &[_][]const u8{ 8417 "tmp.zig:2:30: error: `.*` can't be followed by `*`. Are you missing a space?", 8418 }); 8419 }