1const std = @import("std");
2const builtin = @import("builtin");
3const testing = std.testing;
4const mem = std.mem;
5const assert = std.debug.assert;
6const expect = testing.expect;
7const expectEqual = testing.expectEqual;
8
9test "array to slice" {
10 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
11
12 const a: u32 align(4) = 3;
13 const b: u32 align(8) = 4;
14 const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..];
15 const b_slice: []align(1) const u32 = @as(*const [1]u32, &b)[0..];
16 try expect(a_slice[0] + b_slice[0] == 7);
17
18 const d: []const u32 = &[2]u32{ 1, 2 };
19 const e: []const u32 = &[3]u32{ 3, 4, 5 };
20 try expect(d[0] + e[0] + d[1] + e[1] == 10);
21}
22
23test "arrays" {
24 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
25 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
26 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
27
28 var array: [5]u32 = undefined;
29
30 var i: u32 = 0;
31 while (i < 5) {
32 array[i] = i + 1;
33 i = array[i];
34 }
35
36 i = 0;
37 var accumulator = @as(u32, 0);
38 while (i < 5) {
39 accumulator += array[i];
40
41 i += 1;
42 }
43
44 try expect(accumulator == 15);
45 try expect(getArrayLen(&array) == 5);
46}
47fn getArrayLen(a: []const u32) usize {
48 return a.len;
49}
50
51test "runtime array concat with comptime slice" {
52 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
53 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
54 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
55 var a: [1]u8 = .{1};
56 const b = (comptime @as([]const u8, &.{0})) ++ &a;
57 const c = &a ++ (comptime @as([]const u8, &.{0}));
58 try std.testing.expectEqualSlices(u8, &.{ 0, 1 }, b);
59 try std.testing.expectEqualSlices(u8, &.{ 1, 0 }, c);
60}
61
62test "array concat with undefined" {
63 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
64 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
65
66 const S = struct {
67 fn doTheTest() !void {
68 {
69 var array = "hello".* ++ @as([5]u8, undefined);
70 array[5..10].* = "world".*;
71 try std.testing.expect(std.mem.eql(u8, &array, "helloworld"));
72 }
73 {
74 var array = @as([5]u8, undefined) ++ "world".*;
75 array[0..5].* = "hello".*;
76 try std.testing.expect(std.mem.eql(u8, &array, "helloworld"));
77 }
78 }
79 };
80
81 try S.doTheTest();
82 try comptime S.doTheTest();
83}
84
85test "array concat with tuple" {
86 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
87 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
89
90 const array: [2]u8 = .{ 1, 2 };
91 {
92 const seq = array ++ .{ 3, 4 };
93 try std.testing.expectEqualSlices(u8, &.{ 1, 2, 3, 4 }, &seq);
94 }
95 {
96 const seq = .{ 3, 4 } ++ array;
97 try std.testing.expectEqualSlices(u8, &.{ 3, 4, 1, 2 }, &seq);
98 }
99}
100
101test "array concat with undefined tuple" {
102 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
103
104 {
105 const array: [2]u64 = .{ 1, 2 };
106 var seq = array ++ @as(struct { u32, u16 }, undefined);
107 seq[2] = 3;
108 seq[3] = 4;
109 try std.testing.expectEqualSlices(u64, &.{ 1, 2, 3, 4 }, &seq);
110 }
111 {
112 const array: [2]u64 = undefined;
113 var seq = @as(struct { u32, u16 }, undefined) ++ array;
114 for (&seq, 1..) |*s, i| s.* = i;
115 try std.testing.expectEqualSlices(u64, &.{ 1, 2, 3, 4 }, &seq);
116 }
117}
118
119test "array init with concat" {
120 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
121
122 const a = 'a';
123 var i: [4]u8 = [2]u8{ a, 'b' } ++ [2]u8{ 'c', 'd' };
124 try expect(std.mem.eql(u8, &i, "abcd"));
125}
126
127test "array literal with explicit type" {
128 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
129
130 const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 };
131
132 try expect(hex_mult.len == 4);
133 try expect(hex_mult[1] == 256);
134}
135
136test "array literal with inferred length" {
137 const hex_mult = [_]u16{ 4096, 256, 16, 1 };
138
139 try expect(hex_mult.len == 4);
140 try expect(hex_mult[1] == 256);
141}
142
143test "array dot len const expr" {
144 try expect(comptime x: {
145 break :x some_array.len == 4;
146 });
147}
148
149const ArrayDotLenConstExpr = struct {
150 y: [some_array.len]u8,
151};
152const some_array = [_]u8{ 0, 1, 2, 3 };
153
154test "array literal with specified size" {
155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
156 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
157
158 var array = [2]u8{ 1, 2 };
159 _ = &array;
160 try expect(array[0] == 1);
161 try expect(array[1] == 2);
162}
163
164test "array len field" {
165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
166
167 var arr = [4]u8{ 0, 0, 0, 0 };
168 const ptr = &arr;
169 try expect(arr.len == 4);
170 comptime assert(arr.len == 4);
171 try expect(ptr.len == 4);
172 comptime assert(ptr.len == 4);
173 try expect(@TypeOf(arr.len) == usize);
174}
175
176test "array with sentinels" {
177 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
178 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
179
180 const S = struct {
181 fn doTheTest(is_ct: bool) !void {
182 {
183 var zero_sized: [0:0xde]u8 = [_:0xde]u8{};
184 try expect(zero_sized[0] == 0xde);
185 var reinterpreted: *[1]u8 = @ptrCast(&zero_sized);
186 _ = &reinterpreted;
187 try expect(reinterpreted[0] == 0xde);
188 }
189 var arr: [3:0x55]u8 = undefined;
190 // Make sure the sentinel pointer is pointing after the last element.
191 if (!is_ct) {
192 const sentinel_ptr = @intFromPtr(&arr[3]);
193 const last_elem_ptr = @intFromPtr(&arr[2]);
194 try expect((sentinel_ptr - last_elem_ptr) == 1);
195 }
196 // Make sure the sentinel is writeable.
197 arr[3] = 0x55;
198 }
199 };
200
201 try S.doTheTest(false);
202 try comptime S.doTheTest(true);
203}
204
205test "void arrays" {
206 var array: [4]void = undefined;
207 array[0] = {};
208 array[1] = array[2];
209 try expect(@sizeOf(@TypeOf(array)) == 0);
210 try expect(array.len == 4);
211}
212
213test "nested arrays of strings" {
214 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
215 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
216 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
217
218 const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" };
219 for (array_of_strings, 0..) |s, i| {
220 if (i == 0) try expect(mem.eql(u8, s, "hello"));
221 if (i == 1) try expect(mem.eql(u8, s, "this"));
222 if (i == 2) try expect(mem.eql(u8, s, "is"));
223 if (i == 3) try expect(mem.eql(u8, s, "my"));
224 if (i == 4) try expect(mem.eql(u8, s, "thing"));
225 }
226}
227
228test "nested arrays of integers" {
229 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
230
231 const array_of_numbers = [_][2]u8{
232 [2]u8{ 1, 2 },
233 [2]u8{ 3, 4 },
234 };
235
236 try expect(array_of_numbers[0][0] == 1);
237 try expect(array_of_numbers[0][1] == 2);
238 try expect(array_of_numbers[1][0] == 3);
239 try expect(array_of_numbers[1][1] == 4);
240}
241
242test "implicit comptime in array type size" {
243 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
244
245 var arr: [plusOne(10)]bool = undefined;
246 _ = &arr;
247 try expect(arr.len == 11);
248}
249
250fn plusOne(x: u32) u32 {
251 return x + 1;
252}
253
254test "single-item pointer to array indexing and slicing" {
255 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
256 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
257
258 try testSingleItemPtrArrayIndexSlice();
259 try comptime testSingleItemPtrArrayIndexSlice();
260}
261
262fn testSingleItemPtrArrayIndexSlice() !void {
263 {
264 var array: [4]u8 = "aaaa".*;
265 doSomeMangling(&array);
266 try expect(mem.eql(u8, "azya", &array));
267 }
268 {
269 var array = "aaaa".*;
270 doSomeMangling(&array);
271 try expect(mem.eql(u8, "azya", &array));
272 }
273}
274
275fn doSomeMangling(array: *[4]u8) void {
276 array[1] = 'z';
277 array[2..3][0] = 'y';
278}
279
280test "implicit cast zero sized array ptr to slice" {
281 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
282 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
283
284 {
285 var b = "".*;
286 const c: []const u8 = &b;
287 try expect(c.len == 0);
288 }
289 {
290 var b: [0]u8 = "".*;
291 const c: []const u8 = &b;
292 try expect(c.len == 0);
293 }
294}
295
296test "anonymous list literal syntax" {
297 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
298 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
299
300 const S = struct {
301 fn doTheTest() !void {
302 var array: [4]u8 = .{ 1, 2, 3, 4 };
303 _ = &array;
304 try expect(array[0] == 1);
305 try expect(array[1] == 2);
306 try expect(array[2] == 3);
307 try expect(array[3] == 4);
308 }
309 };
310 try S.doTheTest();
311 try comptime S.doTheTest();
312}
313
314var s_array: [8]Sub = undefined;
315const Sub = struct { b: u8 };
316const Str = struct { a: []Sub };
317test "set global var array via slice embedded in struct" {
318 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
319 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
320
321 var s = Str{ .a = s_array[0..] };
322
323 s.a[0].b = 1;
324 s.a[1].b = 2;
325 s.a[2].b = 3;
326
327 try expect(s_array[0].b == 1);
328 try expect(s_array[1].b == 2);
329 try expect(s_array[2].b == 3);
330}
331
332test "implicit cast single-item pointer" {
333 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
334 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
335
336 try testImplicitCastSingleItemPtr();
337 try comptime testImplicitCastSingleItemPtr();
338}
339
340fn testImplicitCastSingleItemPtr() !void {
341 var byte: u8 = 100;
342 const slice = @as(*[1]u8, &byte)[0..];
343 slice[0] += 1;
344 try expect(byte == 101);
345}
346
347fn testArrayByValAtComptime(b: [2]u8) u8 {
348 return b[0];
349}
350
351test "comptime evaluating function that takes array by value" {
352 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
353
354 const arr = [_]u8{ 1, 2 };
355 const x = comptime testArrayByValAtComptime(arr);
356 const y = comptime testArrayByValAtComptime(arr);
357 try expect(x == 1);
358 try expect(y == 1);
359}
360
361test "runtime initialize array elem and then implicit cast to slice" {
362 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
363 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
364
365 var two: i32 = 2;
366 _ = &two;
367 const x: []const i32 = &[_]i32{two};
368 try expect(x[0] == 2);
369}
370
371test "array literal as argument to function" {
372 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
373 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
374
375 const S = struct {
376 fn entry(two: i32) !void {
377 try foo(&[_]i32{ 1, 2, 3 });
378 try foo(&[_]i32{ 1, two, 3 });
379 try foo2(true, &[_]i32{ 1, 2, 3 });
380 try foo2(true, &[_]i32{ 1, two, 3 });
381 }
382 fn foo(x: []const i32) !void {
383 try expect(x[0] == 1);
384 try expect(x[1] == 2);
385 try expect(x[2] == 3);
386 }
387 fn foo2(trash: bool, x: []const i32) !void {
388 try expect(trash);
389 try expect(x[0] == 1);
390 try expect(x[1] == 2);
391 try expect(x[2] == 3);
392 }
393 };
394 try S.entry(2);
395 try comptime S.entry(2);
396}
397
398test "double nested array to const slice cast in array literal" {
399 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
400 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
401 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
402
403 const S = struct {
404 fn entry(two: i32) !void {
405 const cases = [_][]const []const i32{
406 &[_][]const i32{&[_]i32{1}},
407 &[_][]const i32{&[_]i32{ 2, 3 }},
408 &[_][]const i32{
409 &[_]i32{4},
410 &[_]i32{ 5, 6, 7 },
411 },
412 };
413 try check(&cases);
414
415 const cases2 = [_][]const i32{
416 &[_]i32{1},
417 &[_]i32{ two, 3 },
418 };
419 try expect(cases2.len == 2);
420 try expect(cases2[0].len == 1);
421 try expect(cases2[0][0] == 1);
422 try expect(cases2[1].len == 2);
423 try expect(cases2[1][0] == 2);
424 try expect(cases2[1][1] == 3);
425
426 const cases3 = [_][]const []const i32{
427 &[_][]const i32{&[_]i32{1}},
428 &[_][]const i32{&[_]i32{ two, 3 }},
429 &[_][]const i32{
430 &[_]i32{4},
431 &[_]i32{ 5, 6, 7 },
432 },
433 };
434 try check(&cases3);
435 }
436
437 fn check(cases: []const []const []const i32) !void {
438 try expect(cases.len == 3);
439 try expect(cases[0].len == 1);
440 try expect(cases[0][0].len == 1);
441 try expect(cases[0][0][0] == 1);
442 try expect(cases[1].len == 1);
443 try expect(cases[1][0].len == 2);
444 try expect(cases[1][0][0] == 2);
445 try expect(cases[1][0][1] == 3);
446 try expect(cases[2].len == 2);
447 try expect(cases[2][0].len == 1);
448 try expect(cases[2][0][0] == 4);
449 try expect(cases[2][1].len == 3);
450 try expect(cases[2][1][0] == 5);
451 try expect(cases[2][1][1] == 6);
452 try expect(cases[2][1][2] == 7);
453 }
454 };
455 try S.entry(2);
456 try comptime S.entry(2);
457}
458
459test "anonymous literal in array" {
460 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
461 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
462
463 const S = struct {
464 const Foo = struct {
465 a: usize = 2,
466 b: usize = 4,
467 };
468 fn doTheTest() !void {
469 var array: [2]Foo = .{
470 .{ .a = 3 },
471 .{ .b = 3 },
472 };
473 _ = &array;
474 try expect(array[0].a == 3);
475 try expect(array[0].b == 4);
476 try expect(array[1].a == 2);
477 try expect(array[1].b == 3);
478 }
479 };
480 try S.doTheTest();
481 try comptime S.doTheTest();
482}
483
484test "access the null element of a null terminated array" {
485 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
486
487 const S = struct {
488 fn doTheTest() !void {
489 var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' };
490 _ = &array;
491 try expect(array[4] == 0);
492 var len: usize = 4;
493 _ = &len;
494 try expect(array[len] == 0);
495 }
496 };
497 try S.doTheTest();
498 try comptime S.doTheTest();
499}
500
501test "type deduction for array subscript expression" {
502 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
503 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
504
505 const S = struct {
506 fn doTheTest() !void {
507 var array = [_]u8{ 0x55, 0xAA };
508 var v0 = true;
509 try expect(@as(u8, 0xAA) == array[if (v0) 1 else 0]);
510 var v1 = false;
511 try expect(@as(u8, 0x55) == array[if (v1) 1 else 0]);
512 _ = .{ &array, &v0, &v1 };
513 }
514 };
515 try S.doTheTest();
516 try comptime S.doTheTest();
517}
518
519test "sentinel element count towards the ABI size calculation" {
520 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
521 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
522 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
523
524 const S = struct {
525 fn doTheTest() !void {
526 const T = extern struct {
527 fill_pre: u8 = 0x55,
528 data: [0:0]u8 = undefined,
529 fill_post: u8 = 0xAA,
530 };
531 var x = T{};
532 const as_slice = mem.asBytes(&x);
533 try expect(@as(usize, 3) == as_slice.len);
534 try expect(@as(u8, 0x55) == as_slice[0]);
535 try expect(@as(u8, 0xAA) == as_slice[2]);
536 }
537 };
538
539 try S.doTheTest();
540 try comptime S.doTheTest();
541}
542
543test "type coercion of anon struct literal to array" {
544 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
545 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
546 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
548
549 const S = struct {
550 const U = union {
551 a: u32,
552 b: bool,
553 c: []const u8,
554 };
555
556 fn doTheTest() !void {
557 var x1: u8 = 42;
558 _ = &x1;
559 const t1 = .{ x1, 56, 54 };
560 const arr1: [3]u8 = t1;
561 try expect(arr1[0] == 42);
562 try expect(arr1[1] == 56);
563 try expect(arr1[2] == 54);
564
565 var x2: U = .{ .a = 42 };
566 _ = &x2;
567 const t2 = .{ x2, U{ .b = true }, U{ .c = "hello" } };
568 const arr2: [3]U = t2;
569 try expect(arr2[0].a == 42);
570 try expect(arr2[1].b == true);
571 try expect(mem.eql(u8, arr2[2].c, "hello"));
572 }
573 };
574 try S.doTheTest();
575 try comptime S.doTheTest();
576}
577
578test "array with comptime-only element type" {
579 const a = [_]type{ u32, i32 };
580 try testing.expect(a[0] == u32);
581 try testing.expect(a[1] == i32);
582}
583
584test "tuple to array handles sentinel" {
585 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
586 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
587
588 const S = struct {
589 const a = .{ 1, 2, 3 };
590 var b: [3:0]u8 = a;
591 };
592 try expect(S.b[0] == 1);
593}
594
595test "array init of container level array variable" {
596 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
597 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
598 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
599
600 const S = struct {
601 var pair: [2]usize = .{ 1, 2 };
602 noinline fn foo(x: usize, y: usize) void {
603 pair = [2]usize{ x, y };
604 }
605 noinline fn bar(x: usize, y: usize) void {
606 var tmp: [2]usize = .{ x, y };
607 _ = &tmp;
608 pair = tmp;
609 }
610 };
611 try expectEqual([2]usize{ 1, 2 }, S.pair);
612 S.foo(3, 4);
613 try expectEqual([2]usize{ 3, 4 }, S.pair);
614 S.bar(5, 6);
615 try expectEqual([2]usize{ 5, 6 }, S.pair);
616}
617
618test "runtime initialized sentinel-terminated array literal" {
619 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
620
621 var c: u16 = 300;
622 _ = &c;
623 const f = &[_:0x9999]u16{c};
624 const g = @as(*const [4]u8, @ptrCast(f));
625 try std.testing.expect(g[2] == 0x99);
626 try std.testing.expect(g[3] == 0x99);
627}
628
629test "array of array agregate init" {
630 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
631 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
632
633 var a: [10]u32 = @splat(11);
634 var b: [2][10]u32 = @splat(a);
635 _ = .{ &a, &b };
636 try std.testing.expect(b[1][1] == 11);
637}
638
639test "pointer to array has ptr field" {
640 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
641
642 const arr: *const [5]u32 = &.{ 10, 20, 30, 40, 50 };
643 try std.testing.expect(arr.ptr == @as([*]const u32, arr));
644 try std.testing.expect(arr.ptr[0] == 10);
645 try std.testing.expect(arr.ptr[1] == 20);
646 try std.testing.expect(arr.ptr[2] == 30);
647 try std.testing.expect(arr.ptr[3] == 40);
648 try std.testing.expect((&arr.ptr).*[4] == 50);
649}
650
651test "discarded array init preserves result location" {
652 const S = struct {
653 fn f(p: *u32) u16 {
654 p.* += 1;
655 return 0;
656 }
657 };
658
659 var x: u32 = 0;
660 _ = [2]u8{
661 @intCast(S.f(&x)),
662 @intCast(S.f(&x)),
663 };
664
665 // Ensure function was run
666 try expect(x == 2);
667}
668
669test "array init with no result location has result type" {
670 const x = .{ .foo = [2]u16{
671 @intCast(10),
672 @intCast(20),
673 } };
674
675 try expect(x.foo.len == 2);
676 try expect(x.foo[0] == 10);
677 try expect(x.foo[1] == 20);
678}
679
680test "slicing array of zero-sized values" {
681 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
682 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
683 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
684
685 var arr: [32]u0 = undefined;
686 for (arr[0..]) |*zero|
687 zero.* = 0;
688 for (arr[0..]) |zero|
689 try expect(zero == 0);
690}
691
692test "array init with no result pointer sets field result types" {
693 const S = struct {
694 // A function parameter has a result type, but no result pointer.
695 fn f(arr: [1]u32) u32 {
696 return arr[0];
697 }
698 };
699
700 const x: u64 = 123;
701 const y = S.f(.{@intCast(x)});
702
703 try expect(y == x);
704}
705
706test "runtime side-effects in comptime-known array init" {
707 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
708
709 var side_effects: u4 = 0;
710 const init = [4]u4{
711 blk: {
712 side_effects += 1;
713 break :blk 1;
714 },
715 blk: {
716 side_effects += 2;
717 break :blk 2;
718 },
719 blk: {
720 side_effects += 4;
721 break :blk 4;
722 },
723 blk: {
724 side_effects += 8;
725 break :blk 8;
726 },
727 };
728 try expectEqual([4]u4{ 1, 2, 4, 8 }, init);
729 try expectEqual(@as(u4, std.math.maxInt(u4)), side_effects);
730}
731
732test "slice initialized through reference to anonymous array init provides result types" {
733 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
734
735 var my_u32: u32 = 123;
736 var my_u64: u64 = 456;
737 _ = .{ &my_u32, &my_u64 };
738 const foo: []const u16 = &.{
739 @intCast(my_u32),
740 @intCast(my_u64),
741 @truncate(my_u32),
742 @truncate(my_u64),
743 };
744 try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo);
745}
746
747test "sentinel-terminated slice initialized through reference to anonymous array init provides result types" {
748 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
749
750 var my_u32: u32 = 123;
751 var my_u64: u64 = 456;
752 _ = .{ &my_u32, &my_u64 };
753 const foo: [:999]const u16 = &.{
754 @intCast(my_u32),
755 @intCast(my_u64),
756 @truncate(my_u32),
757 @truncate(my_u64),
758 };
759 try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo);
760}
761
762test "many-item pointer initialized through reference to anonymous array init provides result types" {
763 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
764 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
765
766 var my_u32: u32 = 123;
767 var my_u64: u64 = 456;
768 _ = .{ &my_u32, &my_u64 };
769 const foo: [*]const u16 = &.{
770 @intCast(my_u32),
771 @intCast(my_u64),
772 @truncate(my_u32),
773 @truncate(my_u64),
774 };
775 try expectEqual(123, foo[0]);
776 try expectEqual(456, foo[1]);
777 try expectEqual(123, foo[2]);
778 try expectEqual(456, foo[3]);
779}
780
781test "many-item sentinel-terminated pointer initialized through reference to anonymous array init provides result types" {
782 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
783 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
784
785 var my_u32: u32 = 123;
786 var my_u64: u64 = 456;
787 _ = .{ &my_u32, &my_u64 };
788 const foo: [*:999]const u16 = &.{
789 @intCast(my_u32),
790 @intCast(my_u64),
791 @truncate(my_u32),
792 @truncate(my_u64),
793 };
794 try expectEqual(123, foo[0]);
795 try expectEqual(456, foo[1]);
796 try expectEqual(123, foo[2]);
797 try expectEqual(456, foo[3]);
798 try expectEqual(999, foo[4]);
799}
800
801test "pointer to array initialized through reference to anonymous array init provides result types" {
802 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
803
804 var my_u32: u32 = 123;
805 var my_u64: u64 = 456;
806 _ = .{ &my_u32, &my_u64 };
807 const foo: *const [4]u16 = &.{
808 @intCast(my_u32),
809 @intCast(my_u64),
810 @truncate(my_u32),
811 @truncate(my_u64),
812 };
813 try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo);
814}
815
816test "pointer to sentinel-terminated array initialized through reference to anonymous array init provides result types" {
817 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
818
819 var my_u32: u32 = 123;
820 var my_u64: u64 = 456;
821 _ = .{ &my_u32, &my_u64 };
822 const foo: *const [4:999]u16 = &.{
823 @intCast(my_u32),
824 @intCast(my_u64),
825 @truncate(my_u32),
826 @truncate(my_u64),
827 };
828 try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo);
829}
830
831test "tuple initialized through reference to anonymous array init provides result types" {
832 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
833
834 const Tuple = struct { u64, *const u32 };
835 const foo: *const Tuple = &.{
836 @intCast(12345),
837 @ptrFromInt(0x1000),
838 };
839 try expect(foo[0] == 12345);
840 try expect(@intFromPtr(foo[1]) == 0x1000);
841}
842
843test "copied array element doesn't alias source" {
844 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
845 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
846
847 var x: [10][10]u32 = undefined;
848
849 x[0][1] = 0;
850 const a = x[0];
851 x[0][1] = 15;
852
853 try expect(a[1] == 0);
854}
855
856test "array initialized with string literal" {
857 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
858 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
859
860 const S = struct {
861 a: u32,
862 c: [5]u8,
863 };
864 const U = union {
865 s: S,
866 };
867 const s_1 = S{
868 .a = undefined,
869 .c = "12345".*, // this caused problems
870 };
871
872 var u_2 = U{ .s = s_1 };
873 _ = &u_2;
874 try std.testing.expectEqualStrings("12345", &u_2.s.c);
875}
876
877test "array initialized with array with sentinel" {
878 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
879 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
880
881 const S = struct {
882 a: u32,
883 c: [5]u8,
884 };
885 const U = union {
886 s: S,
887 };
888 const c = [5:0]u8{ 1, 2, 3, 4, 5 };
889 const s_1 = S{
890 .a = undefined,
891 .c = c, // this caused problems
892 };
893 var u_2 = U{ .s = s_1 };
894 _ = &u_2;
895 try std.testing.expectEqualSlices(u8, &.{ 1, 2, 3, 4, 5 }, &u_2.s.c);
896}
897
898test "store array of array of structs at comptime" {
899 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
900 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
901
902 const S = struct {
903 fn storeArrayOfArrayOfStructs() u8 {
904 const S = struct {
905 x: u8,
906 };
907
908 var cases = [_][1]S{
909 [_]S{
910 S{ .x = 15 },
911 },
912 };
913 _ = &cases;
914 return cases[0][0].x;
915 }
916 };
917
918 try expect(S.storeArrayOfArrayOfStructs() == 15);
919 comptime assert(S.storeArrayOfArrayOfStructs() == 15);
920}
921
922test "accessing multidimensional global array at comptime" {
923 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
924 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
925
926 const S = struct {
927 const array = [_][]const []const u8{
928 &.{"hello"},
929 &.{ "world", "hello" },
930 };
931 };
932
933 try std.testing.expect(S.array[0].len == 1);
934 try std.testing.expectEqualStrings("hello", S.array[0][0]);
935}
936
937test "union that needs padding bytes inside an array" {
938 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
939 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
940 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
941 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
942
943 const B = union(enum) {
944 D: u8,
945 E: u16,
946 };
947 const A = union(enum) {
948 B: B,
949 C: u8,
950 };
951 var as = [_]A{
952 A{ .B = B{ .D = 1 } },
953 A{ .B = B{ .D = 1 } },
954 };
955 _ = &as;
956
957 const a = as[0].B;
958 try std.testing.expect(a.D == 1);
959}
960
961test "runtime index of array of zero-bit values" {
962 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
963
964 var runtime: struct { array: [1]void, index: usize } = undefined;
965 runtime = .{ .array = .{{}}, .index = 0 };
966 const result = struct { index: usize, value: void }{
967 .index = runtime.index,
968 .value = runtime.array[runtime.index],
969 };
970 try std.testing.expect(result.index == 0);
971 try std.testing.expect(result.value == {});
972}
973
974test "initialize slice with reference to empty array initializer" {
975 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
976
977 const a: []const u8 = &.{};
978 comptime assert(a.len == 0);
979}
980
981test "initialize many-pointer with reference to empty array initializer" {
982 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
983
984 const a: [*]const u8 = &.{};
985 _ = a; // nothing meaningful to test; points to zero bits
986}
987
988test "initialize sentinel-terminated slice with reference to empty array initializer" {
989 const a: [:0]const u8 = &.{};
990 comptime assert(a.len == 0);
991 comptime assert(a[0] == 0);
992}
993
994test "initialize sentinel-terminated many-pointer with reference to empty array initializer" {
995 const a: [*:0]const u8 = &.{};
996 comptime assert(a[0] == 0);
997}
998
999test "pass pointer to empty array initializer to anytype parameter" {
1000 const S = struct {
1001 fn TypeOf(x: anytype) type {
1002 return @TypeOf(x);
1003 }
1004 };
1005 comptime assert(S.TypeOf(&.{}) == @TypeOf(&.{}));
1006}
1007
1008test "initialize pointer to anyopaque with reference to empty array initializer" {
1009 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1010
1011 const ptr: *const anyopaque = &.{};
1012 // The above acts like an untyped initializer, since the `.{}` has no result type.
1013 // So, `ptr` points in memory to an empty tuple (`@TypeOf(.{})`).
1014 const casted: *const @TypeOf(.{}) = @ptrCast(@alignCast(ptr));
1015 const loaded = casted.*;
1016 // `val` should be a `@TypeOf(.{})`, as expected.
1017 // We can't check the value, but it's zero-bit, so the type matching is good enough.
1018 comptime assert(@TypeOf(loaded) == @TypeOf(.{}));
1019}
1020
1021test "sentinel of runtime-known array initialization is populated" {
1022 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1023
1024 var rt: u32 = undefined;
1025 rt = 42;
1026
1027 const arr: [1:123]u32 = .{rt};
1028 const elems: [*]const u32 = &arr;
1029
1030 try expect(elems[0] == 42);
1031 try expect(elems[1] == 123);
1032}
1033
1034test "resist alias of explicit copy of array passed as arg" {
1035 const S = struct {
1036 const Thing = [1]u32;
1037
1038 fn destroy_and_replace(box_b: *Thing, a: Thing, box_a: *Thing) void {
1039 box_a.* = undefined;
1040 box_b.* = a;
1041 }
1042 };
1043
1044 var buf_a: S.Thing = .{1234};
1045 var buf_b: S.Thing = .{5678};
1046 const box_a = &buf_a;
1047 const box_b = &buf_b;
1048
1049 const a = box_a.*; // explicit copy
1050 S.destroy_and_replace(box_b, a, box_a);
1051
1052 try expect(buf_b[0] == 1234);
1053}
1054
1055test "access element through reference" {
1056 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1057
1058 const S = struct {
1059 fn doTheTest(x: u8) !void {
1060 {
1061 var val: [1]u8 = .{x};
1062 const single_ptr: *[1]u8 = &val;
1063 try expect(single_ptr.*[0] == x);
1064 const elem_ptr = &single_ptr.*[0];
1065 comptime assert(@TypeOf(elem_ptr) == *u8);
1066 try expect(elem_ptr.* == x);
1067 }
1068 {
1069 var val: [1]u8 = .{x};
1070 const c_ptr: [*c][1]u8 = &val;
1071 try expect(c_ptr.*[0] == x);
1072 const elem_ptr = &c_ptr.*[0];
1073 comptime assert(@TypeOf(elem_ptr) == *u8);
1074 try expect(elem_ptr.* == x);
1075 }
1076 }
1077 };
1078 try comptime S.doTheTest(123);
1079 try S.doTheTest(123);
1080}