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