blob ccfbc7e9 (12342B) - Raw
1 const std = @import("std"); 2 const testing = std.testing; 3 const mem = std.mem; 4 const expect = testing.expect; 5 const expectEqual = testing.expectEqual; 6 7 test "arrays" { 8 var array: [5]u32 = undefined; 9 10 var i: u32 = 0; 11 while (i < 5) { 12 array[i] = i + 1; 13 i = array[i]; 14 } 15 16 i = 0; 17 var accumulator = @as(u32, 0); 18 while (i < 5) { 19 accumulator += array[i]; 20 21 i += 1; 22 } 23 24 expect(accumulator == 15); 25 expect(getArrayLen(&array) == 5); 26 } 27 fn getArrayLen(a: []const u32) usize { 28 return a.len; 29 } 30 31 test "array with sentinels" { 32 const S = struct { 33 fn doTheTest(is_ct: bool) void { 34 if (is_ct) { 35 var zero_sized: [0:0xde]u8 = [_:0xde]u8{}; 36 // Disabled at runtime because of 37 // https://github.com/ziglang/zig/issues/4372 38 expectEqual(@as(u8, 0xde), zero_sized[0]); 39 var reinterpreted = @ptrCast(*[1]u8, &zero_sized); 40 expectEqual(@as(u8, 0xde), reinterpreted[0]); 41 } 42 var arr: [3:0x55]u8 = undefined; 43 // Make sure the sentinel pointer is pointing after the last element 44 if (!is_ct) { 45 const sentinel_ptr = @ptrToInt(&arr[3]); 46 const last_elem_ptr = @ptrToInt(&arr[2]); 47 expectEqual(@as(usize, 1), sentinel_ptr - last_elem_ptr); 48 } 49 // Make sure the sentinel is writeable 50 arr[3] = 0x55; 51 } 52 }; 53 54 S.doTheTest(false); 55 comptime S.doTheTest(true); 56 } 57 58 test "void arrays" { 59 var array: [4]void = undefined; 60 array[0] = void{}; 61 array[1] = array[2]; 62 expect(@sizeOf(@TypeOf(array)) == 0); 63 expect(array.len == 4); 64 } 65 66 test "array literal" { 67 const hex_mult = [_]u16{ 68 4096, 69 256, 70 16, 71 1, 72 }; 73 74 expect(hex_mult.len == 4); 75 expect(hex_mult[1] == 256); 76 } 77 78 test "array dot len const expr" { 79 expect(comptime x: { 80 break :x some_array.len == 4; 81 }); 82 } 83 84 const ArrayDotLenConstExpr = struct { 85 y: [some_array.len]u8, 86 }; 87 const some_array = [_]u8{ 88 0, 89 1, 90 2, 91 3, 92 }; 93 94 test "nested arrays" { 95 const array_of_strings = [_][]const u8{ 96 "hello", 97 "this", 98 "is", 99 "my", 100 "thing", 101 }; 102 for (array_of_strings) |s, i| { 103 if (i == 0) expect(mem.eql(u8, s, "hello")); 104 if (i == 1) expect(mem.eql(u8, s, "this")); 105 if (i == 2) expect(mem.eql(u8, s, "is")); 106 if (i == 3) expect(mem.eql(u8, s, "my")); 107 if (i == 4) expect(mem.eql(u8, s, "thing")); 108 } 109 } 110 111 var s_array: [8]Sub = undefined; 112 const Sub = struct { 113 b: u8, 114 }; 115 const Str = struct { 116 a: []Sub, 117 }; 118 test "set global var array via slice embedded in struct" { 119 var s = Str{ .a = s_array[0..] }; 120 121 s.a[0].b = 1; 122 s.a[1].b = 2; 123 s.a[2].b = 3; 124 125 expect(s_array[0].b == 1); 126 expect(s_array[1].b == 2); 127 expect(s_array[2].b == 3); 128 } 129 130 test "array literal with specified size" { 131 var array = [2]u8{ 132 1, 133 2, 134 }; 135 expect(array[0] == 1); 136 expect(array[1] == 2); 137 } 138 139 test "array len field" { 140 var arr = [4]u8{ 0, 0, 0, 0 }; 141 var ptr = &arr; 142 expect(arr.len == 4); 143 comptime expect(arr.len == 4); 144 expect(ptr.len == 4); 145 comptime expect(ptr.len == 4); 146 } 147 148 test "single-item pointer to array indexing and slicing" { 149 testSingleItemPtrArrayIndexSlice(); 150 comptime testSingleItemPtrArrayIndexSlice(); 151 } 152 153 fn testSingleItemPtrArrayIndexSlice() void { 154 { 155 var array: [4]u8 = "aaaa".*; 156 doSomeMangling(&array); 157 expect(mem.eql(u8, "azya", &array)); 158 } 159 { 160 var array = "aaaa".*; 161 doSomeMangling(&array); 162 expect(mem.eql(u8, "azya", &array)); 163 } 164 } 165 166 fn doSomeMangling(array: *[4]u8) void { 167 array[1] = 'z'; 168 array[2..3][0] = 'y'; 169 } 170 171 test "implicit cast single-item pointer" { 172 testImplicitCastSingleItemPtr(); 173 comptime testImplicitCastSingleItemPtr(); 174 } 175 176 fn testImplicitCastSingleItemPtr() void { 177 var byte: u8 = 100; 178 const slice = @as(*[1]u8, &byte)[0..]; 179 slice[0] += 1; 180 expect(byte == 101); 181 } 182 183 fn testArrayByValAtComptime(b: [2]u8) u8 { 184 return b[0]; 185 } 186 187 test "comptime evalutating function that takes array by value" { 188 const arr = [_]u8{ 0, 1 }; 189 _ = comptime testArrayByValAtComptime(arr); 190 _ = comptime testArrayByValAtComptime(arr); 191 } 192 193 test "implicit comptime in array type size" { 194 var arr: [plusOne(10)]bool = undefined; 195 expect(arr.len == 11); 196 } 197 198 fn plusOne(x: u32) u32 { 199 return x + 1; 200 } 201 202 test "runtime initialize array elem and then implicit cast to slice" { 203 var two: i32 = 2; 204 const x: []const i32 = &[_]i32{two}; 205 expect(x[0] == 2); 206 } 207 208 test "array literal as argument to function" { 209 const S = struct { 210 fn entry(two: i32) void { 211 foo(&[_]i32{ 212 1, 213 2, 214 3, 215 }); 216 foo(&[_]i32{ 217 1, 218 two, 219 3, 220 }); 221 foo2(true, &[_]i32{ 222 1, 223 2, 224 3, 225 }); 226 foo2(true, &[_]i32{ 227 1, 228 two, 229 3, 230 }); 231 } 232 fn foo(x: []const i32) void { 233 expect(x[0] == 1); 234 expect(x[1] == 2); 235 expect(x[2] == 3); 236 } 237 fn foo2(trash: bool, x: []const i32) void { 238 expect(trash); 239 expect(x[0] == 1); 240 expect(x[1] == 2); 241 expect(x[2] == 3); 242 } 243 }; 244 S.entry(2); 245 comptime S.entry(2); 246 } 247 248 test "double nested array to const slice cast in array literal" { 249 const S = struct { 250 fn entry(two: i32) void { 251 const cases = [_][]const []const i32{ 252 &[_][]const i32{&[_]i32{1}}, 253 &[_][]const i32{&[_]i32{ 2, 3 }}, 254 &[_][]const i32{ 255 &[_]i32{4}, 256 &[_]i32{ 5, 6, 7 }, 257 }, 258 }; 259 check(&cases); 260 261 const cases2 = [_][]const i32{ 262 &[_]i32{1}, 263 &[_]i32{ two, 3 }, 264 }; 265 expect(cases2.len == 2); 266 expect(cases2[0].len == 1); 267 expect(cases2[0][0] == 1); 268 expect(cases2[1].len == 2); 269 expect(cases2[1][0] == 2); 270 expect(cases2[1][1] == 3); 271 272 const cases3 = [_][]const []const i32{ 273 &[_][]const i32{&[_]i32{1}}, 274 &[_][]const i32{&[_]i32{ two, 3 }}, 275 &[_][]const i32{ 276 &[_]i32{4}, 277 &[_]i32{ 5, 6, 7 }, 278 }, 279 }; 280 check(&cases3); 281 } 282 283 fn check(cases: []const []const []const i32) void { 284 expect(cases.len == 3); 285 expect(cases[0].len == 1); 286 expect(cases[0][0].len == 1); 287 expect(cases[0][0][0] == 1); 288 expect(cases[1].len == 1); 289 expect(cases[1][0].len == 2); 290 expect(cases[1][0][0] == 2); 291 expect(cases[1][0][1] == 3); 292 expect(cases[2].len == 2); 293 expect(cases[2][0].len == 1); 294 expect(cases[2][0][0] == 4); 295 expect(cases[2][1].len == 3); 296 expect(cases[2][1][0] == 5); 297 expect(cases[2][1][1] == 6); 298 expect(cases[2][1][2] == 7); 299 } 300 }; 301 S.entry(2); 302 comptime S.entry(2); 303 } 304 305 test "read/write through global variable array of struct fields initialized via array mult" { 306 const S = struct { 307 fn doTheTest() void { 308 expect(storage[0].term == 1); 309 storage[0] = MyStruct{ .term = 123 }; 310 expect(storage[0].term == 123); 311 } 312 313 pub const MyStruct = struct { 314 term: usize, 315 }; 316 317 var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1; 318 }; 319 S.doTheTest(); 320 } 321 322 test "implicit cast zero sized array ptr to slice" { 323 { 324 var b = "".*; 325 const c: []const u8 = &b; 326 expect(c.len == 0); 327 } 328 { 329 var b: [0]u8 = "".*; 330 const c: []const u8 = &b; 331 expect(c.len == 0); 332 } 333 } 334 335 test "anonymous list literal syntax" { 336 const S = struct { 337 fn doTheTest() void { 338 var array: [4]u8 = .{ 1, 2, 3, 4 }; 339 expect(array[0] == 1); 340 expect(array[1] == 2); 341 expect(array[2] == 3); 342 expect(array[3] == 4); 343 } 344 }; 345 S.doTheTest(); 346 comptime S.doTheTest(); 347 } 348 349 test "anonymous literal in array" { 350 const S = struct { 351 const Foo = struct { 352 a: usize = 2, 353 b: usize = 4, 354 }; 355 fn doTheTest() void { 356 var array: [2]Foo = .{ 357 .{ .a = 3 }, 358 .{ .b = 3 }, 359 }; 360 expect(array[0].a == 3); 361 expect(array[0].b == 4); 362 expect(array[1].a == 2); 363 expect(array[1].b == 3); 364 } 365 }; 366 S.doTheTest(); 367 comptime S.doTheTest(); 368 } 369 370 test "access the null element of a null terminated array" { 371 const S = struct { 372 fn doTheTest() void { 373 var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; 374 expect(array[4] == 0); 375 var len: usize = 4; 376 expect(array[len] == 0); 377 } 378 }; 379 S.doTheTest(); 380 comptime S.doTheTest(); 381 } 382 383 test "type deduction for array subscript expression" { 384 const S = struct { 385 fn doTheTest() void { 386 var array = [_]u8{ 0x55, 0xAA }; 387 var v0 = true; 388 expectEqual(@as(u8, 0xAA), array[if (v0) 1 else 0]); 389 var v1 = false; 390 expectEqual(@as(u8, 0x55), array[if (v1) 1 else 0]); 391 } 392 }; 393 S.doTheTest(); 394 comptime S.doTheTest(); 395 } 396 397 test "sentinel element count towards the ABI size calculation" { 398 const S = struct { 399 fn doTheTest() void { 400 const T = packed struct { 401 fill_pre: u8 = 0x55, 402 data: [0:0]u8 = undefined, 403 fill_post: u8 = 0xAA, 404 }; 405 var x = T{}; 406 var as_slice = mem.asBytes(&x); 407 expectEqual(@as(usize, 3), as_slice.len); 408 expectEqual(@as(u8, 0x55), as_slice[0]); 409 expectEqual(@as(u8, 0xAA), as_slice[2]); 410 } 411 }; 412 413 S.doTheTest(); 414 comptime S.doTheTest(); 415 } 416 417 test "zero-sized array with recursive type definition" { 418 const U = struct { 419 fn foo(comptime T: type, comptime n: usize) type { 420 return struct { 421 s: [n]T, 422 x: usize = n, 423 }; 424 } 425 }; 426 427 const S = struct { 428 list: U.foo(@This(), 0), 429 }; 430 431 var t: S = .{ .list = .{ .s = undefined } }; 432 expectEqual(@as(usize, 0), t.list.x); 433 } 434 435 test "type coercion of anon struct literal to array" { 436 const S = struct { 437 const U = union{ 438 a: u32, 439 b: bool, 440 c: []const u8, 441 }; 442 443 fn doTheTest() void { 444 var x1: u8 = 42; 445 const t1 = .{ x1, 56, 54 }; 446 var arr1: [3]u8 = t1; 447 expect(arr1[0] == 42); 448 expect(arr1[1] == 56); 449 expect(arr1[2] == 54); 450 451 var x2: U = .{ .a = 42 }; 452 const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } }; 453 var arr2: [3]U = t2; 454 expect(arr2[0].a == 42); 455 expect(arr2[1].b == true); 456 expect(mem.eql(u8, arr2[2].c, "hello")); 457 } 458 }; 459 S.doTheTest(); 460 comptime S.doTheTest(); 461 } 462 463 test "type coercion of pointer to anon struct literal to pointer to array" { 464 const S = struct { 465 const U = union{ 466 a: u32, 467 b: bool, 468 c: []const u8, 469 }; 470 471 fn doTheTest() void { 472 var x1: u8 = 42; 473 const t1 = &.{ x1, 56, 54 }; 474 var arr1: *[3]u8 = t1; 475 expect(arr1[0] == 42); 476 expect(arr1[1] == 56); 477 expect(arr1[2] == 54); 478 479 var x2: U = .{ .a = 42 }; 480 const t2 = &.{ x2, .{ .b = true }, .{ .c = "hello" } }; 481 var arr2: *[3]U = t2; 482 expect(arr2[0].a == 42); 483 expect(arr2[1].b == true); 484 expect(mem.eql(u8, arr2[2].c, "hello")); 485 } 486 }; 487 S.doTheTest(); 488 comptime S.doTheTest(); 489 }