| author | |
| committer | |
| log | 9b665a59f27b4de0ae648438617b0a1a08a620c1 |
| tree | bc0cace44659812c5675c985bba382cb8180b80f |
| parent | 94780f7cd19701965d9417e8d90dc6ea4d9285be |
| parent | e0b6140009eb3e2e53b8c90fe3973d80991bd9b8 |
| signature |
add tests for fixed stage1 bugs20 files changed, 388 insertions(+), 9 deletions(-)
doc/langref.html.in+3-3| ... | ... | @@ -12075,7 +12075,7 @@ ContainerDeclarations |
| 12075 | 12075 | / doc_comment? KEYWORD_pub? Decl ContainerDeclarations |
| 12076 | 12076 | / |
| 12077 | 12077 | |
| 12078 | TestDecl <- KEYWORD_test STRINGLITERALSINGLE? Block | |
| 12078 | TestDecl <- KEYWORD_test (STRINGLITERALSINGLE / IDENTIFIER)? Block | |
| 12079 | 12079 | |
| 12080 | 12080 | ComptimeDecl <- KEYWORD_comptime Block |
| 12081 | 12081 | |
| ... | ... | @@ -12089,7 +12089,7 @@ FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpa |
| 12089 | 12089 | VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? AddrSpace? LinkSection? (EQUAL Expr)? SEMICOLON |
| 12090 | 12090 | |
| 12091 | 12091 | ContainerField |
| 12092 | <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)? | |
| 12092 | <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? ByteAlign? (EQUAL Expr)? | |
| 12093 | 12093 | / doc_comment? KEYWORD_comptime? (IDENTIFIER COLON)? !KEYWORD_fn TypeExpr ByteAlign? (EQUAL Expr)? |
| 12094 | 12094 | |
| 12095 | 12095 | # *** Block Level *** |
| ... | ... | @@ -12360,7 +12360,7 @@ PrefixTypeOp |
| 12360 | 12360 | <- QUESTIONMARK |
| 12361 | 12361 | / KEYWORD_anyframe MINUSRARROW |
| 12362 | 12362 | / SliceTypeStart (ByteAlign / AddrSpace / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* |
| 12363 | / PtrTypeStart (AddrSpace / KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 12363 | / PtrTypeStart (AddrSpace / KEYWORD_align LPAREN Expr (COLON Expr COLON Expr)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 12364 | 12364 | / ArrayTypeStart |
| 12365 | 12365 | |
| 12366 | 12366 | SuffixOp |
lib/std/array_list.zig+17| ... | ... | @@ -1604,3 +1604,20 @@ test "std.ArrayList(u0)" { |
| 1604 | 1604 | } |
| 1605 | 1605 | try testing.expectEqual(count, 3); |
| 1606 | 1606 | } |
| 1607 | ||
| 1608 | test "std.ArrayList(?u32).popOrNull()" { | |
| 1609 | const a = testing.allocator; | |
| 1610 | ||
| 1611 | var list = ArrayList(?u32).init(a); | |
| 1612 | defer list.deinit(); | |
| 1613 | ||
| 1614 | try list.append(null); | |
| 1615 | try list.append(1); | |
| 1616 | try list.append(2); | |
| 1617 | try testing.expectEqual(list.items.len, 3); | |
| 1618 | ||
| 1619 | try testing.expect(list.popOrNull().? == @as(u32, 2)); | |
| 1620 | try testing.expect(list.popOrNull().? == @as(u32, 1)); | |
| 1621 | try testing.expect(list.popOrNull().? == null); | |
| 1622 | try testing.expect(list.popOrNull() == null); | |
| 1623 | } |
lib/std/zig/parse.zig+1-1| ... | ... | @@ -1595,7 +1595,7 @@ const Parser = struct { |
| 1595 | 1595 | /// <- QUESTIONMARK |
| 1596 | 1596 | /// / KEYWORD_anyframe MINUSRARROW |
| 1597 | 1597 | /// / SliceTypeStart (ByteAlign / AddrSpace / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* |
| 1598 | /// / PtrTypeStart (AddrSpace / KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 1598 | /// / PtrTypeStart (AddrSpace / KEYWORD_align LPAREN Expr (COLON Expr COLON Expr)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 1599 | 1599 | /// / ArrayTypeStart |
| 1600 | 1600 | /// SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET |
| 1601 | 1601 | /// PtrTypeStart |
src/AstGen.zig+2-2| ... | ... | @@ -3365,7 +3365,7 @@ fn ptrType( |
| 3365 | 3365 | var trailing_count: u32 = 0; |
| 3366 | 3366 | |
| 3367 | 3367 | if (ptr_info.ast.sentinel != 0) { |
| 3368 | sentinel_ref = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, ptr_info.ast.sentinel); | |
| 3368 | sentinel_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, ptr_info.ast.sentinel); | |
| 3369 | 3369 | trailing_count += 1; |
| 3370 | 3370 | } |
| 3371 | 3371 | if (ptr_info.ast.align_node != 0) { |
| ... | ... | @@ -3468,7 +3468,7 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node. |
| 3468 | 3468 | } |
| 3469 | 3469 | const len = try reachableExpr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node, node); |
| 3470 | 3470 | const elem_type = try typeExpr(gz, scope, extra.elem_type); |
| 3471 | const sentinel = try reachableExpr(gz, scope, .{ .rl = .{ .coerced_ty = elem_type } }, extra.sentinel, node); | |
| 3471 | const sentinel = try reachableExprComptime(gz, scope, .{ .rl = .{ .coerced_ty = elem_type } }, extra.sentinel, node, true); | |
| 3472 | 3472 | |
| 3473 | 3473 | const result = try gz.addPlNode(.array_type_sentinel, node, Zir.Inst.ArrayTypeSentinel{ |
| 3474 | 3474 | .len = len, |
src/type.zig+6-1| ... | ... | @@ -2195,7 +2195,12 @@ pub const Type = extern union { |
| 2195 | 2195 | .Slice => try writer.writeAll("[]"), |
| 2196 | 2196 | } |
| 2197 | 2197 | if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) { |
| 2198 | try writer.print("align({d}", .{info.@"align"}); | |
| 2198 | if (info.@"align" != 0) { | |
| 2199 | try writer.print("align({d}", .{info.@"align"}); | |
| 2200 | } else { | |
| 2201 | const alignment = info.pointee_type.abiAlignment(mod.getTarget()); | |
| 2202 | try writer.print("align({d}", .{alignment}); | |
| 2203 | } | |
| 2199 | 2204 | |
| 2200 | 2205 | if (info.bit_offset != 0 or info.host_size != 0) { |
| 2201 | 2206 | try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size }); |
test/behavior/cast.zig+10| ... | ... | @@ -1518,3 +1518,13 @@ test "bitcast packed struct with u0" { |
| 1518 | 1518 | const i = @bitCast(u2, s); |
| 1519 | 1519 | try expect(i == 2); |
| 1520 | 1520 | } |
| 1521 | ||
| 1522 | test "optional pointer coerced to optional allowzero pointer" { | |
| 1523 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 1524 | ||
| 1525 | var p: ?*u32 = undefined; | |
| 1526 | var q: ?*allowzero u32 = undefined; | |
| 1527 | p = @intToPtr(*u32, 4); | |
| 1528 | q = p; | |
| 1529 | try expect(@ptrToInt(q.?) == 4); | |
| 1530 | } |
test/behavior/eval.zig+74| ... | ... | @@ -1547,3 +1547,77 @@ test "comptime function turns function value to function pointer" { |
| 1547 | 1547 | }; |
| 1548 | 1548 | comptime try expect(S.foo[0] == &S.Nil); |
| 1549 | 1549 | } |
| 1550 | ||
| 1551 | test "container level const and var have unique addresses" { | |
| 1552 | const S = struct { | |
| 1553 | x: i32, | |
| 1554 | y: i32, | |
| 1555 | const c = @This(){ .x = 1, .y = 1 }; | |
| 1556 | var v: @This() = c; | |
| 1557 | }; | |
| 1558 | var p = &S.c; | |
| 1559 | try std.testing.expect(p.x == S.c.x); | |
| 1560 | S.v.x = 2; | |
| 1561 | try std.testing.expect(p.x == S.c.x); | |
| 1562 | } | |
| 1563 | ||
| 1564 | test "break from block results in type" { | |
| 1565 | const S = struct { | |
| 1566 | fn NewType(comptime T: type) type { | |
| 1567 | const Padded = blk: { | |
| 1568 | if (@sizeOf(T) <= @sizeOf(usize)) break :blk void; | |
| 1569 | break :blk T; | |
| 1570 | }; | |
| 1571 | ||
| 1572 | return Padded; | |
| 1573 | } | |
| 1574 | }; | |
| 1575 | const T = S.NewType(usize); | |
| 1576 | try expect(T == void); | |
| 1577 | } | |
| 1578 | ||
| 1579 | test "struct in comptime false branch is not evaluated" { | |
| 1580 | const S = struct { | |
| 1581 | const comptime_const = 2; | |
| 1582 | fn some(comptime V: type) type { | |
| 1583 | return switch (comptime_const) { | |
| 1584 | 3 => struct { a: V.foo }, | |
| 1585 | 2 => V, | |
| 1586 | else => unreachable, | |
| 1587 | }; | |
| 1588 | } | |
| 1589 | }; | |
| 1590 | try expect(S.some(u32) == u32); | |
| 1591 | } | |
| 1592 | ||
| 1593 | test "result of nested switch assigned to variable" { | |
| 1594 | var zds: u32 = 0; | |
| 1595 | zds = switch (zds) { | |
| 1596 | 0 => switch (zds) { | |
| 1597 | 0...0 => 1234, | |
| 1598 | 1...1 => zds, | |
| 1599 | 2 => zds, | |
| 1600 | else => return, | |
| 1601 | }, | |
| 1602 | else => zds, | |
| 1603 | }; | |
| 1604 | try expect(zds == 1234); | |
| 1605 | } | |
| 1606 | ||
| 1607 | test "inline for loop of functions returning error unions" { | |
| 1608 | const T1 = struct { | |
| 1609 | fn v() error{}!usize { | |
| 1610 | return 1; | |
| 1611 | } | |
| 1612 | }; | |
| 1613 | const T2 = struct { | |
| 1614 | fn v() error{Error}!usize { | |
| 1615 | return 2; | |
| 1616 | } | |
| 1617 | }; | |
| 1618 | var a: usize = 0; | |
| 1619 | inline for (.{ T1, T2 }) |T| { | |
| 1620 | a += try T.v(); | |
| 1621 | } | |
| 1622 | try expect(a == 3); | |
| 1623 | } |
test/behavior/for.zig+22| ... | ... | @@ -227,3 +227,25 @@ test "else continue outer for" { |
| 227 | 227 | } else continue; |
| 228 | 228 | } |
| 229 | 229 | } |
| 230 | ||
| 231 | test "for loop with else branch" { | |
| 232 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 233 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 234 | ||
| 235 | { | |
| 236 | var x = [_]u32{ 1, 2 }; | |
| 237 | const q = for (x) |y| { | |
| 238 | if ((y & 1) != 0) continue; | |
| 239 | break y * 2; | |
| 240 | } else @as(u32, 1); | |
| 241 | try expect(q == 4); | |
| 242 | } | |
| 243 | { | |
| 244 | var x = [_]u32{ 1, 2 }; | |
| 245 | const q = for (x) |y| { | |
| 246 | if ((y & 1) != 0) continue; | |
| 247 | break y * 2; | |
| 248 | } else @panic(""); | |
| 249 | try expect(q == 4); | |
| 250 | } | |
| 251 | } |
test/behavior/optional.zig+43| ... | ... | @@ -448,3 +448,46 @@ test "Optional slice size is optimized" { |
| 448 | 448 | a = "hello"; |
| 449 | 449 | try expectEqualStrings(a.?, "hello"); |
| 450 | 450 | } |
| 451 | ||
| 452 | test "peer type resolution in nested if expressions" { | |
| 453 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 454 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 455 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 456 | ||
| 457 | const Thing = struct { n: i32 }; | |
| 458 | var a = false; | |
| 459 | var b = false; | |
| 460 | ||
| 461 | var result1 = if (a) | |
| 462 | Thing{ .n = 1 } | |
| 463 | else | |
| 464 | null; | |
| 465 | try expect(result1 == null); | |
| 466 | try expect(@TypeOf(result1) == ?Thing); | |
| 467 | ||
| 468 | var result2 = if (a) | |
| 469 | Thing{ .n = 0 } | |
| 470 | else if (b) | |
| 471 | Thing{ .n = 1 } | |
| 472 | else | |
| 473 | null; | |
| 474 | try expect(result2 == null); | |
| 475 | try expect(@TypeOf(result2) == ?Thing); | |
| 476 | } | |
| 477 | ||
| 478 | test "cast slice to const slice nested in error union and optional" { | |
| 479 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 480 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 481 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 482 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 483 | ||
| 484 | const S = struct { | |
| 485 | fn inner() !?[]u8 { | |
| 486 | return error.Foo; | |
| 487 | } | |
| 488 | fn outer() !?[]const u8 { | |
| 489 | return inner(); | |
| 490 | } | |
| 491 | }; | |
| 492 | try std.testing.expectError(error.Foo, S.outer()); | |
| 493 | } |
test/behavior/packed-struct.zig+21| ... | ... | @@ -567,3 +567,24 @@ test "packed struct passed to callconv(.C) function" { |
| 567 | 567 | }, 5, 4, 3, 2, 1); |
| 568 | 568 | try expect(result); |
| 569 | 569 | } |
| 570 | ||
| 571 | test "overaligned pointer to packed struct" { | |
| 572 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 573 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 574 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 575 | ||
| 576 | const S = packed struct { a: u32, b: u32 }; | |
| 577 | var foo: S align(4) = .{ .a = 123, .b = 456 }; | |
| 578 | const ptr: *align(4) S = &foo; | |
| 579 | switch (comptime builtin.cpu.arch.endian()) { | |
| 580 | .Little => { | |
| 581 | const ptr_to_b: *u32 = &ptr.b; | |
| 582 | try expect(ptr_to_b.* == 456); | |
| 583 | }, | |
| 584 | .Big => { | |
| 585 | // Byte aligned packed struct field pointers have not been implemented yet. | |
| 586 | const ptr_to_a: *align(4:0:8) u32 = &ptr.a; | |
| 587 | try expect(ptr_to_a.* == 123); | |
| 588 | }, | |
| 589 | } | |
| 590 | } |
test/behavior/ptrcast.zig+12| ... | ... | @@ -270,3 +270,15 @@ test "comptime @ptrCast a subset of an array, then write through it" { |
| 270 | 270 | std.mem.copy(u8, buff[4..], "abcdef"); |
| 271 | 271 | } |
| 272 | 272 | } |
| 273 | ||
| 274 | test "@ptrCast undefined value at comptime" { | |
| 275 | const S = struct { | |
| 276 | fn transmute(comptime T: type, comptime U: type, value: T) U { | |
| 277 | return @ptrCast(*const U, &value).*; | |
| 278 | } | |
| 279 | }; | |
| 280 | comptime { | |
| 281 | var x = S.transmute([]u8, i32, undefined); | |
| 282 | _ = x; | |
| 283 | } | |
| 284 | } |
test/behavior/slice.zig+31| ... | ... | @@ -706,3 +706,34 @@ test "global slice field access" { |
| 706 | 706 | S.slice.len -= 2; |
| 707 | 707 | try expectEqualStrings("trin", S.slice); |
| 708 | 708 | } |
| 709 | ||
| 710 | test "slice of void" { | |
| 711 | var n: usize = 10; | |
| 712 | var arr: [12]void = undefined; | |
| 713 | const slice = @as([]void, &arr)[0..n]; | |
| 714 | try expect(slice.len == n); | |
| 715 | } | |
| 716 | ||
| 717 | test "slice with dereferenced value" { | |
| 718 | var a: usize = 0; | |
| 719 | var idx: *usize = &a; | |
| 720 | _ = blk: { | |
| 721 | var array = [_]u8{}; | |
| 722 | break :blk array[idx.*..]; | |
| 723 | }; | |
| 724 | const res = blk: { | |
| 725 | var array = [_]u8{}; | |
| 726 | break :blk array[idx.*..]; | |
| 727 | }; | |
| 728 | try expect(res.len == 0); | |
| 729 | } | |
| 730 | ||
| 731 | test "empty slice ptr is non null" { | |
| 732 | if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; // TODO | |
| 733 | if (builtin.zig_backend == .stage2_x86_64 and (builtin.os.tag == .macos or builtin.os.tag == .windows)) return error.SkipZigTest; // TODO | |
| 734 | ||
| 735 | const empty_slice: []u8 = &[_]u8{}; | |
| 736 | const p: [*]u8 = empty_slice.ptr + 0; | |
| 737 | const t = @ptrCast([*]i8, p); | |
| 738 | try expect(@ptrToInt(t) == @ptrToInt(empty_slice.ptr)); | |
| 739 | } |
test/behavior/struct.zig+37| ... | ... | @@ -1458,3 +1458,40 @@ test "struct has only one reference" { |
| 1458 | 1458 | try expectEqual(@sizeOf(struct { x: u16 }), S.optionalComptimeIntParam(@sizeOf(struct { x: u16 }))); |
| 1459 | 1459 | try expectEqual(@sizeOf(struct { x: u32 }), S.errorUnionComptimeIntParam(@sizeOf(struct { x: u32 }))); |
| 1460 | 1460 | } |
| 1461 | ||
| 1462 | test "no dependency loop on pointer to optional struct" { | |
| 1463 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 1464 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 1465 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 1466 | ||
| 1467 | const S = struct { | |
| 1468 | const A = struct { b: B }; | |
| 1469 | const B = struct { a: *?A }; | |
| 1470 | }; | |
| 1471 | var a1: ?S.A = null; | |
| 1472 | var a2: ?S.A = .{ .b = .{ .a = &a1 } }; | |
| 1473 | a1 = .{ .b = .{ .a = &a2 } }; | |
| 1474 | ||
| 1475 | try expect(a1.?.b.a == &a2); | |
| 1476 | try expect(a2.?.b.a == &a1); | |
| 1477 | } | |
| 1478 | ||
| 1479 | test "discarded struct initialization works as expected" { | |
| 1480 | const S = struct { a: u32 }; | |
| 1481 | _ = S{ .a = 1 }; | |
| 1482 | } | |
| 1483 | ||
| 1484 | test "function pointer in struct returns the struct" { | |
| 1485 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 1486 | ||
| 1487 | const A = struct { | |
| 1488 | const A = @This(); | |
| 1489 | f: *const fn () A, | |
| 1490 | ||
| 1491 | fn f() A { | |
| 1492 | return .{ .f = f }; | |
| 1493 | } | |
| 1494 | }; | |
| 1495 | var a = A.f(); | |
| 1496 | try expect(a.f == A.f); | |
| 1497 | } |
test/behavior/tuple.zig+26| ... | ... | @@ -2,6 +2,7 @@ const builtin = @import("builtin"); |
| 2 | 2 | const std = @import("std"); |
| 3 | 3 | const testing = std.testing; |
| 4 | 4 | const expect = testing.expect; |
| 5 | const expectEqualStrings = std.testing.expectEqualStrings; | |
| 5 | 6 | |
| 6 | 7 | test "tuple concatenation" { |
| 7 | 8 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -340,3 +341,28 @@ test "tuple type with void field and a runtime field" { |
| 340 | 341 | var t: T = .{ 5, {} }; |
| 341 | 342 | try expect(t[0] == 5); |
| 342 | 343 | } |
| 344 | ||
| 345 | test "branching inside tuple literal" { | |
| 346 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 347 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 348 | ||
| 349 | const S = struct { | |
| 350 | fn foo(a: anytype) !void { | |
| 351 | try expect(a[0] == 1234); | |
| 352 | } | |
| 353 | }; | |
| 354 | var a = false; | |
| 355 | try S.foo(.{if (a) @as(u32, 5678) else @as(u32, 1234)}); | |
| 356 | } | |
| 357 | ||
| 358 | test "tuple initialized with a runtime known value" { | |
| 359 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 360 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 361 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 362 | ||
| 363 | const E = union(enum) { e: []const u8 }; | |
| 364 | const W = union(enum) { w: E }; | |
| 365 | var e = E{ .e = "test" }; | |
| 366 | const w = .{W{ .w = e }}; | |
| 367 | try expectEqualStrings(w[0].w.e, "test"); | |
| 368 | } |
test/behavior/union.zig+31| ... | ... | @@ -1471,3 +1471,34 @@ test "union int tag type is properly managed" { |
| 1471 | 1471 | }; |
| 1472 | 1472 | try expect(@sizeOf(Bar) + 1 == 3); |
| 1473 | 1473 | } |
| 1474 | ||
| 1475 | test "no dependency loop when function pointer in union returns the union" { | |
| 1476 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 1477 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 1478 | ||
| 1479 | const U = union(enum) { | |
| 1480 | const U = @This(); | |
| 1481 | a: u8, | |
| 1482 | b: *const fn (x: U) void, | |
| 1483 | c: *const fn (x: U) U, | |
| 1484 | d: *const fn (x: u8) U, | |
| 1485 | fn foo(x: u8) U { | |
| 1486 | return .{ .a = x }; | |
| 1487 | } | |
| 1488 | }; | |
| 1489 | var b: U = .{ .d = U.foo }; | |
| 1490 | try expect(b.d(2).a == 2); | |
| 1491 | } | |
| 1492 | ||
| 1493 | test "union reassignment can use previous value" { | |
| 1494 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 1495 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 1496 | ||
| 1497 | const U = union { | |
| 1498 | a: u32, | |
| 1499 | b: u32, | |
| 1500 | }; | |
| 1501 | var a = U{ .a = 32 }; | |
| 1502 | a = U{ .b = a.a }; | |
| 1503 | try expect(a.b == 32); | |
| 1504 | } |
test/cases/compile_errors/casting_bit_offset_pointer_to_regular_pointer.zig+1-1| ... | ... | @@ -18,7 +18,7 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); } |
| 18 | 18 | // backend=stage2 |
| 19 | 19 | // target=native |
| 20 | 20 | // |
| 21 | // :8:16: error: expected type '*const u3', found '*align(0:3:1) const u3' | |
| 21 | // :8:16: error: expected type '*const u3', found '*align(1:3:1) const u3' | |
| 22 | 22 | // :8:16: note: pointer host size '1' cannot cast into pointer host size '0' |
| 23 | 23 | // :8:16: note: pointer bit offset '3' cannot cast into pointer bit offset '0' |
| 24 | 24 | // :11:11: note: parameter type declared here |
test/cases/compile_errors/control_flow_uses_comptime_var_at_runtime.zig+25| ... | ... | @@ -6,6 +6,27 @@ export fn foo() void { |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | fn bar() void { } |
| 9 | export fn baz() void { | |
| 10 | comptime var idx: u32 = 0; | |
| 11 | while (idx < 1) { | |
| 12 | const not_null: ?u32 = 1; | |
| 13 | _ = not_null orelse return; | |
| 14 | idx += 1; | |
| 15 | } | |
| 16 | } | |
| 17 | ||
| 18 | export fn qux() void { | |
| 19 | comptime var i = 0; | |
| 20 | while (i < 3) : (i += 1) { | |
| 21 | const T = switch (i) { | |
| 22 | 0 => f32, | |
| 23 | 1 => i8, | |
| 24 | 2 => bool, | |
| 25 | else => unreachable, | |
| 26 | }; | |
| 27 | _ = T; | |
| 28 | } | |
| 29 | } | |
| 9 | 30 | |
| 10 | 31 | // error |
| 11 | 32 | // backend=stage2 |
| ... | ... | @@ -13,3 +34,7 @@ fn bar() void { } |
| 13 | 34 | // |
| 14 | 35 | // :3:24: error: cannot store to comptime variable in non-inline loop |
| 15 | 36 | // :3:5: note: non-inline loop here |
| 37 | // :14:13: error: cannot store to comptime variable in non-inline loop | |
| 38 | // :11:5: note: non-inline loop here | |
| 39 | // :20:24: error: cannot store to comptime variable in non-inline loop | |
| 40 | // :20:5: note: non-inline loop here |
test/cases/compile_errors/incompatible sub-byte fields.zig	+1-1| ... | ... | @@ -24,4 +24,4 @@ export fn entry() void { |
| 24 | 24 | // backend=stage2 |
| 25 | 25 | // target=native |
| 26 | 26 | // |
| 27 | // :14:17: error: incompatible types: '*align(0:0:1) u2' and '*align(2:8:2) u2' | |
| 27 | // :14:17: error: incompatible types: '*align(1:0:1) u2' and '*align(2:8:2) u2' |
test/cases/compile_errors/reference_to_const_data.zig+5| ... | ... | @@ -18,6 +18,10 @@ export fn qux() void { |
| 18 | 18 | var ptr = &S{.x=1,.y=2}; |
| 19 | 19 | ptr.x = 2; |
| 20 | 20 | } |
| 21 | export fn quux() void { | |
| 22 | var x = &@returnAddress(); | |
| 23 | x.* = 6; | |
| 24 | } | |
| 21 | 25 | |
| 22 | 26 | // error |
| 23 | 27 | // backend=stage2 |
| ... | ... | @@ -27,3 +31,4 @@ export fn qux() void { |
| 27 | 31 | // :7:8: error: cannot assign to constant |
| 28 | 32 | // :11:8: error: cannot assign to constant |
| 29 | 33 | // :19:8: error: cannot assign to constant |
| 34 | // :23:6: error: cannot assign to constant |
test/cases/compile_errors/return_incompatible_generic_struct.zig created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | fn A(comptime T: type) type { | |
| 2 | return struct { a: T }; | |
| 3 | } | |
| 4 | fn B(comptime T: type) type { | |
| 5 | return struct { b: T }; | |
| 6 | } | |
| 7 | fn foo() A(u32) { | |
| 8 | return B(u32){ .b = 1 }; | |
| 9 | } | |
| 10 | export fn entry() void { | |
| 11 | _ = foo(); | |
| 12 | } | |
| 13 | ||
| 14 | // error | |
| 15 | // backend=stage2 | |
| 16 | // target=native | |
| 17 | // | |
| 18 | // :8:18: error: expected type 'tmp.A(u32)', found 'tmp.B(u32)' | |
| 19 | // :5:12: note: struct declared here | |
| 20 | // :2:12: note: struct declared here |