master
1const builtin = @import("builtin");
2const std = @import("std");
3const assert = std.debug.assert;
4const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;
6const expectEqualSlices = std.testing.expectEqualSlices;
7const mem = std.mem;
8const maxInt = std.math.maxInt;
9const native_endian = builtin.target.cpu.arch.endian();
10
11test "int to ptr cast" {
12 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
13
14 const x = @as(usize, 13);
15 const y = @as(*u8, @ptrFromInt(x));
16 const z = @intFromPtr(y);
17 try expect(z == 13);
18}
19
20test "integer literal to pointer cast" {
21 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
22
23 const vga_mem = @as(*u16, @ptrFromInt(0xB8000));
24 try expect(@intFromPtr(vga_mem) == 0xB8000);
25}
26
27test "peer type resolution: ?T and T" {
28 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
30
31 try expect(peerTypeTAndOptionalT(true, false).? == 0);
32 try expect(peerTypeTAndOptionalT(false, false).? == 3);
33 comptime {
34 try expect(peerTypeTAndOptionalT(true, false).? == 0);
35 try expect(peerTypeTAndOptionalT(false, false).? == 3);
36 }
37}
38fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
39 if (c) {
40 return if (b) null else @as(usize, 0);
41 }
42
43 return @as(usize, 3);
44}
45
46test "resolve undefined with integer" {
47 try testResolveUndefWithInt(true, 1234);
48 try comptime testResolveUndefWithInt(true, 1234);
49}
50fn testResolveUndefWithInt(b: bool, x: i32) !void {
51 const value = if (b) x else undefined;
52 if (b) {
53 try expect(value == x);
54 }
55}
56
57test "@intCast to comptime_int" {
58 try expect(@as(comptime_int, @intCast(0)) == 0);
59}
60
61test "implicit cast comptime numbers to any type when the value fits" {
62 const a: u64 = 255;
63 var b: u8 = a;
64 _ = &b;
65 try expect(b == 255);
66}
67
68test "implicit cast comptime_int to comptime_float" {
69 comptime assert(@as(comptime_float, 10) == @as(f32, 10));
70 try expect(2 == 2.0);
71}
72
73test "comptime_int @floatFromInt" {
74 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
75
76 {
77 const result = @as(f16, @floatFromInt(1234));
78 try expect(@TypeOf(result) == f16);
79 try expect(result == 1234.0);
80 }
81 {
82 const result = @as(f32, @floatFromInt(1234));
83 try expect(@TypeOf(result) == f32);
84 try expect(result == 1234.0);
85 }
86 {
87 const result = @as(f64, @floatFromInt(1234));
88 try expect(@TypeOf(result) == f64);
89 try expect(result == 1234.0);
90 }
91
92 {
93 const result = @as(f128, @floatFromInt(1234));
94 try expect(@TypeOf(result) == f128);
95 try expect(result == 1234.0);
96 }
97 // big comptime_int (> 64 bits) to f128 conversion
98 {
99 const result = @as(f128, @floatFromInt(0x1_0000_0000_0000_0000));
100 try expect(@TypeOf(result) == f128);
101 try expect(result == 0x1_0000_0000_0000_0000.0);
102 }
103}
104
105test "@floatFromInt" {
106 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
107 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109
110 const S = struct {
111 fn doTheTest() !void {
112 try testIntToFloat(-2);
113 }
114
115 fn testIntToFloat(k: i32) !void {
116 const f = @as(f32, @floatFromInt(k));
117 const i = @as(i32, @intFromFloat(f));
118 try expect(i == k);
119 }
120 };
121 try S.doTheTest();
122 try comptime S.doTheTest();
123}
124
125test "@floatFromInt(f80)" {
126 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
127 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
128 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
129 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
130 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
131
132 const S = struct {
133 fn doTheTest(comptime Int: type) !void {
134 try testIntToFloat(Int, -2);
135 }
136
137 fn testIntToFloat(comptime Int: type, k: Int) !void {
138 @setRuntimeSafety(false); // TODO
139 const f = @as(f80, @floatFromInt(k));
140 const i = @as(Int, @intFromFloat(f));
141 try expect(i == k);
142 }
143 };
144 try S.doTheTest(i31);
145 try S.doTheTest(i32);
146 try S.doTheTest(i45);
147 try S.doTheTest(i64);
148 try S.doTheTest(i80);
149 try S.doTheTest(i128);
150 // try S.doTheTest(i256); // TODO missing compiler_rt symbols
151 try comptime S.doTheTest(i31);
152 try comptime S.doTheTest(i32);
153 try comptime S.doTheTest(i45);
154 try comptime S.doTheTest(i64);
155 try comptime S.doTheTest(i80);
156 try comptime S.doTheTest(i128);
157 try comptime S.doTheTest(i256);
158}
159
160test "@intFromFloat" {
161 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
162 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
163 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
164
165 try testIntFromFloats();
166 try comptime testIntFromFloats();
167}
168
169fn testIntFromFloats() !void {
170 const x = @as(i32, 1e4);
171 try expect(x == 10000);
172 const y = @as(i32, @intFromFloat(@as(f32, 1e4)));
173 try expect(y == 10000);
174 try expectIntFromFloat(f32, 255.1, u8, 255);
175 try expectIntFromFloat(f32, 127.2, i8, 127);
176 try expectIntFromFloat(f32, -128.2, i8, -128);
177}
178
179fn expectIntFromFloat(comptime F: type, f: F, comptime I: type, i: I) !void {
180 try expect(@as(I, @intFromFloat(f)) == i);
181}
182
183test "implicitly cast indirect pointer to maybe-indirect pointer" {
184 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
185 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
186
187 const S = struct {
188 const Self = @This();
189 x: u8,
190 fn constConst(p: *const *const Self) u8 {
191 return p.*.x;
192 }
193 fn maybeConstConst(p: ?*const *const Self) u8 {
194 return p.?.*.x;
195 }
196 fn constConstConst(p: *const *const *const Self) u8 {
197 return p.*.*.x;
198 }
199 fn maybeConstConstConst(p: ?*const *const *const Self) u8 {
200 return p.?.*.*.x;
201 }
202 };
203 const s = S{ .x = 42 };
204 const p = &s;
205 const q = &p;
206 const r = &q;
207 try expect(42 == S.constConst(q));
208 try expect(42 == S.maybeConstConst(q));
209 try expect(42 == S.constConstConst(r));
210 try expect(42 == S.maybeConstConstConst(r));
211}
212
213test "@intCast comptime_int" {
214 const result = @as(i32, @intCast(1234));
215 try expect(@TypeOf(result) == i32);
216 try expect(result == 1234);
217}
218
219test "@floatCast comptime_int and comptime_float" {
220 {
221 const result = @as(f16, @floatCast(1234));
222 try expect(@TypeOf(result) == f16);
223 try expect(result == 1234.0);
224 }
225 {
226 const result = @as(f16, @floatCast(1234.0));
227 try expect(@TypeOf(result) == f16);
228 try expect(result == 1234.0);
229 }
230 {
231 const result = @as(f32, @floatCast(1234));
232 try expect(@TypeOf(result) == f32);
233 try expect(result == 1234.0);
234 }
235 {
236 const result = @as(f32, @floatCast(1234.0));
237 try expect(@TypeOf(result) == f32);
238 try expect(result == 1234.0);
239 }
240}
241
242test "coerce undefined to optional" {
243 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
244 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
245
246 try expect(MakeType(void).getNull() == null);
247 try expect(MakeType(void).getNonNull() != null);
248}
249
250fn MakeType(comptime T: type) type {
251 return struct {
252 fn getNull() ?T {
253 return null;
254 }
255
256 fn getNonNull() ?T {
257 return @as(T, undefined);
258 }
259 };
260}
261
262test "implicit cast from *[N]T to [*c]T" {
263 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
264 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
265
266 var x: [4]u16 = [4]u16{ 0, 1, 2, 3 };
267 var y: [*c]u16 = &x;
268
269 try expect(std.mem.eql(u16, x[0..4], y[0..4]));
270 x[0] = 8;
271 y[3] = 6;
272 try expect(std.mem.eql(u16, x[0..4], y[0..4]));
273}
274
275test "*usize to *void" {
276 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
277
278 var i = @as(usize, 0);
279 const v: *void = @ptrCast(&i);
280 v.* = {};
281}
282
283test "@enumFromInt passed a comptime_int to an enum with one item" {
284 const E = enum { A };
285 const x = @as(E, @enumFromInt(0));
286 try expect(x == E.A);
287}
288
289test "@intCast to u0 and use the result" {
290 const S = struct {
291 fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {
292 try expect((one << @as(u0, @intCast(bigzero))) == 1);
293 try expect((zero << @as(u0, @intCast(bigzero))) == 0);
294 }
295 };
296 try S.doTheTest(0, 1, 0);
297 try comptime S.doTheTest(0, 1, 0);
298}
299
300test "peer result null and comptime_int" {
301 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
302 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
303
304 const S = struct {
305 fn blah(n: i32) ?i32 {
306 if (n == 0) {
307 return null;
308 } else if (n < 0) {
309 return -1;
310 } else {
311 return 1;
312 }
313 }
314 };
315
316 try expect(S.blah(0) == null);
317 comptime assert(S.blah(0) == null);
318 try expect(S.blah(10).? == 1);
319 comptime assert(S.blah(10).? == 1);
320 try expect(S.blah(-10).? == -1);
321 comptime assert(S.blah(-10).? == -1);
322}
323
324test "*const ?[*]const T to [*c]const [*c]const T" {
325 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
326 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
327 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
328
329 var array = [_]u8{ 'o', 'k' };
330 const opt_array_ptr: ?[*]const u8 = &array;
331 const a: *const ?[*]const u8 = &opt_array_ptr;
332 const b: [*c]const [*c]const u8 = a;
333 try expect(b.*[0] == 'o');
334 try expect(b[0][1] == 'k');
335}
336
337test "array coercion to undefined at runtime" {
338 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
339 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
340
341 @setRuntimeSafety(true);
342
343 if (builtin.mode != .Debug and builtin.mode != .ReleaseSafe) {
344 return error.SkipZigTest;
345 }
346
347 var array = [4]u8{ 3, 4, 5, 6 };
348 var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA };
349
350 try expect(std.mem.eql(u8, &array, &array));
351 array = undefined;
352 try expect(std.mem.eql(u8, &array, &undefined_val));
353}
354
355test "implicitly cast from int to anyerror!?T" {
356 implicitIntLitToOptional();
357 comptime implicitIntLitToOptional();
358}
359fn implicitIntLitToOptional() void {
360 const f: ?i32 = 1;
361 _ = f;
362 const g: anyerror!?i32 = 1;
363 _ = g catch {};
364}
365
366test "return u8 coercing into ?u32 return type" {
367 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
368 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
369
370 const S = struct {
371 fn doTheTest() !void {
372 try expect(foo(123).? == 123);
373 }
374 fn foo(arg: u8) ?u32 {
375 return arg;
376 }
377 };
378 try S.doTheTest();
379 try comptime S.doTheTest();
380}
381
382test "cast from ?[*]T to ??[*]T" {
383 const a: ??[*]u8 = @as(?[*]u8, null);
384 try expect(a != null and a.? == null);
385}
386
387test "peer type unsigned int to signed" {
388 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
389
390 var w: u31 = 5;
391 var x: u8 = 7;
392 var y: i32 = -5;
393 _ = .{ &w, &x, &y };
394 const a = w + y + x;
395 comptime assert(@TypeOf(a) == i32);
396 try expect(a == 7);
397}
398
399test "expected [*c]const u8, found [*:0]const u8" {
400 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
401 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
402
403 var a: [*:0]const u8 = "hello";
404 _ = &a;
405 const b: [*c]const u8 = a;
406 const c: [*:0]const u8 = b;
407 try expect(std.mem.eql(u8, c[0..5], "hello"));
408}
409
410test "explicit cast from integer to error type" {
411 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
412 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
413 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
414 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
415
416 try testCastIntToErr(error.ItBroke);
417 try comptime testCastIntToErr(error.ItBroke);
418}
419fn testCastIntToErr(err: anyerror) !void {
420 const x = @intFromError(err);
421 const y = @errorFromInt(x);
422 try expect(error.ItBroke == y);
423}
424
425test "peer resolve array and const slice" {
426 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
428 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
429
430 try testPeerResolveArrayConstSlice(true);
431 try comptime testPeerResolveArrayConstSlice(true);
432}
433fn testPeerResolveArrayConstSlice(b: bool) !void {
434 const value1 = if (b) "aoeu" else @as([]const u8, "zz");
435 const value2 = if (b) @as([]const u8, "zz") else "aoeu";
436 try expect(mem.eql(u8, value1, "aoeu"));
437 try expect(mem.eql(u8, value2, "zz"));
438}
439
440test "implicitly cast from T to anyerror!?T" {
441 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
442 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
443
444 try castToOptionalTypeError(1);
445 try comptime castToOptionalTypeError(1);
446}
447
448const A = struct {
449 a: i32,
450};
451fn castToOptionalTypeError(z: i32) !void {
452 const x = @as(i32, 1);
453 const y: anyerror!?i32 = x;
454 try expect((try y).? == 1);
455
456 const f = z;
457 const g: anyerror!?i32 = f;
458 _ = try g;
459
460 const a = A{ .a = z };
461 const b: anyerror!?A = a;
462 try expect((b catch unreachable).?.a == 1);
463}
464
465test "implicitly cast from [0]T to anyerror![]T" {
466 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
467
468 try testCastZeroArrayToErrSliceMut();
469 try comptime testCastZeroArrayToErrSliceMut();
470}
471
472fn testCastZeroArrayToErrSliceMut() !void {
473 try expect((gimmeErrOrSlice() catch unreachable).len == 0);
474}
475
476fn gimmeErrOrSlice() anyerror![]u8 {
477 return &[_]u8{};
478}
479
480test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
481 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
482 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
483 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
484
485 const S = struct {
486 fn doTheTest() anyerror!void {
487 {
488 var data = "hi".*;
489 const slice = data[0..];
490 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
491 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
492 }
493 {
494 var data: [2]u8 = "hi".*;
495 const slice = data[0..];
496 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
497 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
498 }
499 }
500 };
501 try S.doTheTest();
502 try comptime S.doTheTest();
503}
504fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
505 if (a) {
506 return &[_]u8{};
507 }
508
509 return slice[0..1];
510}
511
512test "implicit cast from *const [N]T to []const T" {
513 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
514 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
515
516 try testCastConstArrayRefToConstSlice();
517 try comptime testCastConstArrayRefToConstSlice();
518}
519
520fn testCastConstArrayRefToConstSlice() !void {
521 {
522 const blah = "aoeu".*;
523 const const_array_ref = &blah;
524 try expect(@TypeOf(const_array_ref) == *const [4:0]u8);
525 const slice: []const u8 = const_array_ref;
526 try expect(mem.eql(u8, slice, "aoeu"));
527 }
528 {
529 const blah: [4]u8 = "aoeu".*;
530 const const_array_ref = &blah;
531 try expect(@TypeOf(const_array_ref) == *const [4]u8);
532 const slice: []const u8 = const_array_ref;
533 try expect(mem.eql(u8, slice, "aoeu"));
534 }
535}
536
537test "peer type resolution: error and [N]T" {
538 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
539 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
540
541 try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
542 comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
543 try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
544 comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
545}
546
547fn testPeerErrorAndArray(x: u8) anyerror![]const u8 {
548 return switch (x) {
549 0x00 => "OK",
550 else => error.BadValue,
551 };
552}
553fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
554 return switch (x) {
555 0x00 => "OK",
556 0x01 => "OKK",
557 else => error.BadValue,
558 };
559}
560
561test "single-item pointer of array to slice to unknown length pointer" {
562 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
563 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
564
565 try testCastPtrOfArrayToSliceAndPtr();
566 try comptime testCastPtrOfArrayToSliceAndPtr();
567}
568
569fn testCastPtrOfArrayToSliceAndPtr() !void {
570 {
571 var array = "aoeu".*;
572 const x: [*]u8 = &array;
573 x[0] += 1;
574 try expect(mem.eql(u8, array[0..], "boeu"));
575 const y: []u8 = &array;
576 y[0] += 1;
577 try expect(mem.eql(u8, array[0..], "coeu"));
578 }
579 {
580 var array: [4]u8 = "aoeu".*;
581 const x: [*]u8 = &array;
582 x[0] += 1;
583 try expect(mem.eql(u8, array[0..], "boeu"));
584 const y: []u8 = &array;
585 y[0] += 1;
586 try expect(mem.eql(u8, array[0..], "coeu"));
587 }
588}
589
590test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
591 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
592 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
593
594 const window_name = [1][*]const u8{"window name"};
595 const x: [*]const ?[*]const u8 = &window_name;
596 try expect(mem.eql(u8, std.mem.sliceTo(@as([*:0]const u8, @ptrCast(x[0].?)), 0), "window name"));
597}
598
599test "@intCast on vector" {
600 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
601 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
602 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
603 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
604 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
605 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
606 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
607
608 const S = struct {
609 fn doTheTest() !void {
610 {
611 // Upcast (implicit, equivalent to @intCast)
612 var up0: @Vector(2, u8) = .{ 0x55, 0xaa };
613 _ = &up0;
614 const up1: @Vector(2, u16) = up0;
615 const up2: @Vector(2, u32) = up0;
616 const up3: @Vector(2, u64) = up0;
617
618 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));
619 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));
620 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));
621
622 {
623 // Downcast (safety-checked)
624 const down2: @Vector(2, u32) = @intCast(up3);
625 const down1: @Vector(2, u16) = @intCast(up3);
626 const down0: @Vector(2, u8) = @intCast(up3);
627
628 try expect(mem.eql(u32, &@as([2]u32, down2), &[2]u32{ 0x55, 0xaa }));
629 try expect(mem.eql(u16, &@as([2]u16, down1), &[2]u16{ 0x55, 0xaa }));
630 try expect(mem.eql(u8, &@as([2]u8, down0), &[2]u8{ 0x55, 0xaa }));
631 }
632
633 {
634 // Downcast (safety-checked)
635 const down1: @Vector(2, u16) = @intCast(up2);
636 const down0: @Vector(2, u8) = @intCast(up2);
637
638 try expect(mem.eql(u16, &@as([2]u16, down1), &[2]u16{ 0x55, 0xaa }));
639 try expect(mem.eql(u8, &@as([2]u8, down0), &[2]u8{ 0x55, 0xaa }));
640 }
641
642 {
643 // Downcast (safety-checked)
644 const down0: @Vector(2, u8) = @intCast(up1);
645
646 try expect(mem.eql(u8, &@as([2]u8, down0), &[2]u8{ 0x55, 0xaa }));
647 }
648 }
649 {
650 // Upcast (implicit, equivalent to @intCast)
651 var up0: @Vector(4, u8) = .{ 0x00, 0x55, 0xaa, 0xff };
652 _ = &up0;
653 const up1: @Vector(4, u16) = up0;
654 const up2: @Vector(4, u32) = up0;
655 const up3: @Vector(4, u64) = up0;
656
657 try expect(mem.eql(u16, &@as([4]u16, up1), &[4]u16{ 0x00, 0x55, 0xaa, 0xff }));
658 try expect(mem.eql(u32, &@as([4]u32, up2), &[4]u32{ 0x00, 0x55, 0xaa, 0xff }));
659 try expect(mem.eql(u64, &@as([4]u64, up3), &[4]u64{ 0x00, 0x55, 0xaa, 0xff }));
660
661 {
662 // Downcast (safety-checked)
663 const down2: @Vector(4, u32) = @intCast(up3);
664 const down1: @Vector(4, u16) = @intCast(up3);
665 const down0: @Vector(4, u8) = @intCast(up3);
666
667 try expect(mem.eql(u32, &@as([4]u32, down2), &[4]u32{ 0x00, 0x55, 0xaa, 0xff }));
668 try expect(mem.eql(u16, &@as([4]u16, down1), &[4]u16{ 0x00, 0x55, 0xaa, 0xff }));
669 try expect(mem.eql(u8, &@as([4]u8, down0), &[4]u8{ 0x00, 0x55, 0xaa, 0xff }));
670 }
671
672 {
673 // Downcast (safety-checked)
674 const down1: @Vector(4, u16) = @intCast(up2);
675 const down0: @Vector(4, u8) = @intCast(up2);
676
677 try expect(mem.eql(u16, &@as([4]u16, down1), &[4]u16{ 0x00, 0x55, 0xaa, 0xff }));
678 try expect(mem.eql(u8, &@as([4]u8, down0), &[4]u8{ 0x00, 0x55, 0xaa, 0xff }));
679 }
680
681 {
682 // Downcast (safety-checked)
683 const down0: @Vector(4, u8) = @intCast(up1);
684
685 try expect(mem.eql(u8, &@as([4]u8, down0), &[4]u8{ 0x00, 0x55, 0xaa, 0xff }));
686 }
687 }
688 {
689 // Upcast (implicit, equivalent to @intCast)
690 var up0: @Vector(8, u8) = .{
691 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
692 };
693 _ = &up0;
694 const up1: @Vector(8, u16) = up0;
695 const up2: @Vector(8, u32) = up0;
696 const up3: @Vector(8, u64) = up0;
697
698 try expect(mem.eql(u16, &@as([8]u16, up1), &[8]u16{
699 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
700 }));
701 try expect(mem.eql(u32, &@as([8]u32, up2), &[8]u32{
702 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
703 }));
704 try expect(mem.eql(u64, &@as([8]u64, up3), &[8]u64{
705 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
706 }));
707
708 {
709 // Downcast (safety-checked)
710 const down2: @Vector(8, u32) = @intCast(up3);
711 const down1: @Vector(8, u16) = @intCast(up3);
712 const down0: @Vector(8, u8) = @intCast(up3);
713
714 try expect(mem.eql(u32, &@as([8]u32, down2), &[8]u32{
715 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
716 }));
717 try expect(mem.eql(u16, &@as([8]u16, down1), &[8]u16{
718 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
719 }));
720 try expect(mem.eql(u8, &@as([8]u8, down0), &[8]u8{
721 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
722 }));
723 }
724
725 {
726 // Downcast (safety-checked)
727 const down1: @Vector(8, u16) = @intCast(up2);
728 const down0: @Vector(8, u8) = @intCast(up2);
729
730 try expect(mem.eql(u16, &@as([8]u16, down1), &[8]u16{
731 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
732 }));
733 try expect(mem.eql(u8, &@as([8]u8, down0), &[8]u8{
734 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
735 }));
736 }
737
738 {
739 // Downcast (safety-checked)
740 const down0: @Vector(8, u8) = @intCast(up1);
741
742 try expect(mem.eql(u8, &@as([8]u8, down0), &[8]u8{
743 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
744 }));
745 }
746 }
747 {
748 // Upcast (implicit, equivalent to @intCast)
749 var up0: @Vector(16, u8) = .{
750 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
751 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
752 };
753 _ = &up0;
754 const up1: @Vector(16, u16) = up0;
755 const up2: @Vector(16, u32) = up0;
756 const up3: @Vector(16, u64) = up0;
757
758 try expect(mem.eql(u16, &@as([16]u16, up1), &[16]u16{
759 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
760 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
761 }));
762 try expect(mem.eql(u32, &@as([16]u32, up2), &[16]u32{
763 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
764 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
765 }));
766 try expect(mem.eql(u64, &@as([16]u64, up3), &[16]u64{
767 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
768 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
769 }));
770
771 {
772 // Downcast (safety-checked)
773 const down2: @Vector(16, u32) = @intCast(up3);
774 const down1: @Vector(16, u16) = @intCast(up3);
775 const down0: @Vector(16, u8) = @intCast(up3);
776
777 try expect(mem.eql(u32, &@as([16]u32, down2), &[16]u32{
778 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
779 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
780 }));
781 try expect(mem.eql(u16, &@as([16]u16, down1), &[16]u16{
782 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
783 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
784 }));
785 try expect(mem.eql(u8, &@as([16]u8, down0), &[16]u8{
786 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
787 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
788 }));
789 }
790
791 {
792 // Downcast (safety-checked)
793 const down1: @Vector(16, u16) = @intCast(up2);
794 const down0: @Vector(16, u8) = @intCast(up2);
795
796 try expect(mem.eql(u16, &@as([16]u16, down1), &[16]u16{
797 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
798 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
799 }));
800 try expect(mem.eql(u8, &@as([16]u8, down0), &[16]u8{
801 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
802 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
803 }));
804 }
805
806 {
807 // Downcast (safety-checked)
808 const down0: @Vector(16, u8) = @intCast(up1);
809
810 try expect(mem.eql(u8, &@as([16]u8, down0), &[16]u8{
811 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
812 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
813 }));
814 }
815 }
816 }
817 };
818
819 try S.doTheTest();
820 try comptime S.doTheTest();
821}
822
823test "@floatCast cast down" {
824 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
825 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
826 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
827
828 {
829 var double: f64 = 0.001534;
830 _ = &double;
831 const single = @as(f32, @floatCast(double));
832 try expect(single == 0.001534);
833 }
834 {
835 const double: f64 = 0.001534;
836 const single = @as(f32, @floatCast(double));
837 try expect(single == 0.001534);
838 }
839}
840
841test "peer type resolution: unreachable, error set, unreachable" {
842 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
843
844 const Error = error{
845 FileDescriptorAlreadyPresentInSet,
846 OperationCausesCircularLoop,
847 FileDescriptorNotRegistered,
848 SystemResources,
849 UserResourceLimitReached,
850 FileDescriptorIncompatibleWithEpoll,
851 Unexpected,
852 };
853 var err = Error.SystemResources;
854 _ = &err;
855 const transformed_err = switch (err) {
856 error.FileDescriptorAlreadyPresentInSet => unreachable,
857 error.OperationCausesCircularLoop => unreachable,
858 error.FileDescriptorNotRegistered => unreachable,
859 error.SystemResources => error.SystemResources,
860 error.UserResourceLimitReached => error.UserResourceLimitReached,
861 error.FileDescriptorIncompatibleWithEpoll => unreachable,
862 error.Unexpected => unreachable,
863 };
864 try expect(transformed_err == error.SystemResources);
865}
866
867test "peer cast: error set any anyerror" {
868 const a: error{ One, Two } = undefined;
869 const b: anyerror = undefined;
870 try expect(@TypeOf(a, b) == anyerror);
871 try expect(@TypeOf(b, a) == anyerror);
872}
873
874test "peer type resolution: error set supersets" {
875 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
876 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
877 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
878
879 const a: error{ One, Two } = undefined;
880 const b: error{One} = undefined;
881
882 // A superset of B
883 {
884 const ty = @TypeOf(a, b);
885 const error_set_info = @typeInfo(ty);
886 try expect(error_set_info == .error_set);
887 try expect(error_set_info.error_set.?.len == 2);
888 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
889 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
890 }
891
892 // B superset of A
893 {
894 const ty = @TypeOf(b, a);
895 const error_set_info = @typeInfo(ty);
896 try expect(error_set_info == .error_set);
897 try expect(error_set_info.error_set.?.len == 2);
898 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
899 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
900 }
901}
902
903test "peer type resolution: disjoint error sets" {
904 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
905 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
906 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
907
908 const a: error{ One, Two } = undefined;
909 const b: error{Three} = undefined;
910
911 {
912 const ty = @TypeOf(a, b);
913 const error_set_info = @typeInfo(ty);
914 try expect(error_set_info == .error_set);
915 try expect(error_set_info.error_set.?.len == 3);
916 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
917 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
918 try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three"));
919 }
920
921 {
922 const ty = @TypeOf(b, a);
923 const error_set_info = @typeInfo(ty);
924 try expect(error_set_info == .error_set);
925 try expect(error_set_info.error_set.?.len == 3);
926 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
927 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
928 try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three"));
929 }
930}
931
932test "peer type resolution: error union and error set" {
933 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
934 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
935 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
936
937 const a: error{Three} = undefined;
938 const b: error{ One, Two }!u32 = undefined;
939
940 {
941 const ty = @TypeOf(a, b);
942 const info = @typeInfo(ty);
943 try expect(info == .error_union);
944
945 const error_set_info = @typeInfo(info.error_union.error_set);
946 try expect(error_set_info.error_set.?.len == 3);
947 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
948 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
949 try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three"));
950 }
951
952 {
953 const ty = @TypeOf(b, a);
954 const info = @typeInfo(ty);
955 try expect(info == .error_union);
956
957 const error_set_info = @typeInfo(info.error_union.error_set);
958 try expect(error_set_info.error_set.?.len == 3);
959 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
960 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
961 try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three"));
962 }
963}
964
965test "peer type resolution: error union after non-error" {
966 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
967 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
968 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
969
970 const a: u32 = undefined;
971 const b: error{ One, Two }!u32 = undefined;
972
973 {
974 const ty = @TypeOf(a, b);
975 const info = @typeInfo(ty);
976 try expect(info == .error_union);
977 try expect(info.error_union.payload == u32);
978
979 const error_set_info = @typeInfo(info.error_union.error_set);
980 try expect(error_set_info.error_set.?.len == 2);
981 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
982 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
983 }
984
985 {
986 const ty = @TypeOf(b, a);
987 const info = @typeInfo(ty);
988 try expect(info == .error_union);
989 try expect(info.error_union.payload == u32);
990
991 const error_set_info = @typeInfo(info.error_union.error_set);
992 try expect(error_set_info.error_set.?.len == 2);
993 try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One"));
994 try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two"));
995 }
996}
997
998test "peer cast *[0]T to E![]const T" {
999 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1000 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1001 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1002
1003 var buffer: [5]u8 = "abcde".*;
1004 const buf: anyerror![]const u8 = buffer[0..];
1005 var b = false;
1006 _ = &b;
1007 const y = if (b) &[0]u8{} else buf;
1008 const z = if (!b) buf else &[0]u8{};
1009 try expect(mem.eql(u8, "abcde", y catch unreachable));
1010 try expect(mem.eql(u8, "abcde", z catch unreachable));
1011}
1012
1013test "peer cast *[0]T to []const T" {
1014 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1015 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1016 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1017
1018 var buffer: [5]u8 = "abcde".*;
1019 const buf: []const u8 = buffer[0..];
1020 var b = false;
1021 _ = &b;
1022 const y = if (b) &[0]u8{} else buf;
1023 try expect(mem.eql(u8, "abcde", y));
1024}
1025
1026test "peer cast *[N]T to [*]T" {
1027 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1028
1029 var array = [4:99]i32{ 1, 2, 3, 4 };
1030 var dest: [*]i32 = undefined;
1031 _ = &dest;
1032 try expect(@TypeOf(&array, dest) == [*]i32);
1033 try expect(@TypeOf(dest, &array) == [*]i32);
1034}
1035
1036test "peer resolution of string literals" {
1037 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1038 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1039 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1040
1041 const S = struct {
1042 const E = enum { a, b, c, d };
1043
1044 fn doTheTest(e: E) !void {
1045 const cmd = switch (e) {
1046 .a => "one",
1047 .b => "two",
1048 .c => "three",
1049 .d => "four",
1050 };
1051 try expect(mem.eql(u8, cmd, "two"));
1052 }
1053 };
1054 try S.doTheTest(.b);
1055 try comptime S.doTheTest(.b);
1056}
1057
1058test "peer cast [:x]T to []T" {
1059 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1060 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1061
1062 const S = struct {
1063 fn doTheTest() !void {
1064 var array = [4:0]i32{ 1, 2, 3, 4 };
1065 const slice: [:0]i32 = &array;
1066 const dest: []i32 = slice;
1067 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
1068 }
1069 };
1070 try S.doTheTest();
1071 try comptime S.doTheTest();
1072}
1073
1074test "peer cast [N:x]T to [N]T" {
1075 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1076 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1077
1078 const S = struct {
1079 fn doTheTest() !void {
1080 var array = [4:0]i32{ 1, 2, 3, 4 };
1081 _ = &array;
1082 const dest: [4]i32 = array;
1083 try expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 }));
1084 }
1085 };
1086 try S.doTheTest();
1087 try comptime S.doTheTest();
1088}
1089
1090test "peer cast *[N:x]T to *[N]T" {
1091 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1092 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1093
1094 const S = struct {
1095 fn doTheTest() !void {
1096 var array = [4:0]i32{ 1, 2, 3, 4 };
1097 const dest: *[4]i32 = &array;
1098 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
1099 }
1100 };
1101 try S.doTheTest();
1102 try comptime S.doTheTest();
1103}
1104
1105test "peer cast [*:x]T to [*]T" {
1106 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1107 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1108 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1109
1110 const S = struct {
1111 fn doTheTest() !void {
1112 var array = [4:99]i32{ 1, 2, 3, 4 };
1113 const dest: [*]i32 = &array;
1114 try expect(dest[0] == 1);
1115 try expect(dest[1] == 2);
1116 try expect(dest[2] == 3);
1117 try expect(dest[3] == 4);
1118 try expect(dest[4] == 99);
1119 }
1120 };
1121 try S.doTheTest();
1122 try comptime S.doTheTest();
1123}
1124
1125test "peer cast [:x]T to [*:x]T" {
1126 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1127 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1128 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1129
1130 const S = struct {
1131 fn doTheTest() !void {
1132 var array = [4:0]i32{ 1, 2, 3, 4 };
1133 const slice: [:0]i32 = &array;
1134 const dest: [*:0]i32 = slice;
1135 try expect(dest[0] == 1);
1136 try expect(dest[1] == 2);
1137 try expect(dest[2] == 3);
1138 try expect(dest[3] == 4);
1139 try expect(dest[4] == 0);
1140 }
1141 };
1142 try S.doTheTest();
1143 try comptime S.doTheTest();
1144}
1145
1146test "peer type resolution implicit cast to return type" {
1147 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1148 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1149
1150 const S = struct {
1151 fn doTheTest() !void {
1152 for ("hello") |c| _ = f(c);
1153 }
1154 fn f(c: u8) []const u8 {
1155 return switch (c) {
1156 'h', 'e' => &[_]u8{c}, // should cast to slice
1157 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
1158 else => ([_]u8{c})[0..], // is a slice
1159 };
1160 }
1161 };
1162 try S.doTheTest();
1163 try comptime S.doTheTest();
1164}
1165
1166test "peer type resolution implicit cast to variable type" {
1167 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1168 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1169
1170 const S = struct {
1171 fn doTheTest() !void {
1172 var x: []const u8 = undefined;
1173 for ("hello") |c| x = switch (c) {
1174 'h', 'e' => &[_]u8{c}, // should cast to slice
1175 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
1176 else => ([_]u8{c})[0..], // is a slice
1177 };
1178 }
1179 };
1180 try S.doTheTest();
1181 try comptime S.doTheTest();
1182}
1183
1184test "variable initialization uses result locations properly with regards to the type" {
1185 var b = true;
1186 _ = &b;
1187 const x: i32 = if (b) 1 else 2;
1188 try expect(x == 1);
1189}
1190
1191test "cast between C pointer with different but compatible types" {
1192 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1193 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1194
1195 const S = struct {
1196 fn foo(arg: [*]c_ushort) u16 {
1197 return arg[0];
1198 }
1199 fn doTheTest() !void {
1200 var x = [_]u16{ 4, 2, 1, 3 };
1201 try expect(foo(@as([*]u16, @ptrCast(&x))) == 4);
1202 }
1203 };
1204 try S.doTheTest();
1205 try comptime S.doTheTest();
1206}
1207
1208test "peer type resolve string lit with sentinel-terminated mutable slice" {
1209 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1210 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1211
1212 var array: [4:0]u8 = undefined;
1213 array[4] = 0; // TODO remove this when #4372 is solved
1214 const slice: [:0]u8 = array[0..4 :0];
1215 comptime assert(@TypeOf(slice, "hi") == [:0]const u8);
1216 comptime assert(@TypeOf("hi", slice) == [:0]const u8);
1217}
1218
1219test "peer type resolve array pointers, one of them const" {
1220 var array1: [4]u8 = undefined;
1221 const array2: [5]u8 = undefined;
1222 comptime assert(@TypeOf(&array1, &array2) == []const u8);
1223 comptime assert(@TypeOf(&array2, &array1) == []const u8);
1224}
1225
1226test "peer type resolve array pointer and unknown pointer" {
1227 const const_array: [4]u8 = undefined;
1228 var array: [4]u8 = undefined;
1229 var const_ptr: [*]const u8 = undefined;
1230 var ptr: [*]u8 = undefined;
1231 _ = .{ &const_ptr, &ptr };
1232
1233 comptime assert(@TypeOf(&array, ptr) == [*]u8);
1234 comptime assert(@TypeOf(ptr, &array) == [*]u8);
1235
1236 comptime assert(@TypeOf(&const_array, ptr) == [*]const u8);
1237 comptime assert(@TypeOf(ptr, &const_array) == [*]const u8);
1238
1239 comptime assert(@TypeOf(&array, const_ptr) == [*]const u8);
1240 comptime assert(@TypeOf(const_ptr, &array) == [*]const u8);
1241
1242 comptime assert(@TypeOf(&const_array, const_ptr) == [*]const u8);
1243 comptime assert(@TypeOf(const_ptr, &const_array) == [*]const u8);
1244}
1245
1246test "comptime float casts" {
1247 const a = @as(comptime_float, @floatFromInt(1));
1248 try expect(a == 1);
1249 try expect(@TypeOf(a) == comptime_float);
1250 const b = @as(comptime_int, @intFromFloat(2));
1251 try expect(b == 2);
1252 try expect(@TypeOf(b) == comptime_int);
1253
1254 try expectIntFromFloat(comptime_int, 1234, i16, 1234);
1255 try expectIntFromFloat(comptime_float, 12.3, comptime_int, 12);
1256}
1257
1258test "pointer reinterpret const float to int" {
1259 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1260
1261 // The hex representation is 0x3fe3333333333303.
1262 const float: f64 = 5.99999999999994648725e-01;
1263 const float_ptr = &float;
1264 const int_ptr = @as(*const i32, @ptrCast(float_ptr));
1265 const int_val = int_ptr.*;
1266 if (native_endian == .little)
1267 try expect(int_val == 0x33333303)
1268 else
1269 try expect(int_val == 0x3fe33333);
1270}
1271
1272test "implicit cast from [*]T to ?*anyopaque" {
1273 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1274 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1275 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1276
1277 var a = [_]u8{ 3, 2, 1 };
1278 var runtime_zero: usize = 0;
1279 _ = &runtime_zero;
1280 incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
1281 try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
1282}
1283
1284fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
1285 var n: usize = 0;
1286 while (n < len) : (n += 1) {
1287 @as([*]u8, @ptrCast(array.?))[n] += 1;
1288 }
1289}
1290
1291test "compile time int to ptr of function" {
1292 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1293
1294 try foobar(FUNCTION_CONSTANT);
1295}
1296
1297// On some architectures function pointers must be aligned.
1298const hardcoded_fn_addr = maxInt(usize) & ~@as(usize, 0xf);
1299pub const FUNCTION_CONSTANT = @as(PFN_void, @ptrFromInt(hardcoded_fn_addr));
1300pub const PFN_void = *const fn (*anyopaque) callconv(.c) void;
1301
1302fn foobar(func: PFN_void) !void {
1303 try std.testing.expect(@intFromPtr(func) == hardcoded_fn_addr);
1304}
1305
1306test "cast function with an opaque parameter" {
1307 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1308
1309 if (builtin.zig_backend == .stage2_c) {
1310 // https://github.com/ziglang/zig/issues/16845
1311 return error.SkipZigTest;
1312 }
1313
1314 const Container = struct {
1315 const Ctx = opaque {};
1316 ctx: *Ctx,
1317 func: *const fn (*Ctx) void,
1318 };
1319 const Foo = struct {
1320 x: i32,
1321 y: i32,
1322 fn funcImpl(self: *@This()) void {
1323 self.x += 1;
1324 self.y += 1;
1325 }
1326 };
1327 var foo = Foo{ .x = 100, .y = 200 };
1328 var c = Container{
1329 .ctx = @ptrCast(&foo),
1330 .func = @ptrCast(&Foo.funcImpl),
1331 };
1332 c.func(c.ctx);
1333 try std.testing.expectEqual(Foo{ .x = 101, .y = 201 }, foo);
1334}
1335
1336test "implicit ptr to *anyopaque" {
1337 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1338 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1339 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1340
1341 var a: u32 = 1;
1342 const ptr: *align(@alignOf(u32)) anyopaque = &a;
1343 const b: *u32 = @as(*u32, @ptrCast(ptr));
1344 try expect(b.* == 1);
1345 const ptr2: ?*align(@alignOf(u32)) anyopaque = &a;
1346 const c: *u32 = @as(*u32, @ptrCast(ptr2.?));
1347 try expect(c.* == 1);
1348}
1349
1350test "return null from fn () anyerror!?&T" {
1351 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1352 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1353
1354 const a = returnNullFromOptionalTypeErrorRef();
1355 const b = returnNullLitFromOptionalTypeErrorRef();
1356 try expect((try a) == null and (try b) == null);
1357}
1358fn returnNullFromOptionalTypeErrorRef() anyerror!?*A {
1359 const a: ?*A = null;
1360 return a;
1361}
1362fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
1363 return null;
1364}
1365
1366test "peer type resolution: [0]u8 and []const u8" {
1367 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1368 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1369 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1370
1371 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
1372 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
1373 comptime {
1374 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
1375 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
1376 }
1377}
1378fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
1379 if (a) {
1380 return &[_]u8{};
1381 }
1382
1383 return slice[0..1];
1384}
1385
1386test "implicitly cast from [N]T to ?[]const T" {
1387 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1388 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1389 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1390
1391 try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
1392 comptime assert(mem.eql(u8, castToOptionalSlice().?, "hi"));
1393}
1394
1395fn castToOptionalSlice() ?[]const u8 {
1396 return "hi";
1397}
1398
1399test "cast u128 to f128 and back" {
1400 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1401 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1402 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1403 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1404
1405 try comptime testCast128();
1406 try testCast128();
1407}
1408
1409fn testCast128() !void {
1410 try expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
1411}
1412
1413fn cast128Int(x: f128) u128 {
1414 return @as(u128, @bitCast(x));
1415}
1416
1417fn cast128Float(x: u128) f128 {
1418 return @as(f128, @bitCast(x));
1419}
1420
1421test "implicit cast from *[N]T to ?[*]T" {
1422 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1423 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1424 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1425 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1426
1427 var x: ?[*]u16 = null;
1428 var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
1429
1430 x = &y;
1431 try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
1432 x.?[0] = 8;
1433 y[3] = 6;
1434 try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
1435}
1436
1437test "implicit cast from *T to ?*anyopaque" {
1438 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1439 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1440 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1441
1442 var a: u8 = 1;
1443 incrementVoidPtrValue(&a);
1444 try std.testing.expect(a == 2);
1445}
1446
1447fn incrementVoidPtrValue(value: ?*anyopaque) void {
1448 @as(*u8, @ptrCast(value.?)).* += 1;
1449}
1450
1451test "implicit cast *[0]T to E![]const u8" {
1452 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1453
1454 var x = @as(anyerror![]const u8, &[0]u8{});
1455 _ = &x;
1456 try expect((x catch unreachable).len == 0);
1457}
1458
1459var global_array: [4]u8 = undefined;
1460test "cast from array reference to fn: comptime fn ptr" {
1461 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1462
1463 const f = @as(*align(1) const fn () callconv(.c) void, @ptrCast(&global_array));
1464 try expect(@intFromPtr(f) == @intFromPtr(&global_array));
1465}
1466test "cast from array reference to fn: runtime fn ptr" {
1467 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1468
1469 var f = @as(*align(1) const fn () callconv(.c) void, @ptrCast(&global_array));
1470 _ = &f;
1471 try expect(@intFromPtr(f) == @intFromPtr(&global_array));
1472}
1473
1474test "*const [N]null u8 to ?[]const u8" {
1475 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1477 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1478
1479 const S = struct {
1480 fn doTheTest() !void {
1481 var a = "Hello";
1482 _ = &a;
1483 const b: ?[]const u8 = a;
1484 try expect(mem.eql(u8, b.?, "Hello"));
1485 }
1486 };
1487 try S.doTheTest();
1488 try comptime S.doTheTest();
1489}
1490
1491test "cast between [*c]T and ?[*:0]T on fn parameter" {
1492 const S = struct {
1493 const Handler = ?fn ([*c]const u8) callconv(.c) void;
1494 fn addCallback(comptime handler: Handler) void {
1495 _ = handler;
1496 }
1497
1498 fn myCallback(cstr: ?[*:0]const u8) callconv(.c) void {
1499 _ = cstr;
1500 }
1501
1502 fn doTheTest() void {
1503 addCallback(myCallback);
1504 }
1505 };
1506 S.doTheTest();
1507}
1508
1509var global_struct: struct { f0: usize } = undefined;
1510test "assignment to optional pointer result loc" {
1511 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1512 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1513 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1514
1515 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
1516 _ = &foo;
1517 try expect(foo.ptr.? == @as(*anyopaque, @ptrCast(&global_struct)));
1518}
1519
1520test "cast between *[N]void and []void" {
1521 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1522
1523 var a: [4]void = undefined;
1524 const b: []void = &a;
1525 try expect(b.len == 4);
1526}
1527
1528test "peer resolve arrays of different size to const slice" {
1529 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1530 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1531
1532 try expect(mem.eql(u8, boolToStr(true), "true"));
1533 try expect(mem.eql(u8, boolToStr(false), "false"));
1534 comptime assert(mem.eql(u8, boolToStr(true), "true"));
1535 comptime assert(mem.eql(u8, boolToStr(false), "false"));
1536}
1537fn boolToStr(b: bool) []const u8 {
1538 return if (b) "true" else "false";
1539}
1540
1541test "cast f16 to wider types" {
1542 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1543 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1544 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1545 if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1546 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1547
1548 const S = struct {
1549 fn doTheTest() !void {
1550 var x: f16 = 1234.0;
1551 _ = &x;
1552 try expect(@as(f32, 1234.0) == x);
1553 try expect(@as(f64, 1234.0) == x);
1554 try expect(@as(f128, 1234.0) == x);
1555 }
1556 };
1557 try S.doTheTest();
1558 try comptime S.doTheTest();
1559}
1560
1561test "cast f128 to narrower types" {
1562 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1563 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1564 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1565 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1566
1567 const S = struct {
1568 fn doTheTest() !void {
1569 var x: f128 = 1234.0;
1570 _ = &x;
1571 try expect(@as(f16, 1234.0) == @as(f16, @floatCast(x)));
1572 try expect(@as(f32, 1234.0) == @as(f32, @floatCast(x)));
1573 try expect(@as(f64, 1234.0) == @as(f64, @floatCast(x)));
1574 }
1575 };
1576 try S.doTheTest();
1577 try comptime S.doTheTest();
1578}
1579
1580test "peer type resolution: unreachable, null, slice" {
1581 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1582 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1583 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1584
1585 const S = struct {
1586 fn doTheTest(num: usize, word: []const u8) !void {
1587 const result = switch (num) {
1588 0 => null,
1589 1 => word,
1590 else => unreachable,
1591 };
1592 try expect(mem.eql(u8, result.?, "hi"));
1593 }
1594 };
1595 try S.doTheTest(1, "hi");
1596}
1597
1598test "cast i8 fn call peers to i32 result" {
1599 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1600
1601 const S = struct {
1602 fn doTheTest() !void {
1603 var cond = true;
1604 _ = &cond;
1605 const value: i32 = if (cond) smallBoi() else bigBoi();
1606 try expect(value == 123);
1607 }
1608 fn smallBoi() i8 {
1609 return 123;
1610 }
1611 fn bigBoi() i16 {
1612 return 1234;
1613 }
1614 };
1615 try S.doTheTest();
1616 try comptime S.doTheTest();
1617}
1618
1619test "cast compatible optional types" {
1620 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1621 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1622 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1623
1624 var a: ?[:0]const u8 = null;
1625 _ = &a;
1626 const b: ?[]const u8 = a;
1627 try expect(b == null);
1628}
1629
1630test "coerce undefined single-item pointer of array to error union of slice" {
1631 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1632
1633 const a = @as([*]u8, undefined)[0..0];
1634 var b: error{a}![]const u8 = a;
1635 _ = &b;
1636 const s = try b;
1637 try expect(s.len == 0);
1638}
1639
1640test "pointer to empty struct literal to mutable slice" {
1641 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1642
1643 var x: []i32 = &.{};
1644 _ = &x;
1645 try expect(x.len == 0);
1646}
1647
1648test "coerce between pointers of compatible differently-named floats" {
1649 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1650 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows and !builtin.link_libc) return error.SkipZigTest;
1651 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1652 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1653 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1654
1655 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
1656 // https://github.com/ziglang/zig/issues/12396
1657 return error.SkipZigTest;
1658 }
1659
1660 const F = switch (@typeInfo(c_longdouble).float.bits) {
1661 16 => f16,
1662 32 => f32,
1663 64 => f64,
1664 80 => f80,
1665 128 => f128,
1666 else => @compileError("unreachable"),
1667 };
1668 var f1: F = 12.34;
1669 const f2: *c_longdouble = &f1;
1670 f2.* += 1;
1671 try expect(f1 == @as(F, 12.34) + 1);
1672}
1673
1674test "peer type resolution of const and non-const pointer to array" {
1675 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1676
1677 const a = @as(*[1024]u8, @ptrFromInt(42));
1678 const b = @as(*const [1024]u8, @ptrFromInt(42));
1679 try std.testing.expect(@TypeOf(a, b) == *const [1024]u8);
1680 try std.testing.expect(a == b);
1681}
1682
1683test "intFromFloat to zero-bit int" {
1684 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1685 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1686
1687 const a: f32 = 0.0;
1688 try comptime std.testing.expect(@as(u0, @intFromFloat(a)) == 0);
1689}
1690
1691test "peer type resolution of function pointer and function body" {
1692 const T = fn () u32;
1693 const a: T = undefined;
1694 const b: *const T = undefined;
1695 try expect(@TypeOf(a, b) == *const fn () u32);
1696 try expect(@TypeOf(b, a) == *const fn () u32);
1697}
1698
1699test "cast typed undefined to int" {
1700 comptime {
1701 const a: u16 = undefined;
1702 const b: u8 = a;
1703 _ = b;
1704 }
1705}
1706
1707// test "implicit cast from [:0]T to [*c]T" {
1708// var a: [:0]const u8 = "foo";
1709// _ = &a;
1710// const b: [*c]const u8 = a;
1711// const c = std.mem.span(b);
1712// try expect(c.len == a.len);
1713// try expect(c.ptr == a.ptr);
1714// }
1715
1716test "bitcast packed struct with u0" {
1717 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1718
1719 const S = packed struct(u2) { a: u0, b: u2 };
1720 const s = @as(S, @bitCast(@as(u2, 2)));
1721 try expect(s.a == 0);
1722 try expect(s.b == 2);
1723 const i = @as(u2, @bitCast(s));
1724 try expect(i == 2);
1725}
1726
1727test "optional pointer coerced to optional allowzero pointer" {
1728 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1729 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1730
1731 var p: ?*u32 = undefined;
1732 var q: ?*allowzero u32 = undefined;
1733 p = @as(*u32, @ptrFromInt(4));
1734 q = p;
1735 try expect(@intFromPtr(q.?) == 4);
1736}
1737
1738test "optional slice coerced to allowzero many pointer" {
1739 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1740
1741 const a: ?[]const u32 = null;
1742 const b: [*]allowzero const u8 = @ptrCast(a);
1743 const c = @intFromPtr(b);
1744 try std.testing.expect(c == 0);
1745}
1746
1747test "optional slice passed as parameter coerced to allowzero many pointer" {
1748 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1749
1750 const ns = struct {
1751 const Color = struct {
1752 r: u8,
1753 g: u8,
1754 b: u8,
1755 a: u8,
1756 };
1757
1758 fn foo(pixels: ?[]const Color) !void {
1759 const data: [*]allowzero const u8 = @ptrCast(pixels);
1760 const int = @intFromPtr(data);
1761 try std.testing.expect(int == 0);
1762 }
1763 };
1764
1765 try ns.foo(null);
1766}
1767
1768test "single item pointer to pointer to array to slice" {
1769 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1770
1771 var x: i32 = 1234;
1772 try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234);
1773 const z1 = @as([]const i32, @as(*[1]i32, &x));
1774 try expect(z1[0] == 1234);
1775}
1776
1777test "peer type resolution forms error union" {
1778 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1779 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1780
1781 var foo: i32 = 123;
1782 _ = &foo;
1783 const result = if (foo < 0) switch (-foo) {
1784 0 => unreachable,
1785 42 => error.AccessDenied,
1786 else => unreachable,
1787 } else @as(u32, @intCast(foo));
1788 try expect(try result == 123);
1789}
1790
1791test "@constCast without a result location" {
1792 const x: i32 = 1234;
1793 const y = @constCast(&x);
1794 try expect(@TypeOf(y) == *i32);
1795 try expect(y.* == 1234);
1796}
1797
1798test "@constCast optional" {
1799 const x: u8 = 10;
1800 const m: ?*const u8 = &x;
1801 const p = @constCast(m);
1802 try expect(@TypeOf(p) == ?*u8);
1803}
1804
1805test "@volatileCast without a result location" {
1806 var x: i32 = 1234;
1807 const y: *volatile i32 = &x;
1808 const z = @volatileCast(y);
1809 try expect(@TypeOf(z) == *i32);
1810 try expect(z.* == 1234);
1811}
1812
1813test "coercion from single-item pointer to @as to slice" {
1814 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1815
1816 var x: u32 = 1;
1817
1818 // Why the following line gets a compile error?
1819 const t: []u32 = @as(*[1]u32, &x);
1820
1821 try expect(t[0] == 1);
1822}
1823
1824test "peer type resolution: const sentinel slice and mutable non-sentinel slice" {
1825 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1826 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1827 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1828
1829 const S = struct {
1830 fn doTheTest(comptime T: type, comptime s: T) !void {
1831 var a: [:s]const T = @as(*const [2:s]T, @ptrFromInt(0x1000));
1832 var b: []T = @as(*[3]T, @ptrFromInt(0x2000));
1833 _ = .{ &a, &b };
1834 comptime assert(@TypeOf(a, b) == []const T);
1835 comptime assert(@TypeOf(b, a) == []const T);
1836
1837 var t = true;
1838 _ = &t;
1839 const r1 = if (t) a else b;
1840 const r2 = if (t) b else a;
1841
1842 const R = @TypeOf(r1);
1843
1844 try expectEqual(@as(R, @as(*const [2:s]T, @ptrFromInt(0x1000))), r1);
1845 try expectEqual(@as(R, @as(*const [3]T, @ptrFromInt(0x2000))), r2);
1846 }
1847 };
1848
1849 try S.doTheTest(u8, 0);
1850 try S.doTheTest(?*anyopaque, null);
1851}
1852
1853test "peer type resolution: float and comptime-known fixed-width integer" {
1854 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1855 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1856
1857 const i: u8 = 100;
1858 var f: f32 = 1.234;
1859 _ = &f;
1860 comptime assert(@TypeOf(i, f) == f32);
1861 comptime assert(@TypeOf(f, i) == f32);
1862
1863 var t = true;
1864 _ = &t;
1865 const r1 = if (t) i else f;
1866 const r2 = if (t) f else i;
1867
1868 const T = @TypeOf(r1);
1869
1870 try expectEqual(@as(T, 100.0), r1);
1871 try expectEqual(@as(T, 1.234), r2);
1872}
1873
1874test "peer type resolution: same array type with sentinel" {
1875 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1876 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1877 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1878 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1879
1880 var a: [2:0]u32 = .{ 0, 1 };
1881 var b: [2:0]u32 = .{ 2, 3 };
1882 _ = .{ &a, &b };
1883 comptime assert(@TypeOf(a, b) == [2:0]u32);
1884 comptime assert(@TypeOf(b, a) == [2:0]u32);
1885
1886 var t = true;
1887 _ = &t;
1888 const r1 = if (t) a else b;
1889 const r2 = if (t) b else a;
1890
1891 const T = @TypeOf(r1);
1892
1893 try expectEqual(T{ 0, 1 }, r1);
1894 try expectEqual(T{ 2, 3 }, r2);
1895}
1896
1897test "peer type resolution: array with sentinel and array without sentinel" {
1898 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1899 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1900 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1901
1902 var a: [2:0]u32 = .{ 0, 1 };
1903 var b: [2]u32 = .{ 2, 3 };
1904 _ = .{ &a, &b };
1905 comptime assert(@TypeOf(a, b) == [2]u32);
1906 comptime assert(@TypeOf(b, a) == [2]u32);
1907
1908 var t = true;
1909 _ = &t;
1910 const r1 = if (t) a else b;
1911 const r2 = if (t) b else a;
1912
1913 const T = @TypeOf(r1);
1914
1915 try expectEqual(T{ 0, 1 }, r1);
1916 try expectEqual(T{ 2, 3 }, r2);
1917}
1918
1919test "peer type resolution: array and vector with same child type" {
1920 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1921 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1922 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1923 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1924 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1925 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1926
1927 var arr: [2]u32 = .{ 0, 1 };
1928 var vec: @Vector(2, u32) = .{ 2, 3 };
1929 _ = .{ &arr, &vec };
1930 comptime assert(@TypeOf(arr, vec) == @Vector(2, u32));
1931 comptime assert(@TypeOf(vec, arr) == @Vector(2, u32));
1932
1933 var t = true;
1934 _ = &t;
1935 const r1 = if (t) arr else vec;
1936 const r2 = if (t) vec else arr;
1937
1938 const T = @TypeOf(r1);
1939
1940 try expectEqual(T{ 0, 1 }, r1);
1941 try expectEqual(T{ 2, 3 }, r2);
1942}
1943
1944test "peer type resolution: array with smaller child type and vector with larger child type" {
1945 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1946 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1947 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1948 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1949 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1950
1951 var arr: [2]u8 = .{ 0, 1 };
1952 var vec: @Vector(2, u64) = .{ 2, 3 };
1953 _ = .{ &arr, &vec };
1954 comptime assert(@TypeOf(arr, vec) == @Vector(2, u64));
1955 comptime assert(@TypeOf(vec, arr) == @Vector(2, u64));
1956
1957 var t = true;
1958 _ = &t;
1959 const r1 = if (t) arr else vec;
1960 const r2 = if (t) vec else arr;
1961
1962 const T = @TypeOf(r1);
1963
1964 try expectEqual(T{ 0, 1 }, r1);
1965 try expectEqual(T{ 2, 3 }, r2);
1966}
1967
1968test "peer type resolution: error union and optional of same type" {
1969 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1970 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1971 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1972 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1973
1974 const E = error{Foo};
1975 var a: E!*u8 = error.Foo;
1976 var b: ?*u8 = null;
1977 _ = .{ &a, &b };
1978 comptime assert(@TypeOf(a, b) == E!?*u8);
1979 comptime assert(@TypeOf(b, a) == E!?*u8);
1980
1981 var t = true;
1982 _ = &t;
1983 const r1 = if (t) a else b;
1984 const r2 = if (t) b else a;
1985
1986 const T = @TypeOf(r1);
1987
1988 try expectEqual(@as(T, error.Foo), r1);
1989 try expectEqual(@as(T, null), r2);
1990}
1991
1992test "peer type resolution: C pointer and @TypeOf(null)" {
1993 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1994 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1995 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1996
1997 var a: [*c]c_int = 0x1000;
1998 _ = &a;
1999 const b = null;
2000 comptime assert(@TypeOf(a, b) == [*c]c_int);
2001 comptime assert(@TypeOf(b, a) == [*c]c_int);
2002
2003 var t = true;
2004 _ = &t;
2005 const r1 = if (t) a else b;
2006 const r2 = if (t) b else a;
2007
2008 const T = @TypeOf(r1);
2009
2010 try expectEqual(@as(T, 0x1000), r1);
2011 try expectEqual(@as(T, null), r2);
2012}
2013
2014test "peer type resolution: three-way resolution combines error set and optional" {
2015 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2016 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2017 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2018
2019 const E = error{Foo};
2020 var a: E = error.Foo;
2021 var b: *const [5:0]u8 = @ptrFromInt(0x1000);
2022 var c: ?[*:0]u8 = null;
2023 _ = .{ &a, &b, &c };
2024 comptime assert(@TypeOf(a, b, c) == E!?[*:0]const u8);
2025 comptime assert(@TypeOf(a, c, b) == E!?[*:0]const u8);
2026 comptime assert(@TypeOf(b, a, c) == E!?[*:0]const u8);
2027 comptime assert(@TypeOf(b, c, a) == E!?[*:0]const u8);
2028 comptime assert(@TypeOf(c, a, b) == E!?[*:0]const u8);
2029 comptime assert(@TypeOf(c, b, a) == E!?[*:0]const u8);
2030
2031 var x: u8 = 0;
2032 _ = &x;
2033 const r1 = switch (x) {
2034 0 => a,
2035 1 => b,
2036 else => c,
2037 };
2038 const r2 = switch (x) {
2039 0 => b,
2040 1 => a,
2041 else => c,
2042 };
2043 const r3 = switch (x) {
2044 0 => c,
2045 1 => a,
2046 else => b,
2047 };
2048
2049 const T = @TypeOf(r1);
2050
2051 try expectEqual(@as(T, error.Foo), r1);
2052 try expectEqual(@as(T, @as([*:0]u8, @ptrFromInt(0x1000))), r2);
2053 try expectEqual(@as(T, null), r3);
2054}
2055
2056test "peer type resolution: vector and optional vector" {
2057 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2058 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2059 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2060 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2061 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
2062 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
2063
2064 var a: ?@Vector(3, u32) = .{ 0, 1, 2 };
2065 var b: @Vector(3, u32) = .{ 3, 4, 5 };
2066 _ = .{ &a, &b };
2067 comptime assert(@TypeOf(a, b) == ?@Vector(3, u32));
2068 comptime assert(@TypeOf(b, a) == ?@Vector(3, u32));
2069
2070 var t = true;
2071 _ = &t;
2072 const r1 = if (t) a else b;
2073 const r2 = if (t) b else a;
2074
2075 const T = @TypeOf(r1);
2076
2077 try expectEqual(@as(T, .{ 0, 1, 2 }), r1);
2078 try expectEqual(@as(T, .{ 3, 4, 5 }), r2);
2079}
2080
2081test "peer type resolution: optional fixed-width int and comptime_int" {
2082 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2083 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2084
2085 var a: ?i32 = 42;
2086 _ = &a;
2087 const b: comptime_int = 50;
2088 comptime assert(@TypeOf(a, b) == ?i32);
2089 comptime assert(@TypeOf(b, a) == ?i32);
2090
2091 var t = true;
2092 _ = &t;
2093 const r1 = if (t) a else b;
2094 const r2 = if (t) b else a;
2095
2096 const T = @TypeOf(r1);
2097
2098 try expectEqual(@as(T, 42), r1);
2099 try expectEqual(@as(T, 50), r2);
2100}
2101
2102test "peer type resolution: array and tuple" {
2103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2104 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2105 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2106 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2107
2108 var arr: [3]i32 = .{ 1, 2, 3 };
2109 _ = &arr;
2110 const tup = .{ 4, 5, 6 };
2111
2112 comptime assert(@TypeOf(arr, tup) == [3]i32);
2113 comptime assert(@TypeOf(tup, arr) == [3]i32);
2114
2115 var t = true;
2116 _ = &t;
2117 const r1 = if (t) arr else tup;
2118 const r2 = if (t) tup else arr;
2119
2120 const T = @TypeOf(r1);
2121
2122 try expectEqual(T{ 1, 2, 3 }, r1);
2123 try expectEqual(T{ 4, 5, 6 }, r2);
2124}
2125
2126test "peer type resolution: vector and tuple" {
2127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2129 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2130 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2131
2132 var vec: @Vector(3, i32) = .{ 1, 2, 3 };
2133 _ = &vec;
2134 const tup = .{ 4, 5, 6 };
2135
2136 comptime assert(@TypeOf(vec, tup) == @Vector(3, i32));
2137 comptime assert(@TypeOf(tup, vec) == @Vector(3, i32));
2138
2139 var t = true;
2140 _ = &t;
2141 const r1 = if (t) vec else tup;
2142 const r2 = if (t) tup else vec;
2143
2144 const T = @TypeOf(r1);
2145
2146 try expectEqual(T{ 1, 2, 3 }, r1);
2147 try expectEqual(T{ 4, 5, 6 }, r2);
2148}
2149
2150test "peer type resolution: vector and array and tuple" {
2151 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2152 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2153 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2154 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2155 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2156
2157 var vec: @Vector(2, i8) = .{ 10, 20 };
2158 var arr: [2]i8 = .{ 30, 40 };
2159 _ = .{ &vec, &arr };
2160 const tup = .{ 50, 60 };
2161
2162 comptime assert(@TypeOf(vec, arr, tup) == @Vector(2, i8));
2163 comptime assert(@TypeOf(vec, tup, arr) == @Vector(2, i8));
2164 comptime assert(@TypeOf(arr, vec, tup) == @Vector(2, i8));
2165 comptime assert(@TypeOf(arr, tup, vec) == @Vector(2, i8));
2166 comptime assert(@TypeOf(tup, vec, arr) == @Vector(2, i8));
2167 comptime assert(@TypeOf(tup, arr, vec) == @Vector(2, i8));
2168
2169 var x: u8 = 0;
2170 _ = &x;
2171 const r1 = switch (x) {
2172 0 => vec,
2173 1 => arr,
2174 else => tup,
2175 };
2176 const r2 = switch (x) {
2177 0 => arr,
2178 1 => vec,
2179 else => tup,
2180 };
2181 const r3 = switch (x) {
2182 0 => tup,
2183 1 => vec,
2184 else => arr,
2185 };
2186
2187 const T = @TypeOf(r1);
2188
2189 try expectEqual(T{ 10, 20 }, r1);
2190 try expectEqual(T{ 30, 40 }, r2);
2191 try expectEqual(T{ 50, 60 }, r3);
2192}
2193
2194test "peer type resolution: empty tuple pointer and slice" {
2195 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2196 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2197 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2198
2199 var a: [:0]const u8 = "Hello";
2200 var b = &.{};
2201 _ = .{ &a, &b };
2202
2203 comptime assert(@TypeOf(a, b) == []const u8);
2204 comptime assert(@TypeOf(b, a) == []const u8);
2205
2206 var t = true;
2207 _ = &t;
2208 const r1 = if (t) a else b;
2209 const r2 = if (t) b else a;
2210
2211 try expectEqualSlices(u8, "Hello", r1);
2212 try expectEqualSlices(u8, "", r2);
2213}
2214
2215test "peer type resolution: tuple pointer and slice" {
2216 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2217 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2218 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2219
2220 var a: [:0]const u8 = "Hello";
2221 var b = &.{ @as(u8, 'x'), @as(u8, 'y'), @as(u8, 'z') };
2222 _ = .{ &a, &b };
2223
2224 comptime assert(@TypeOf(a, b) == []const u8);
2225 comptime assert(@TypeOf(b, a) == []const u8);
2226
2227 var t = true;
2228 _ = &t;
2229 const r1 = if (t) a else b;
2230 const r2 = if (t) b else a;
2231
2232 try expectEqualSlices(u8, "Hello", r1);
2233 try expectEqualSlices(u8, "xyz", r2);
2234}
2235
2236test "peer type resolution: tuple pointer and optional slice" {
2237 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2238 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2239 // Miscompilation on Intel's OpenCL CPU runtime.
2240 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // flaky
2241
2242 var a: ?[:0]const u8 = null;
2243 var b = &.{ @as(u8, 'x'), @as(u8, 'y'), @as(u8, 'z') };
2244 _ = .{ &a, &b };
2245
2246 comptime assert(@TypeOf(a, b) == ?[]const u8);
2247 comptime assert(@TypeOf(b, a) == ?[]const u8);
2248
2249 var t = true;
2250 _ = &t;
2251 const r1 = if (t) a else b;
2252 const r2 = if (t) b else a;
2253
2254 try expectEqual(@as(?[]const u8, null), r1);
2255 try expectEqualSlices(u8, "xyz", r2 orelse "");
2256}
2257
2258test "peer type resolution: many compatible pointers" {
2259 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2260 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2261 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2262
2263 var buf = "foo-3".*;
2264
2265 var vals = .{
2266 @as([*]const u8, "foo-0"),
2267 @as([*:0]const u8, "foo-1"),
2268 @as([*:0]const u8, "foo-2"),
2269 @as([*]u8, &buf),
2270 @as(*const [5]u8, "foo-4"),
2271 };
2272 _ = &vals;
2273
2274 // Check every possible permutation of types in @TypeOf
2275 @setEvalBranchQuota(5000);
2276 comptime var perms = 0; // check the loop is hitting every permutation
2277 inline for (0..5) |i_0| {
2278 inline for (0..5) |i_1| {
2279 if (i_1 == i_0) continue;
2280 inline for (0..5) |i_2| {
2281 if (i_2 == i_0 or i_2 == i_1) continue;
2282 inline for (0..5) |i_3| {
2283 if (i_3 == i_0 or i_3 == i_1 or i_3 == i_2) continue;
2284 inline for (0..5) |i_4| {
2285 if (i_4 == i_0 or i_4 == i_1 or i_4 == i_2 or i_4 == i_3) continue;
2286 perms += 1;
2287 comptime assert(@TypeOf(
2288 vals[i_0],
2289 vals[i_1],
2290 vals[i_2],
2291 vals[i_3],
2292 vals[i_4],
2293 ) == [*]const u8);
2294 }
2295 }
2296 }
2297 }
2298 }
2299 comptime assert(perms == 5 * 4 * 3 * 2 * 1);
2300
2301 var x: u8 = 0;
2302 _ = &x;
2303 inline for (0..5) |i| {
2304 const r = switch (x) {
2305 0 => vals[i],
2306 1 => vals[0],
2307 2 => vals[1],
2308 3 => vals[2],
2309 4 => vals[3],
2310 else => vals[4],
2311 };
2312 const expected = switch (i) {
2313 0 => "foo-0",
2314 1 => "foo-1",
2315 2 => "foo-2",
2316 3 => "foo-3",
2317 4 => "foo-4",
2318 else => unreachable,
2319 };
2320 try expectEqualSlices(u8, expected, std.mem.span(@as([*:0]const u8, @ptrCast(r))));
2321 }
2322}
2323
2324test "peer type resolution: tuples with comptime fields" {
2325 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2326 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2327 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
2328
2329 const a = .{ 1, 2 };
2330 const b = .{ @as(u32, 3), @as(i16, 4) };
2331
2332 // TODO: tuple type equality doesn't work properly yet
2333 const ti1 = @typeInfo(@TypeOf(a, b));
2334 const ti2 = @typeInfo(@TypeOf(b, a));
2335 inline for (.{ ti1, ti2 }) |ti| {
2336 const s = ti.@"struct";
2337 comptime assert(s.is_tuple);
2338 comptime assert(s.fields.len == 2);
2339 comptime assert(s.fields[0].type == u32);
2340 comptime assert(s.fields[1].type == i16);
2341 }
2342
2343 var t = true;
2344 _ = &t;
2345 const r1 = if (t) a else b;
2346 const r2 = if (t) b else a;
2347
2348 try expectEqual(@as(u32, 1), r1[0]);
2349 try expectEqual(@as(i16, 2), r1[1]);
2350
2351 try expectEqual(@as(u32, 3), r2[0]);
2352 try expectEqual(@as(i16, 4), r2[1]);
2353}
2354
2355test "peer type resolution: C pointer and many pointer" {
2356 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2357 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2358 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2359
2360 var buf = "hello".*;
2361
2362 const a: [*c]u8 = &buf;
2363 var b: [*:0]const u8 = "world";
2364 _ = &b;
2365
2366 comptime assert(@TypeOf(a, b) == [*c]const u8);
2367 comptime assert(@TypeOf(b, a) == [*c]const u8);
2368
2369 var t = true;
2370 _ = &t;
2371 const r1 = if (t) a else b;
2372 const r2 = if (t) b else a;
2373
2374 try expectEqual(r1, a);
2375 try expectEqual(r2, b);
2376}
2377
2378test "peer type resolution: pointer attributes are combined correctly" {
2379 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2381 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2382
2383 var buf_a align(4) = "foo".*;
2384 var buf_b align(4) = "bar".*;
2385 var buf_c align(4) = "baz".*;
2386 var buf_d align(4) = "qux".*;
2387
2388 const a: [*:0]align(4) const u8 = &buf_a;
2389 const b: *align(2) volatile [3:0]u8 = &buf_b;
2390 const c: [*:0]align(4) u8 = &buf_c;
2391 const d: [*:0]allowzero align(4) u8 = &buf_d;
2392
2393 comptime assert(@TypeOf(a, b, c, d) == [*:0]allowzero align(2) const volatile u8);
2394 comptime assert(@TypeOf(a, b, d, c) == [*:0]allowzero align(2) const volatile u8);
2395 comptime assert(@TypeOf(a, c, b, d) == [*:0]allowzero align(2) const volatile u8);
2396 comptime assert(@TypeOf(a, c, d, b) == [*:0]allowzero align(2) const volatile u8);
2397 comptime assert(@TypeOf(a, d, b, c) == [*:0]allowzero align(2) const volatile u8);
2398 comptime assert(@TypeOf(a, d, c, b) == [*:0]allowzero align(2) const volatile u8);
2399
2400 comptime assert(@TypeOf(b, a, c, d) == [*:0]allowzero align(2) const volatile u8);
2401 comptime assert(@TypeOf(b, a, d, c) == [*:0]allowzero align(2) const volatile u8);
2402 comptime assert(@TypeOf(b, c, a, d) == [*:0]allowzero align(2) const volatile u8);
2403 comptime assert(@TypeOf(b, c, d, a) == [*:0]allowzero align(2) const volatile u8);
2404 comptime assert(@TypeOf(b, d, c, a) == [*:0]allowzero align(2) const volatile u8);
2405 comptime assert(@TypeOf(b, d, a, c) == [*:0]allowzero align(2) const volatile u8);
2406
2407 comptime assert(@TypeOf(c, a, b, d) == [*:0]allowzero align(2) const volatile u8);
2408 comptime assert(@TypeOf(c, a, d, b) == [*:0]allowzero align(2) const volatile u8);
2409 comptime assert(@TypeOf(c, b, a, d) == [*:0]allowzero align(2) const volatile u8);
2410 comptime assert(@TypeOf(c, b, d, a) == [*:0]allowzero align(2) const volatile u8);
2411 comptime assert(@TypeOf(c, d, b, a) == [*:0]allowzero align(2) const volatile u8);
2412 comptime assert(@TypeOf(c, d, a, b) == [*:0]allowzero align(2) const volatile u8);
2413
2414 comptime assert(@TypeOf(d, a, b, c) == [*:0]allowzero align(2) const volatile u8);
2415 comptime assert(@TypeOf(d, a, c, b) == [*:0]allowzero align(2) const volatile u8);
2416 comptime assert(@TypeOf(d, b, a, c) == [*:0]allowzero align(2) const volatile u8);
2417 comptime assert(@TypeOf(d, b, c, a) == [*:0]allowzero align(2) const volatile u8);
2418 comptime assert(@TypeOf(d, c, b, a) == [*:0]allowzero align(2) const volatile u8);
2419 comptime assert(@TypeOf(d, c, a, b) == [*:0]allowzero align(2) const volatile u8);
2420
2421 var x: u8 = 0;
2422 _ = &x;
2423 const r1 = switch (x) {
2424 0 => a,
2425 1 => b,
2426 2 => c,
2427 else => d,
2428 };
2429 const r2 = switch (x) {
2430 0 => b,
2431 1 => a,
2432 2 => c,
2433 else => d,
2434 };
2435 const r3 = switch (x) {
2436 0 => c,
2437 1 => a,
2438 2 => b,
2439 else => d,
2440 };
2441 const r4 = switch (x) {
2442 0 => d,
2443 1 => a,
2444 2 => b,
2445 else => c,
2446 };
2447
2448 const NonAllowZero = comptime blk: {
2449 const ptr = @typeInfo(@TypeOf(r1, r2, r3, r4)).pointer;
2450 break :blk @Pointer(ptr.size, .{
2451 .@"const" = ptr.is_const,
2452 .@"volatile" = ptr.is_volatile,
2453 .@"allowzero" = false,
2454 .@"align" = ptr.alignment,
2455 .@"addrspace" = ptr.address_space,
2456 }, ptr.child, ptr.sentinel());
2457 };
2458 try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r1)))), "foo");
2459 try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r2)))), "bar");
2460 try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r3)))), "baz");
2461 try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r4)))), "qux");
2462}
2463
2464test "peer type resolution: arrays of compatible types" {
2465 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2466 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2467 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2468 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2469
2470 var e0: u8 = 3;
2471 var e1: u8 = 2;
2472 var e2: u8 = 1;
2473 const a = [3]*u8{ &e0, &e1, &e2 };
2474 const b = [3]*const u8{ &e0, &e1, &e2 };
2475
2476 comptime assert(@TypeOf(a, b) == [3]*const u8);
2477 comptime assert(@TypeOf(b, a) == [3]*const u8);
2478
2479 try expectEqual(@as(@TypeOf(a, b), a), b);
2480}
2481
2482test "cast builtins can wrap result in optional" {
2483 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2484 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2485 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2486
2487 const S = struct {
2488 const MyEnum = enum(u32) { _ };
2489 fn a() ?MyEnum {
2490 return @enumFromInt(123);
2491 }
2492 fn b() ?u32 {
2493 return @intFromFloat(42.50);
2494 }
2495 fn c() ?*const f32 {
2496 const x: u32 = 1;
2497 return @ptrCast(&x);
2498 }
2499
2500 fn doTheTest() !void {
2501 const ra = a() orelse return error.ImpossibleError;
2502 const rb = b() orelse return error.ImpossibleError;
2503 const rc = c() orelse return error.ImpossibleError;
2504
2505 comptime assert(@TypeOf(ra) == MyEnum);
2506 comptime assert(@TypeOf(rb) == u32);
2507 comptime assert(@TypeOf(rc) == *const f32);
2508
2509 try expect(@intFromEnum(ra) == 123);
2510 try expect(rb == 42);
2511 try expect(@as(*const u32, @ptrCast(rc)).* == 1);
2512 }
2513 };
2514
2515 try S.doTheTest();
2516 try comptime S.doTheTest();
2517}
2518
2519test "cast builtins can wrap result in error union" {
2520 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2521 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2522
2523 const S = struct {
2524 const MyEnum = enum(u32) { _ };
2525 const E = error{ImpossibleError};
2526 fn a() E!MyEnum {
2527 return @enumFromInt(123);
2528 }
2529 fn b() E!u32 {
2530 return @intFromFloat(42.50);
2531 }
2532 fn c() E!*const f32 {
2533 const x: u32 = 1;
2534 return @ptrCast(&x);
2535 }
2536
2537 fn doTheTest() !void {
2538 const ra = try a();
2539 const rb = try b();
2540 const rc = try c();
2541
2542 comptime assert(@TypeOf(ra) == MyEnum);
2543 comptime assert(@TypeOf(rb) == u32);
2544 comptime assert(@TypeOf(rc) == *const f32);
2545
2546 try expect(@intFromEnum(ra) == 123);
2547 try expect(rb == 42);
2548 try expect(@as(*const u32, @ptrCast(rc)).* == 1);
2549 }
2550 };
2551
2552 try S.doTheTest();
2553 try comptime S.doTheTest();
2554}
2555
2556test "cast builtins can wrap result in error union and optional" {
2557 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2558 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2559 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2560
2561 const S = struct {
2562 const MyEnum = enum(u32) { _ };
2563 const E = error{ImpossibleError};
2564 fn a() E!?MyEnum {
2565 return @enumFromInt(123);
2566 }
2567 fn b() E!?u32 {
2568 return @intFromFloat(42.50);
2569 }
2570 fn c() E!?*const f32 {
2571 const x: u32 = 1;
2572 return @ptrCast(&x);
2573 }
2574
2575 fn doTheTest() !void {
2576 const ra = try a() orelse return error.ImpossibleError;
2577 const rb = try b() orelse return error.ImpossibleError;
2578 const rc = try c() orelse return error.ImpossibleError;
2579
2580 comptime assert(@TypeOf(ra) == MyEnum);
2581 comptime assert(@TypeOf(rb) == u32);
2582 comptime assert(@TypeOf(rc) == *const f32);
2583
2584 try expect(@intFromEnum(ra) == 123);
2585 try expect(rb == 42);
2586 try expect(@as(*const u32, @ptrCast(rc)).* == 1);
2587 }
2588 };
2589
2590 try S.doTheTest();
2591 try comptime S.doTheTest();
2592}
2593
2594test "@floatCast on vector" {
2595 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2596 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2597 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2598 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2599 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2600
2601 const S = struct {
2602 fn doTheTest() !void {
2603 {
2604 var a: @Vector(2, f64) = .{ 1.5, 2.5 };
2605 _ = &a;
2606 const b: @Vector(2, f32) = @floatCast(a);
2607 try expectEqual(@Vector(2, f32){ 1.5, 2.5 }, b);
2608 }
2609 {
2610 var a: @Vector(2, f32) = .{ 3.25, 4.25 };
2611 _ = &a;
2612 const b: @Vector(2, f64) = @floatCast(a);
2613 try expectEqual(@Vector(2, f64){ 3.25, 4.25 }, b);
2614 }
2615 {
2616 var a: @Vector(2, f32) = .{ 5.75, 6.75 };
2617 _ = &a;
2618 const b: @Vector(2, f64) = a;
2619 try expectEqual(@Vector(2, f64){ 5.75, 6.75 }, b);
2620 }
2621 {
2622 var vec: @Vector(2, f32) = @splat(1234.0);
2623 _ = &vec;
2624 const wider: @Vector(2, f64) = vec;
2625 try expect(wider[0] == 1234.0);
2626 try expect(wider[1] == 1234.0);
2627 }
2628 }
2629 };
2630
2631 try S.doTheTest();
2632 try comptime S.doTheTest();
2633}
2634
2635test "@ptrFromInt on vector" {
2636 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2637 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2638 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2639 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2640 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2641 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2642
2643 const S = struct {
2644 fn doTheTest() !void {
2645 var a: @Vector(3, usize) = .{ 0x1000, 0x2000, 0x3000 };
2646 _ = &a;
2647 const b: @Vector(3, *anyopaque) = @ptrFromInt(a);
2648 try expectEqual(@Vector(3, *anyopaque){
2649 @ptrFromInt(0x1000),
2650 @ptrFromInt(0x2000),
2651 @ptrFromInt(0x3000),
2652 }, b);
2653 }
2654 };
2655
2656 try S.doTheTest();
2657 try comptime S.doTheTest();
2658}
2659
2660test "@intFromPtr on vector" {
2661 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2662 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2663 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2664 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2665 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2666 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2667
2668 const S = struct {
2669 fn doTheTest() !void {
2670 var a: @Vector(3, *anyopaque) = .{
2671 @ptrFromInt(0x1000),
2672 @ptrFromInt(0x2000),
2673 @ptrFromInt(0x3000),
2674 };
2675 _ = &a;
2676 const b: @Vector(3, usize) = @intFromPtr(a);
2677 try expectEqual(@Vector(3, usize){ 0x1000, 0x2000, 0x3000 }, b);
2678 }
2679 };
2680
2681 try S.doTheTest();
2682 try comptime S.doTheTest();
2683}
2684
2685test "@floatFromInt on vector" {
2686 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2687 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2688 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2689 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2690 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2691
2692 const S = struct {
2693 fn doTheTest() !void {
2694 var a: @Vector(3, u32) = .{ 10, 20, 30 };
2695 _ = &a;
2696 const b: @Vector(3, f32) = @floatFromInt(a);
2697 try expectEqual(@Vector(3, f32){ 10.0, 20.0, 30.0 }, b);
2698 }
2699 };
2700
2701 try S.doTheTest();
2702 try comptime S.doTheTest();
2703}
2704
2705test "@intFromFloat on vector" {
2706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2707 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2708 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2709 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2710 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2711
2712 const S = struct {
2713 fn doTheTest() !void {
2714 var a: @Vector(3, f32) = .{ 10.3, 20.5, 30.7 };
2715 _ = &a;
2716 const b: @Vector(3, u32) = @intFromFloat(a);
2717 try expectEqual(@Vector(3, u32){ 10, 20, 30 }, b);
2718 }
2719 };
2720
2721 try S.doTheTest();
2722 try comptime S.doTheTest();
2723}
2724
2725test "@intFromBool on vector" {
2726 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2727 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2728 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2729 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2730 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2731
2732 const S = struct {
2733 fn doTheTest() !void {
2734 var a: @Vector(3, bool) = .{ false, true, false };
2735 _ = &a;
2736 const b: @Vector(3, u1) = @intFromBool(a);
2737 try expectEqual(@Vector(3, u1){ 0, 1, 0 }, b);
2738 }
2739 };
2740
2741 try S.doTheTest();
2742 try comptime S.doTheTest();
2743}
2744
2745test "numeric coercions with undefined" {
2746 const from: i32 = undefined;
2747 var to: f32 = from;
2748 to = @floatFromInt(from);
2749 to = 42.0;
2750 try expectEqual(@as(f32, 42.0), to);
2751}
2752
2753test "15-bit int to float" {
2754 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2755
2756 var a: u15 = 42;
2757 _ = &a;
2758 const b: f32 = @floatFromInt(a);
2759 try expect(b == 42.0);
2760}
2761
2762test "@as does not corrupt values with incompatible representations" {
2763 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2764 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2765
2766 const x: f32 = @as(f16, blk: {
2767 if (false) {
2768 // Trick the compiler into trying to use a result pointer if it can!
2769 break :blk .{undefined};
2770 }
2771 break :blk 1.23;
2772 });
2773 try std.testing.expectApproxEqAbs(@as(f32, 1.23), x, 0.001);
2774}
2775
2776test "result information is preserved through many nested structures" {
2777 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2778 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2779 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2780
2781 const S = struct {
2782 fn doTheTest() !void {
2783 const E = error{Foo};
2784 const T = *const ?E!struct { x: ?*const E!?u8 };
2785
2786 var val: T = &.{ .x = &@truncate(0x1234) };
2787 _ = &val;
2788
2789 const struct_val = val.*.? catch unreachable;
2790 const int_val = (struct_val.x.?.* catch unreachable).?;
2791
2792 try expect(int_val == 0x34);
2793 }
2794 };
2795
2796 try S.doTheTest();
2797 try comptime S.doTheTest();
2798}
2799
2800test "@intCast vector of signed integer" {
2801 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2802 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2803 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2804 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2805 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2806 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2807 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
2808
2809 var x: @Vector(4, i32) = .{ 1, 2, 3, 4 };
2810 _ = &x;
2811 const y: @Vector(4, i8) = @intCast(x);
2812
2813 try expect(y[0] == 1);
2814 try expect(y[1] == 2);
2815 try expect(y[2] == 3);
2816 try expect(y[3] == 4);
2817}
2818
2819test "result type is preserved into comptime block" {
2820 const x: u32 = comptime @intCast(123);
2821 try expect(x == 123);
2822}
2823
2824test "bitcast vector" {
2825 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2826
2827 const u8x32 = @Vector(32, u8);
2828 const u32x8 = @Vector(8, u32);
2829
2830 const zerox32: u8x32 = [_]u8{0} ** 32;
2831 const bigsum: u32x8 = @bitCast(zerox32);
2832 try std.testing.expectEqual(0, @reduce(.Add, bigsum));
2833}
2834
2835test "peer type resolution: slice of sentinel-terminated array" {
2836 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2837
2838 var f: bool = undefined;
2839 f = false;
2840
2841 const a: [][2:0]u8 = &.{};
2842 const b: []const [2:0]u8 = &.{.{ 10, 20 }};
2843
2844 const result = if (f) a else b;
2845
2846 comptime assert(@TypeOf(result) == []const [2:0]u8);
2847 try expect(result.len == 1);
2848 try expect(result[0].len == 2);
2849 try expect(result[0][0] == 10);
2850 try expect(result[0][1] == 20);
2851}
2852
2853test "@intFromFloat boundary cases" {
2854 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2855
2856 const S = struct {
2857 fn case(comptime I: type, x: f32, bump: enum { up, down }, expected: I) !void {
2858 const input: f32 = switch (bump) {
2859 .up => std.math.nextAfter(f32, x, std.math.inf(f32)),
2860 .down => std.math.nextAfter(f32, x, -std.math.inf(f32)),
2861 };
2862 const output: I = @intFromFloat(input);
2863 try expect(output == expected);
2864 }
2865 fn doTheTest() !void {
2866 try case(u8, 256.0, .down, 255);
2867 try case(u8, -1.0, .up, 0);
2868 try case(i8, 128.0, .down, 127);
2869 try case(i8, -129.0, .up, -128);
2870
2871 try case(u0, 1.0, .down, 0);
2872 try case(u0, -1.0, .up, 0);
2873 try case(i0, 1.0, .down, 0);
2874 try case(i0, -1.0, .up, 0);
2875
2876 try case(u10, 1024.0, .down, 1023);
2877 try case(u10, -1.0, .up, 0);
2878 try case(i10, 512.0, .down, 511);
2879 try case(i10, -513.0, .up, -512);
2880 }
2881 };
2882 try S.doTheTest();
2883 try comptime S.doTheTest();
2884}
2885
2886test "@intFromFloat vector boundary cases" {
2887 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2888 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2889 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
2890
2891 const S = struct {
2892 fn case(comptime I: type, unshifted_inputs: [2]f32, expected: [2]I) !void {
2893 const inputs: @Vector(2, f32) = .{
2894 std.math.nextAfter(f32, unshifted_inputs[0], std.math.inf(f32)),
2895 std.math.nextAfter(f32, unshifted_inputs[1], -std.math.inf(f32)),
2896 };
2897 const outputs: @Vector(2, I) = @intFromFloat(inputs);
2898 try expect(outputs[0] == expected[0]);
2899 try expect(outputs[1] == expected[1]);
2900 }
2901 fn doTheTest() !void {
2902 try case(u8, .{ -1.0, 256.0 }, .{ 0, 255 });
2903 try case(i8, .{ -129.0, 128.0 }, .{ -128, 127 });
2904
2905 try case(u0, .{ -1.0, 1.0 }, .{ 0, 0 });
2906 try case(i0, .{ -1.0, 1.0 }, .{ 0, 0 });
2907
2908 try case(u10, .{ -1.0, 1024.0 }, .{ 0, 1023 });
2909 try case(i10, .{ -513.0, 512.0 }, .{ -512, 511 });
2910 }
2911 };
2912 try S.doTheTest();
2913 try comptime S.doTheTest();
2914}
2915
2916test "coerce enum to union with zero-bit fields through local variables" {
2917 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2918
2919 const E = enum(u1) { foo, bar };
2920 const U = union(E) { foo, bar };
2921
2922 var runtime: E = undefined;
2923 runtime = .foo;
2924
2925 var result: U = undefined;
2926 result = runtime;
2927
2928 try expect(result == .foo);
2929}