| author | |
| committer | |
| log | a3d2f2999f9708cbcc6f3082547b5f68a3b593cd |
| tree | 27455924e27051dab92e0c44f63e9b90c985fe3e |
| parent | f92b998f9fe985d554d6078bb2bb11d094d94b91 |
| signature |
Some for bugs which have been fixed, some for language changes.20 files changed, 297 insertions(+), 51 deletions(-)
test/behavior/alignof.zig+5| ... | ... | @@ -39,3 +39,8 @@ test "correct alignment for elements and slices of aligned array" { |
| 39 | 39 | try expect(@alignOf(@TypeOf(&buf[start..end])) == @alignOf(*u8)); |
| 40 | 40 | try expect(@alignOf(@TypeOf(&buf[start])) == @alignOf(*u8)); |
| 41 | 41 | } |
| 42 | ||
| 43 | test "@alignOf(anyerror!noreturn)" { | |
| 44 | try expect(@alignOf(anyerror!noreturn) == @alignOf(anyerror)); | |
| 45 | try expect(@alignOf(anyerror!anyerror!noreturn) == @alignOf(anyerror)); | |
| 46 | } |
test/behavior/enum.zig+15| ... | ... | @@ -1354,3 +1354,18 @@ test "empty enum passed as argument" { |
| 1354 | 1354 | }; |
| 1355 | 1355 | E.f(@as(E, undefined)); |
| 1356 | 1356 | } |
| 1357 | ||
| 1358 | test "enum int tag type uses declaration inside the enum" { | |
| 1359 | const static = struct { | |
| 1360 | const E = enum(E.IntTag) { | |
| 1361 | const IntTag = u8; | |
| 1362 | a, | |
| 1363 | b, | |
| 1364 | c, | |
| 1365 | }; | |
| 1366 | }; | |
| 1367 | try expect(@sizeOf(static.E) == @sizeOf(u8)); | |
| 1368 | const val: static.E = .b; | |
| 1369 | try expect(val == .b); | |
| 1370 | try expect(@intFromEnum(val) == 1); | |
| 1371 | } |
test/behavior/error.zig+33| ... | ... | @@ -1109,3 +1109,36 @@ test "'if' ignores error via local while 'else' ignores error directly" { |
| 1109 | 1109 | try S.testOne(false); |
| 1110 | 1110 | try S.testOne(true); |
| 1111 | 1111 | } |
| 1112 | ||
| 1113 | test "@errorCast into own inferred error set" { | |
| 1114 | const static = struct { | |
| 1115 | fn foo(b: bool) !void { | |
| 1116 | if (b) { | |
| 1117 | return @errorCast(error.Bad); | |
| 1118 | } | |
| 1119 | } | |
| 1120 | }; | |
| 1121 | try static.foo(false); | |
| 1122 | if (static.foo(true)) { | |
| 1123 | return error.ExpectedError; | |
| 1124 | } else |err| { | |
| 1125 | try expect(err == error.Bad); | |
| 1126 | } | |
| 1127 | ||
| 1128 | const errors = @typeInfo(@typeInfo(@TypeOf(static.foo(false))).error_union.error_set).error_set.?; | |
| 1129 | comptime assert(errors.len == 1); | |
| 1130 | comptime assert(std.mem.eql(u8, errors[0].name, "Bad")); | |
| 1131 | } | |
| 1132 | ||
| 1133 | test "@errorCast into other inferred error set" { | |
| 1134 | const static = struct { | |
| 1135 | fn foo() !void { | |
| 1136 | return error.Bad; | |
| 1137 | } | |
| 1138 | }; | |
| 1139 | const Ies = @typeInfo(@TypeOf(static.foo())).error_union.error_set; | |
| 1140 | const err: Ies = @errorCast(error.Bad); | |
| 1141 | try expect(err == error.Bad); | |
| 1142 | const non_err: Ies!u32 = @errorCast(@as(error{}!u32, 123)); | |
| 1143 | try expect(try non_err == 123); | |
| 1144 | } |
test/behavior/packed-union.zig+22| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const assert = std.debug.assert; |
| 4 | const expect = std.testing.expect; | |
| 4 | 5 | const expectEqual = std.testing.expectEqual; |
| 5 | 6 | |
| 6 | 7 | test "flags in packed union" { |
| ... | ... | @@ -177,3 +178,24 @@ test "assigning to non-active field at comptime" { |
| 177 | 178 | test_bits.bits = .{}; |
| 178 | 179 | } |
| 179 | 180 | } |
| 181 | ||
| 182 | test "packed union with explicit backing integer" { | |
| 183 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 184 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 185 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; | |
| 186 | ||
| 187 | const U = packed union(i32) { | |
| 188 | raw: i32, | |
| 189 | unsigned_halves: packed struct { low: u16, high: u16 }, | |
| 190 | ||
| 191 | fn check(val: @This()) !void { | |
| 192 | try expect(@as(i32, @bitCast(val)) == -2); | |
| 193 | try expect(@as(u32, @bitCast(val)) == 0xFFFFFFFE); | |
| 194 | try expect(val.raw == -2); | |
| 195 | try expect(val.unsigned_halves.low == 0xFFFE); | |
| 196 | try expect(val.unsigned_halves.high == 0xFFFF); | |
| 197 | } | |
| 198 | }; | |
| 199 | try U.check(.{ .raw = -2 }); | |
| 200 | try comptime U.check(.{ .raw = -2 }); | |
| 201 | } |
test/behavior/struct.zig+51| ... | ... | @@ -2254,3 +2254,54 @@ test "runtime-known slice of comptime-only struct" { |
| 2254 | 2254 | .{ .index = 15, .T = Mixed }, |
| 2255 | 2255 | }); |
| 2256 | 2256 | } |
| 2257 | ||
| 2258 | test "struct contains aligned pointer to itself through type decl" { | |
| 2259 | const Slab = struct { | |
| 2260 | const Ptr = *align(64) const @This(); | |
| 2261 | next: Ptr, | |
| 2262 | }; | |
| 2263 | // We intentionally use `Slab.Ptr` before `Slab`. | |
| 2264 | var ptr: Slab.Ptr = undefined; | |
| 2265 | var slab: Slab align(64) = undefined; | |
| 2266 | ptr = &slab; | |
| 2267 | slab.next = ptr; | |
| 2268 | ||
| 2269 | try expect(ptr == &slab); | |
| 2270 | try expect(slab.next == &slab); | |
| 2271 | try expect(slab.next.next == &slab); | |
| 2272 | try expect(slab.next.next.next == &slab); | |
| 2273 | } | |
| 2274 | ||
| 2275 | test "struct contains underaligned field with overaligned pointer to itself" { | |
| 2276 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 2277 | const S = struct { | |
| 2278 | ptr: *align(8) @This() align(1), | |
| 2279 | }; | |
| 2280 | var val: S align(8) = undefined; | |
| 2281 | val.ptr = &val; | |
| 2282 | try expect(val.ptr == &val); | |
| 2283 | try expect(val.ptr.ptr == &val); | |
| 2284 | try expect(val.ptr.ptr.ptr == &val); | |
| 2285 | } | |
| 2286 | ||
| 2287 | test "struct contains pointer to function accepting that struct" { | |
| 2288 | const S = struct { | |
| 2289 | const FnPtr = ?*const fn (@This()) void; | |
| 2290 | fn_ptr: FnPtr, | |
| 2291 | }; | |
| 2292 | const dummy_fn_ptr: S.FnPtr = @ptrFromInt(0x100000); | |
| 2293 | const dummy_s: S = .{ .fn_ptr = dummy_fn_ptr }; | |
| 2294 | try expect(dummy_s.fn_ptr == dummy_fn_ptr); | |
| 2295 | try expect(@TypeOf(dummy_s.fn_ptr.?) == *const fn (S) void); | |
| 2296 | } | |
| 2297 | ||
| 2298 | test "struct queries typeinfo of struct containing pointer back to first struct" { | |
| 2299 | const static = struct { | |
| 2300 | const A = struct { b: *B }; | |
| 2301 | const B = struct { a: T: { | |
| 2302 | _ = @typeInfo(A); | |
| 2303 | break :T u32; | |
| 2304 | } }; | |
| 2305 | }; | |
| 2306 | _ = @as(static.A, undefined); | |
| 2307 | } |
test/behavior/tuple.zig+11| ... | ... | @@ -592,3 +592,14 @@ test "array of tuples that end with a zero-bit field followed by padding" { |
| 592 | 592 | try expect(S.foo[1][1] == 4); |
| 593 | 593 | try expect(S.foo[1][2] == {}); |
| 594 | 594 | } |
| 595 | ||
| 596 | test "call function at comptime through container-level const tuple" { | |
| 597 | const static = struct { | |
| 598 | const MyTuple = struct { (fn () u32) }; | |
| 599 | const val: MyTuple = .{foo}; | |
| 600 | fn foo() u32 { | |
| 601 | return 1234; | |
| 602 | } | |
| 603 | }; | |
| 604 | comptime assert(static.val[0]() == 1234); | |
| 605 | } |
test/cases/compile_errors/enum_uses_own_typeinfo.zig created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | const E = enum(u9) { | |
| 2 | const a_val: @typeInfo(E).@"enum".tag_type = 0; | |
| 3 | a = a_val, | |
| 4 | }; | |
| 5 | comptime { | |
| 6 | _ = E.a; | |
| 7 | } | |
| 8 | ||
| 9 | // error | |
| 10 | // | |
| 11 | // error: dependency loop with length 3 | |
| 12 | // :3:9: note: type 'tmp.E' uses value of declaration 'tmp.E.a_val' here | |
| 13 | // :2:50: note: value of declaration 'tmp.E.a_val' uses type of declaration 'tmp.E.a_val' here | |
| 14 | // :2:18: note: type of declaration 'tmp.E.a_val' depends on type 'tmp.E' for type information query here | |
| 15 | // note: eliminate any one of these dependencies to break the loop |
test/cases/compile_errors/exported_enum_without_explicit_integer_tag_type.zig+2-2| ... | ... | @@ -11,6 +11,6 @@ comptime { |
| 11 | 11 | // |
| 12 | 12 | // :3:5: error: unable to export type 'type' |
| 13 | 13 | // :7:5: error: unable to export type 'tmp.E' |
| 14 | // :7:5: note: enum tag type 'u1' is not extern compatible | |
| 15 | // :7:5: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible | |
| 14 | // :1:11: note: integer tag type of enum is inferred | |
| 15 | // :1:11: note: consider explicitly specifying the integer tag type | |
| 16 | 16 | // :1:11: note: enum declared here |
test/cases/compile_errors/extern_struct_with_extern-compatible_but_inferred_integer_tag_type.zig deleted-45| ... | ... | @@ -1,45 +0,0 @@ |
| 1 | // zig fmt: off | |
| 2 | pub const E = enum { | |
| 3 | @"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12", | |
| 4 | @"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23", | |
| 5 | @"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34", | |
| 6 | @"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45", | |
| 7 | @"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56", | |
| 8 | @"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67", | |
| 9 | @"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78", | |
| 10 | @"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89", | |
| 11 | @"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100", | |
| 12 | @"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109", | |
| 13 | @"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118", | |
| 14 | @"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127", | |
| 15 | @"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136", | |
| 16 | @"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145", | |
| 17 | @"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154", | |
| 18 | @"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163", | |
| 19 | @"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172", | |
| 20 | @"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181", | |
| 21 | @"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190", | |
| 22 | @"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199", | |
| 23 | @"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208", | |
| 24 | @"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217", | |
| 25 | @"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226", | |
| 26 | @"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235", | |
| 27 | @"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244", | |
| 28 | @"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253", | |
| 29 | @"254",@"255", @"256" | |
| 30 | }; | |
| 31 | // zig fmt: on | |
| 32 | pub const S = extern struct { | |
| 33 | e: E, | |
| 34 | }; | |
| 35 | export fn entry() void { | |
| 36 | const s: S = undefined; | |
| 37 | _ = s; | |
| 38 | } | |
| 39 | ||
| 40 | // error | |
| 41 | // | |
| 42 | // :33:8: error: extern structs cannot contain fields of type 'tmp.E' | |
| 43 | // :33:8: note: enum tag type 'u9' is not extern compatible | |
| 44 | // :33:8: note: only integers with 0 or power of two bits are extern compatible | |
| 45 | // :2:15: note: enum declared here |
test/cases/compile_errors/extern_struct_with_non-extern-compatible_integer_tag_type.zig+2-2| ... | ... | @@ -10,6 +10,6 @@ export fn entry() void { |
| 10 | 10 | // error |
| 11 | 11 | // |
| 12 | 12 | // :3:8: error: extern structs cannot contain fields of type 'tmp.E' |
| 13 | // :3:8: note: enum tag type 'u31' is not extern compatible | |
| 14 | // :3:8: note: only integers with 0 or power of two bits are extern compatible | |
| 13 | // :1:15: note: enum tag type 'u31' is not extern compatible | |
| 14 | // :1:15: note: only integers with 0 or power of two bits are extern compatible | |
| 15 | 15 | // :1:15: note: enum declared here |
test/cases/compile_errors/fn_type_returning_pointer_to_itself.zig created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | const MyFn = fn () ?*const MyFn; | |
| 2 | comptime { | |
| 3 | _ = MyFn; | |
| 4 | } | |
| 5 | ||
| 6 | // error | |
| 7 | // | |
| 8 | // :1:28: error: value of declaration 'tmp.MyFn' depends on itself here |
test/cases/compile_errors/function_with_non-extern_non-packed_enum_parameter.zig+2-2| ... | ... | @@ -7,6 +7,6 @@ export fn entry(foo: Foo) void { |
| 7 | 7 | // target=x86_64-linux |
| 8 | 8 | // |
| 9 | 9 | // :2:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv' |
| 10 | // :2:17: note: enum tag type 'u2' is not extern compatible | |
| 11 | // :2:17: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible | |
| 10 | // :1:13: note: integer tag type of enum is inferred | |
| 11 | // :1:13: note: consider explicitly specifying the integer tag type | |
| 12 | 12 | // :1:13: note: enum declared here |
test/cases/compile_errors/implicit_backing_type_in_extern_context.zig created+51| ... | ... | @@ -0,0 +1,51 @@ |
| 1 | const PackedStruct = packed struct { x: u32 }; | |
| 2 | const PackedUnion = packed union { x: u32 }; | |
| 3 | ||
| 4 | /// This enum has 256 fields, so `u8` will be its inferred tag type. | |
| 5 | const Enum = enum { | |
| 6 | // zig fmt: off | |
| 7 | _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0a, _0b, _0c, _0d, _0e, _0f, | |
| 8 | _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1a, _1b, _1c, _1d, _1e, _1f, | |
| 9 | _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2a, _2b, _2c, _2d, _2e, _2f, | |
| 10 | _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3a, _3b, _3c, _3d, _3e, _3f, | |
| 11 | _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4a, _4b, _4c, _4d, _4e, _4f, | |
| 12 | _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5a, _5b, _5c, _5d, _5e, _5f, | |
| 13 | _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6a, _6b, _6c, _6d, _6e, _6f, | |
| 14 | _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7a, _7b, _7c, _7d, _7e, _7f, | |
| 15 | _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8a, _8b, _8c, _8d, _8e, _8f, | |
| 16 | _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9a, _9b, _9c, _9d, _9e, _9f, | |
| 17 | _a0, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _aa, _ab, _ac, _ad, _ae, _af, | |
| 18 | _b0, _b1, _b2, _b3, _b4, _b5, _b6, _b7, _b8, _b9, _ba, _bb, _bc, _bd, _be, _bf, | |
| 19 | _c0, _c1, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _ca, _cb, _cc, _cd, _ce, _cf, | |
| 20 | _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7, _d8, _d9, _da, _db, _dc, _dd, _de, _df, | |
| 21 | _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7, _e8, _e9, _ea, _eb, _ec, _ed, _ee, _ef, | |
| 22 | _f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _fa, _fb, _fc, _fd, _fe, _ff, | |
| 23 | // zig fmt: on | |
| 24 | }; | |
| 25 | ||
| 26 | const Extern0 = extern struct { val: PackedStruct }; | |
| 27 | const Extern1 = extern struct { val: PackedUnion }; | |
| 28 | const Extern2 = extern struct { val: Enum }; | |
| 29 | ||
| 30 | comptime { | |
| 31 | _ = @as(Extern0, undefined); | |
| 32 | } | |
| 33 | comptime { | |
| 34 | _ = @as(Extern1, undefined); | |
| 35 | } | |
| 36 | comptime { | |
| 37 | _ = @as(Extern2, undefined); | |
| 38 | } | |
| 39 | ||
| 40 | // error | |
| 41 | // | |
| 42 | // :26:38: error: extern structs cannot contain fields of type 'tmp.PackedStruct' | |
| 43 | // :26:38: note: inferred backing integer of packed struct has unspecified signedness | |
| 44 | // :1:29: note: struct declared here | |
| 45 | // :27:38: error: extern structs cannot contain fields of type 'tmp.PackedUnion' | |
| 46 | // :27:38: note: inferred backing integer of packed union has unspecified signedness | |
| 47 | // :2:28: note: union declared here | |
| 48 | // :28:38: error: extern structs cannot contain fields of type 'tmp.Enum' | |
| 49 | // :5:14: note: integer tag type of enum is inferred | |
| 50 | // :5:14: note: consider explicitly specifying the integer tag type | |
| 51 | // :5:14: note: enum declared here |
test/cases/compile_errors/packed_struct_uses_own_size.zig created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | const S = packed struct { | |
| 2 | x: @Int(.unsigned, @sizeOf(S)), | |
| 3 | }; | |
| 4 | comptime { | |
| 5 | _ = @as(S, undefined); | |
| 6 | } | |
| 7 | ||
| 8 | // error | |
| 9 | // | |
| 10 | // :2:32: error: type 'tmp.S' depends on itself for size query here |
test/cases/compile_errors/packed_struct_uses_own_typeinfo.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | const S = packed struct(u16) { | |
| 2 | a: bool, | |
| 3 | b: bool, | |
| 4 | _padding: @Int(.unsigned, 17 - @typeInfo(S).Struct.fields.len) = 0, | |
| 5 | }; | |
| 6 | ||
| 7 | comptime { | |
| 8 | _ = @as(S, .{ .a = true, .b = true }); | |
| 9 | } | |
| 10 | ||
| 11 | // error | |
| 12 | // | |
| 13 | // :4:36: error: type 'tmp.S' depends on itself for type information query here |
test/cases/compile_errors/simple_struct_loop.zig created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | const A = struct { | |
| 2 | b: B, | |
| 3 | }; | |
| 4 | const B = struct { | |
| 5 | a: A, | |
| 6 | }; | |
| 7 | comptime { | |
| 8 | _ = @as(A, undefined); | |
| 9 | } | |
| 10 | ||
| 11 | // error | |
| 12 | // | |
| 13 | // error: dependency loop with length 2 | |
| 14 | // :2:8: note: type 'tmp.A' depends on type 'tmp.B' for field declared here | |
| 15 | // :5:8: note: type 'tmp.B' depends on type 'tmp.A' for field declared here | |
| 16 | // note: eliminate any one of these dependencies to break the loop |
test/cases/compile_errors/sizeOf_bad_type.zig+4| ... | ... | @@ -15,6 +15,9 @@ const S4 = struct { a: u32, b: noreturn }; |
| 15 | 15 | export fn entry4() usize { |
| 16 | 16 | return @sizeOf(S4); |
| 17 | 17 | } |
| 18 | export fn entry5() usize { | |
| 19 | return @sizeOf([1]fn () void); | |
| 20 | } | |
| 18 | 21 | |
| 19 | 22 | // error |
| 20 | 23 | // |
| ... | ... | @@ -25,3 +28,4 @@ export fn entry4() usize { |
| 25 | 28 | // :10:12: note: struct declared here |
| 26 | 29 | // :16:20: error: no size available for uninstantiable type 'tmp.S4' |
| 27 | 30 | // :14:12: note: struct declared here |
| 31 | // :19:20: error: no size available for comptime-only type '[1]fn () void' |
test/cases/compile_errors/struct_field_queries_hasfield_of_itself.zig created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | const Foo = packed struct { | |
| 2 | bar: (T: { | |
| 3 | _ = @hasField(Foo, "bar"); | |
| 4 | break :T void; | |
| 5 | }), | |
| 6 | }; | |
| 7 | ||
| 8 | comptime { | |
| 9 | _ = @as(Foo, undefined); | |
| 10 | } | |
| 11 | ||
| 12 | // error | |
| 13 | // | |
| 14 | // :3:23: error: type 'tmp.Foo' depends on itself for field query here |
test/cases/compile_errors/struct_uses_reified_type_which_queries_struct_alignment.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | const A = struct { b: *B }; | |
| 2 | const B = @Struct(.auto, null, &.{"x"}, &.{A}, &.{.{ .@"align" = @alignOf(A) }}); | |
| 3 | comptime { | |
| 4 | _ = @as(A, undefined); | |
| 5 | _ = @as(B, undefined); | |
| 6 | } | |
| 7 | ||
| 8 | // error | |
| 9 | // | |
| 10 | // error: dependency loop with length 2 | |
| 11 | // :1:24: note: type 'tmp.A' uses value of declaration 'tmp.B' here | |
| 12 | // :2:75: note: value of declaration 'tmp.B' depends on type 'tmp.A' for alignment query here | |
| 13 | // note: eliminate any one of these dependencies to break the loop |
test/cases/compile_errors/struct_uses_sizeof_self_as_array_len.zig created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | const S = struct { | |
| 2 | a: *[@sizeOf(S)]u8, | |
| 3 | }; | |
| 4 | comptime { | |
| 5 | _ = @as(S, undefined); | |
| 6 | } | |
| 7 | ||
| 8 | // error | |
| 9 | // | |
| 10 | // :2:18: error: type 'tmp.S' depends on itself for size query here |