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