1const std = @import("std");
2const assert = std.debug.assert;
3const expect = std.testing.expect;
4const expectError = std.testing.expectError;
5const expectEqual = std.testing.expectEqual;
6const builtin = @import("builtin");
7
8test "switch on error union catch capture" {
9 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11
12 const S = struct {
13 const Error = error{ A, B, C };
14 fn doTheTest() !void {
15 try testScalar();
16 try testMulti();
17 try testElse();
18 try testCapture();
19 try testInline();
20 try testEmptyErrSet();
21 try testUnreachableElseProng();
22 try testErrNotInSet();
23 try testAddressOf();
24 }
25
26 fn testScalar() !void {
27 {
28 var a: Error!u64 = 3;
29 _ = &a;
30 const b: u64 = a catch |err| switch (err) {
31 error.A => 0,
32 error.B => 1,
33 error.C => 2,
34 };
35 try expectEqual(@as(u64, 3), b);
36 }
37 {
38 var a: Error!u64 = 3;
39 _ = &a;
40 const b: u64 = a catch |err| switch (err) {
41 error.A => 0,
42 error.B => @intFromError(err) + 4,
43 error.C => @intFromError(err) + 4,
44 };
45 try expectEqual(@as(u64, 3), b);
46 }
47 {
48 var a: Error!u64 = error.A;
49 _ = &a;
50 const b: u64 = a catch |err| switch (err) {
51 error.A => 0,
52 error.B => @intFromError(err) + 4,
53 error.C => @intFromError(err) + 4,
54 };
55 try expectEqual(@as(u64, 0), b);
56 }
57 }
58
59 fn testMulti() !void {
60 {
61 var a: Error!u64 = 3;
62 _ = &a;
63 const b: u64 = a catch |err| switch (err) {
64 error.A, error.B => 0,
65 error.C => @intFromError(err) + 4,
66 };
67 try expectEqual(@as(u64, 3), b);
68 }
69 {
70 var a: Error!u64 = 3;
71 _ = &a;
72 const b: u64 = a catch |err| switch (err) {
73 error.A => 0,
74 error.B, error.C => @intFromError(err) + 4,
75 };
76 try expectEqual(@as(u64, 3), b);
77 }
78 {
79 var a: Error!u64 = error.A;
80 _ = &a;
81 const b: u64 = a catch |err| switch (err) {
82 error.A, error.B => 0,
83 error.C => @intFromError(err) + 4,
84 };
85 try expectEqual(@as(u64, 0), b);
86 }
87 {
88 var a: Error!u64 = error.A;
89 _ = &a;
90 const b: u64 = a catch |err| switch (err) {
91 error.A => 0,
92 error.B, error.C => @intFromError(err) + 4,
93 };
94 try expectEqual(@as(u64, 0), b);
95 }
96 {
97 var a: Error!u64 = error.B;
98 _ = &a;
99 const b: u64 = a catch |err| switch (err) {
100 error.A => 0,
101 error.B, error.C => @intFromError(err) + 4,
102 };
103 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
104 }
105 }
106
107 fn testElse() !void {
108 {
109 var a: Error!u64 = 3;
110 _ = &a;
111 const b: u64 = a catch |err| switch (err) {
112 error.A => 0,
113 else => 1,
114 };
115 try expectEqual(@as(u64, 3), b);
116 }
117 {
118 var a: Error!u64 = 3;
119 _ = &a;
120 const b: u64 = a catch |err| switch (err) {
121 error.A => 0,
122 else => @intFromError(err) + 4,
123 };
124 try expectEqual(@as(u64, 3), b);
125 }
126 {
127 var a: Error!u64 = error.A;
128 _ = &a;
129 const b: u64 = a catch |err| switch (err) {
130 error.A => 1,
131 else => @intFromError(err) + 4,
132 };
133 try expectEqual(@as(u64, 1), b);
134 }
135 {
136 var a: Error!u64 = error.B;
137 _ = &a;
138 const b: u64 = a catch |err| switch (err) {
139 error.A => 0,
140 else => 1,
141 };
142 try expectEqual(@as(u64, 1), b);
143 }
144 {
145 var a: Error!u64 = error.B;
146 _ = &a;
147 const b: u64 = a catch |err| switch (err) {
148 error.A => 0,
149 else => @intFromError(err) + 4,
150 };
151 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
152 }
153 }
154
155 fn testCapture() !void {
156 {
157 var a: Error!u64 = error.A;
158 _ = &a;
159 const b: u64 = a catch |err| switch (err) {
160 error.A => |e| @intFromError(e) + 4,
161 else => 0,
162 };
163 try expectEqual(@as(u64, @intFromError(error.A) + 4), b);
164 }
165 {
166 var a: Error!u64 = error.A;
167 _ = &a;
168 const b: u64 = a catch |err| switch (err) {
169 error.A => 0,
170 else => |e| @intFromError(e) + 4,
171 };
172 try expectEqual(@as(u64, 0), b);
173 }
174 {
175 var a: Error!u64 = error.B;
176 _ = &a;
177 const b: u64 = a catch |err| switch (err) {
178 error.A => 0,
179 else => |e| @intFromError(e) + 4,
180 };
181 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
182 }
183 {
184 var a: Error!u64 = error.B;
185 _ = &a;
186 const b: u64 = a catch |err| switch (err) {
187 error.A => |e| @intFromError(e) + 4,
188 else => |e| @intFromError(e) + 4,
189 };
190 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
191 }
192 {
193 var a: Error!u64 = error.B;
194 _ = &a;
195 const b: u64 = a catch |err| switch (err) {
196 error.A => 0,
197 error.B, error.C => |e| @intFromError(e) + 4,
198 };
199 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
200 }
201 }
202
203 fn testInline() !void {
204 {
205 var a: Error!u64 = error.B;
206 _ = &a;
207 const b: u64 = a catch |err| switch (err) {
208 error.A => 0,
209 inline else => @intFromError(err) + 4,
210 };
211 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
212 }
213 {
214 var a: Error!u64 = error.B;
215 _ = &a;
216 const b: u64 = a catch |err| switch (err) {
217 error.A => |e| @intFromError(e) + 4,
218 inline else => @intFromError(err) + 4,
219 };
220 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
221 }
222 {
223 var a: Error!u64 = error.B;
224 _ = &a;
225 const b: u64 = a catch |err| switch (err) {
226 inline else => |e| @intFromError(e) + 4,
227 };
228 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
229 }
230 {
231 var a: Error!u64 = error.B;
232 _ = &a;
233 const b: u64 = a catch |err| switch (err) {
234 error.A => 0,
235 inline error.B, error.C => |e| @intFromError(e) + 4,
236 };
237 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
238 }
239 }
240
241 fn testEmptyErrSet() !void {
242 {
243 var a: error{}!u64 = 0;
244 _ = &a;
245 const b = a catch |err| switch (err) {
246 undefined => comptime unreachable,
247 };
248 try expectEqual(@as(u64, 0), b);
249 }
250 }
251
252 fn testUnreachableElseProng() !void {
253 {
254 var a: error{}!u64 = 0;
255 _ = &a;
256 const b = a catch |err| switch (err) {
257 else => unreachable,
258 };
259 try expectEqual(@as(u64, 0), b);
260 }
261 {
262 var a: error{}!u64 = 0;
263 _ = &a;
264 const b = a catch |err| switch (err) {
265 else => return,
266 };
267 try expectEqual(@as(u64, 0), b);
268 }
269 {
270 var a: error{}!u64 = 0;
271 _ = &a;
272 const b = a catch |err| switch (err) {
273 else => |e| return e,
274 };
275 try expectEqual(@as(u64, 0), b);
276 }
277 {
278 var a: error{MyError}!u64 = error.MyError;
279 _ = &a;
280 const b = a catch |err| switch (err) {
281 error.MyError => 0,
282 else => unreachable,
283 };
284 try expectEqual(@as(u64, 0), b);
285 }
286 {
287 var a: error{MyError}!u64 = error.MyError;
288 _ = &a;
289 const b = a catch |err| switch (err) {
290 error.MyError => 0,
291 else => return,
292 };
293 try expectEqual(@as(u64, 0), b);
294 }
295 {
296 var a: error{MyError}!u64 = error.MyError;
297 _ = &a;
298 const b = a catch |err| switch (err) {
299 error.MyError => 0,
300 else => |e| return e,
301 };
302 try expectEqual(@as(u64, 0), b);
303 }
304 }
305
306 fn testErrNotInSet() !void {
307 {
308 var a: error{MyError}!u64 = 0;
309 _ = &a;
310 const b = a catch |err| switch (err) {
311 error.MyError => 1,
312 error.MyOtherError => comptime unreachable,
313 error.YetAnotherError, error.ThereIsAnother => comptime unreachable,
314 };
315 try expectEqual(@as(u64, 0), b);
316 }
317 {
318 var a: error{MyError}!u64 = error.MyError;
319 _ = &a;
320 const b = a catch |err| switch (err) {
321 error.MyError => 0,
322 error.MyOtherError => comptime unreachable,
323 error.YetAnotherError, error.ThereIsAnother => comptime unreachable,
324 };
325 try expectEqual(@as(u64, 0), b);
326 }
327 }
328
329 fn testAddressOf() !void {
330 {
331 const a: anyerror!usize = 0;
332 const ptr = &(a catch |e| switch (e) {
333 else => 3,
334 });
335 comptime assert(@TypeOf(ptr) == *const usize);
336 try expectEqual(ptr, &(a catch unreachable));
337 }
338 {
339 const a: anyerror!usize = error.A;
340 const ptr = &(a catch |e| switch (e) {
341 else => 3,
342 });
343 comptime assert(@TypeOf(ptr) == *const comptime_int);
344 try expectEqual(3, ptr.*);
345 }
346 {
347 var a: anyerror!usize = 0;
348 _ = &a;
349 const ptr = &(a catch |e| switch (e) {
350 else => return,
351 });
352 comptime assert(@TypeOf(ptr) == *usize);
353 ptr.* += 1;
354 try expectEqual(@as(usize, 1), a catch unreachable);
355 }
356 {
357 var a: anyerror!usize = error.A;
358 _ = &a;
359 const ptr = &(a catch |e| switch (e) {
360 else => return,
361 });
362 comptime assert(@TypeOf(ptr) == *usize);
363 unreachable;
364 }
365 }
366 };
367
368 try comptime S.doTheTest();
369 try S.doTheTest();
370}
371
372test "switch on error union if else capture" {
373 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
374 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
375
376 const S = struct {
377 const Error = error{ A, B, C };
378 fn doTheTest() !void {
379 try testScalar();
380 try testScalarPtr();
381 try testMulti();
382 try testMultiPtr();
383 try testElse();
384 try testElsePtr();
385 try testCapture();
386 try testCapturePtr();
387 try testInline();
388 try testInlinePtr();
389 try testEmptyErrSet();
390 try testEmptyErrSetPtr();
391 try testUnreachableElseProng();
392 try testUnreachableElseProngPtr();
393 try testErrNotInSet();
394 try testAddressOf();
395 }
396
397 fn testScalar() !void {
398 {
399 var a: Error!u64 = 3;
400 _ = &a;
401 const b: u64 = if (a) |x| x else |err| switch (err) {
402 error.A => 0,
403 error.B => 1,
404 error.C => 2,
405 };
406 try expectEqual(@as(u64, 3), b);
407 }
408 {
409 var a: Error!u64 = 3;
410 _ = &a;
411 const b: u64 = if (a) |x| x else |err| switch (err) {
412 error.A => 0,
413 error.B => @intFromError(err) + 4,
414 error.C => @intFromError(err) + 4,
415 };
416 try expectEqual(@as(u64, 3), b);
417 }
418 {
419 var a: Error!u64 = error.A;
420 _ = &a;
421 const b: u64 = if (a) |x| x else |err| switch (err) {
422 error.A => 0,
423 error.B => @intFromError(err) + 4,
424 error.C => @intFromError(err) + 4,
425 };
426 try expectEqual(@as(u64, 0), b);
427 }
428 }
429
430 fn testScalarPtr() !void {
431 {
432 var a: Error!u64 = 3;
433 _ = &a;
434 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
435 error.A => 0,
436 error.B => 1,
437 error.C => 2,
438 };
439 try expectEqual(@as(u64, 3), b);
440 }
441 {
442 var a: Error!u64 = 3;
443 _ = &a;
444 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
445 error.A => 0,
446 error.B => @intFromError(err) + 4,
447 error.C => @intFromError(err) + 4,
448 };
449 try expectEqual(@as(u64, 3), b);
450 }
451 {
452 var a: Error!u64 = error.A;
453 _ = &a;
454 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
455 error.A => 0,
456 error.B => @intFromError(err) + 4,
457 error.C => @intFromError(err) + 4,
458 };
459 try expectEqual(@as(u64, 0), b);
460 }
461 }
462
463 fn testMulti() !void {
464 {
465 var a: Error!u64 = 3;
466 _ = &a;
467 const b: u64 = if (a) |x| x else |err| switch (err) {
468 error.A, error.B => 0,
469 error.C => @intFromError(err) + 4,
470 };
471 try expectEqual(@as(u64, 3), b);
472 }
473 {
474 var a: Error!u64 = 3;
475 _ = &a;
476 const b: u64 = if (a) |x| x else |err| switch (err) {
477 error.A => 0,
478 error.B, error.C => @intFromError(err) + 4,
479 };
480 try expectEqual(@as(u64, 3), b);
481 }
482 {
483 var a: Error!u64 = error.A;
484 _ = &a;
485 const b: u64 = if (a) |x| x else |err| switch (err) {
486 error.A, error.B => 0,
487 error.C => @intFromError(err) + 4,
488 };
489 try expectEqual(@as(u64, 0), b);
490 }
491 {
492 var a: Error!u64 = error.A;
493 _ = &a;
494 const b: u64 = if (a) |x| x else |err| switch (err) {
495 error.A => 0,
496 error.B, error.C => @intFromError(err) + 4,
497 };
498 try expectEqual(@as(u64, 0), b);
499 }
500 {
501 var a: Error!u64 = error.B;
502 _ = &a;
503 const b: u64 = if (a) |x| x else |err| switch (err) {
504 error.A => 0,
505 error.B, error.C => @intFromError(err) + 4,
506 };
507 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
508 }
509 }
510
511 fn testMultiPtr() !void {
512 {
513 var a: Error!u64 = 3;
514 _ = &a;
515 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
516 error.A, error.B => 0,
517 error.C => @intFromError(err) + 4,
518 };
519 try expectEqual(@as(u64, 3), b);
520 }
521 {
522 var a: Error!u64 = 3;
523 _ = &a;
524 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
525 error.A => 0,
526 error.B, error.C => @intFromError(err) + 4,
527 };
528 try expectEqual(@as(u64, 3), b);
529 }
530 {
531 var a: Error!u64 = error.A;
532 _ = &a;
533 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
534 error.A, error.B => 0,
535 error.C => @intFromError(err) + 4,
536 };
537 try expectEqual(@as(u64, 0), b);
538 }
539 {
540 var a: Error!u64 = error.A;
541 _ = &a;
542 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
543 error.A => 0,
544 error.B, error.C => @intFromError(err) + 4,
545 };
546 try expectEqual(@as(u64, 0), b);
547 }
548 {
549 var a: Error!u64 = error.B;
550 _ = &a;
551 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
552 error.A => 0,
553 error.B, error.C => @intFromError(err) + 4,
554 };
555 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
556 }
557 }
558
559 fn testElse() !void {
560 {
561 var a: Error!u64 = 3;
562 _ = &a;
563 const b: u64 = if (a) |x| x else |err| switch (err) {
564 error.A => 0,
565 else => 1,
566 };
567 try expectEqual(@as(u64, 3), b);
568 }
569 {
570 var a: Error!u64 = 3;
571 _ = &a;
572 const b: u64 = if (a) |x| x else |err| switch (err) {
573 error.A => 0,
574 else => @intFromError(err) + 4,
575 };
576 try expectEqual(@as(u64, 3), b);
577 }
578 {
579 var a: Error!u64 = error.A;
580 _ = &a;
581 const b: u64 = if (a) |x| x else |err| switch (err) {
582 error.A => 1,
583 else => @intFromError(err) + 4,
584 };
585 try expectEqual(@as(u64, 1), b);
586 }
587 {
588 var a: Error!u64 = error.B;
589 _ = &a;
590 const b: u64 = if (a) |x| x else |err| switch (err) {
591 error.A => 0,
592 else => 1,
593 };
594 try expectEqual(@as(u64, 1), b);
595 }
596 {
597 var a: Error!u64 = error.B;
598 _ = &a;
599 const b: u64 = if (a) |x| x else |err| switch (err) {
600 error.A => 0,
601 else => @intFromError(err) + 4,
602 };
603 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
604 }
605 }
606
607 fn testElsePtr() !void {
608 {
609 var a: Error!u64 = 3;
610 _ = &a;
611 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
612 error.A => 0,
613 else => 1,
614 };
615 try expectEqual(@as(u64, 3), b);
616 }
617 {
618 var a: Error!u64 = 3;
619 _ = &a;
620 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
621 error.A => 0,
622 else => @intFromError(err) + 4,
623 };
624 try expectEqual(@as(u64, 3), b);
625 }
626 {
627 var a: Error!u64 = error.A;
628 _ = &a;
629 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
630 error.A => 1,
631 else => @intFromError(err) + 4,
632 };
633 try expectEqual(@as(u64, 1), b);
634 }
635 {
636 var a: Error!u64 = error.B;
637 _ = &a;
638 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
639 error.A => 0,
640 else => 1,
641 };
642 try expectEqual(@as(u64, 1), b);
643 }
644 {
645 var a: Error!u64 = error.B;
646 _ = &a;
647 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
648 error.A => 0,
649 else => @intFromError(err) + 4,
650 };
651 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
652 }
653 }
654
655 fn testCapture() !void {
656 {
657 var a: Error!u64 = error.A;
658 _ = &a;
659 const b: u64 = if (a) |x| x else |err| switch (err) {
660 error.A => |e| @intFromError(e) + 4,
661 else => 0,
662 };
663 try expectEqual(@as(u64, @intFromError(error.A) + 4), b);
664 }
665 {
666 var a: Error!u64 = error.A;
667 _ = &a;
668 const b: u64 = if (a) |x| x else |err| switch (err) {
669 error.A => 0,
670 else => |e| @intFromError(e) + 4,
671 };
672 try expectEqual(@as(u64, 0), b);
673 }
674 {
675 var a: Error!u64 = error.B;
676 _ = &a;
677 const b: u64 = if (a) |x| x else |err| switch (err) {
678 error.A => 0,
679 else => |e| @intFromError(e) + 4,
680 };
681 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
682 }
683 {
684 var a: Error!u64 = error.B;
685 _ = &a;
686 const b: u64 = if (a) |x| x else |err| switch (err) {
687 error.A => |e| @intFromError(e) + 4,
688 else => |e| @intFromError(e) + 4,
689 };
690 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
691 }
692 {
693 var a: Error!u64 = error.B;
694 _ = &a;
695 const b: u64 = if (a) |x| x else |err| switch (err) {
696 error.A => 0,
697 error.B, error.C => |e| @intFromError(e) + 4,
698 };
699 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
700 }
701 }
702
703 fn testCapturePtr() !void {
704 {
705 var a: Error!u64 = error.A;
706 _ = &a;
707 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
708 error.A => |e| @intFromError(e) + 4,
709 else => 0,
710 };
711 try expectEqual(@as(u64, @intFromError(error.A) + 4), b);
712 }
713 {
714 var a: Error!u64 = error.A;
715 _ = &a;
716 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
717 error.A => 0,
718 else => |e| @intFromError(e) + 4,
719 };
720 try expectEqual(@as(u64, 0), b);
721 }
722 {
723 var a: Error!u64 = error.B;
724 _ = &a;
725 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
726 error.A => 0,
727 else => |e| @intFromError(e) + 4,
728 };
729 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
730 }
731 {
732 var a: Error!u64 = error.B;
733 _ = &a;
734 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
735 error.A => |e| @intFromError(e) + 4,
736 else => |e| @intFromError(e) + 4,
737 };
738 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
739 }
740 {
741 var a: Error!u64 = error.B;
742 _ = &a;
743 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
744 error.A => 0,
745 error.B, error.C => |e| @intFromError(e) + 4,
746 };
747 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
748 }
749 }
750
751 fn testInline() !void {
752 {
753 var a: Error!u64 = error.B;
754 _ = &a;
755 const b: u64 = if (a) |x| x else |err| switch (err) {
756 error.A => 0,
757 inline else => @intFromError(err) + 4,
758 };
759 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
760 }
761 {
762 var a: Error!u64 = error.B;
763 _ = &a;
764 const b: u64 = if (a) |x| x else |err| switch (err) {
765 error.A => |e| @intFromError(e) + 4,
766 inline else => @intFromError(err) + 4,
767 };
768 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
769 }
770 {
771 var a: Error!u64 = error.B;
772 _ = &a;
773 const b: u64 = if (a) |x| x else |err| switch (err) {
774 inline else => |e| @intFromError(e) + 4,
775 };
776 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
777 }
778 {
779 var a: Error!u64 = error.B;
780 _ = &a;
781 const b: u64 = if (a) |x| x else |err| switch (err) {
782 error.A => 0,
783 inline error.B, error.C => |e| @intFromError(e) + 4,
784 };
785 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
786 }
787 }
788
789 fn testInlinePtr() !void {
790 {
791 var a: Error!u64 = error.B;
792 _ = &a;
793 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
794 error.A => 0,
795 inline else => @intFromError(err) + 4,
796 };
797 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
798 }
799 {
800 var a: Error!u64 = error.B;
801 _ = &a;
802 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
803 error.A => |e| @intFromError(e) + 4,
804 inline else => @intFromError(err) + 4,
805 };
806 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
807 }
808 {
809 var a: Error!u64 = error.B;
810 _ = &a;
811 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
812 inline else => |e| @intFromError(e) + 4,
813 };
814 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
815 }
816 {
817 var a: Error!u64 = error.B;
818 _ = &a;
819 const b: u64 = if (a) |*x| x.* else |err| switch (err) {
820 error.A => 0,
821 inline error.B, error.C => |e| @intFromError(e) + 4,
822 };
823 try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
824 }
825 }
826
827 fn testEmptyErrSet() !void {
828 {
829 var a: error{}!u64 = 0;
830 _ = &a;
831 const b = if (a) |x| x else |err| switch (err) {
832 undefined => comptime unreachable,
833 };
834 try expectEqual(@as(u64, 0), b);
835 }
836 }
837
838 fn testEmptyErrSetPtr() !void {
839 {
840 var a: error{}!u64 = 0;
841 _ = &a;
842 const b = if (a) |*x| x.* else |err| switch (err) {
843 undefined => comptime unreachable,
844 };
845 try expectEqual(@as(u64, 0), b);
846 }
847 }
848
849 fn testUnreachableElseProng() !void {
850 {
851 var a: error{}!u64 = 0;
852 _ = &a;
853 const b = if (a) |x| x else |err| switch (err) {
854 else => unreachable,
855 };
856 try expectEqual(@as(u64, 0), b);
857 }
858 {
859 var a: error{}!u64 = 0;
860 _ = &a;
861 const b = if (a) |x| x else |err| switch (err) {
862 error.UnknownError => return error.Fail,
863 else => return,
864 };
865 try expectEqual(@as(u64, 0), b);
866 }
867 {
868 var a: error{}!u64 = 0;
869 _ = &a;
870 const b = if (a) |x| x else |err| switch (err) {
871 error.UnknownError => return error.Fail,
872 else => |e| return e,
873 };
874 try expectEqual(@as(u64, 0), b);
875 }
876 {
877 var a: error{MyError}!u64 = error.MyError;
878 _ = &a;
879 const b = if (a) |x| x else |err| switch (err) {
880 error.MyError => 0,
881 else => unreachable,
882 };
883 try expectEqual(@as(u64, 0), b);
884 }
885 {
886 var a: error{MyError}!u64 = error.MyError;
887 _ = &a;
888 const b = if (a) |x| x else |err| switch (err) {
889 error.MyError => 0,
890 else => return,
891 };
892 try expectEqual(@as(u64, 0), b);
893 }
894 {
895 var a: error{MyError}!u64 = error.MyError;
896 _ = &a;
897 const b = if (a) |x| x else |err| switch (err) {
898 error.MyError => 0,
899 else => |e| return e,
900 };
901 try expectEqual(@as(u64, 0), b);
902 }
903 }
904
905 fn testUnreachableElseProngPtr() !void {
906 {
907 var a: error{}!u64 = 0;
908 _ = &a;
909 const b = if (a) |*x| x.* else |err| switch (err) {
910 else => unreachable,
911 };
912 try expectEqual(@as(u64, 0), b);
913 }
914 {
915 var a: error{}!u64 = 0;
916 _ = &a;
917 const b = if (a) |*x| x.* else |err| switch (err) {
918 else => return,
919 };
920 try expectEqual(@as(u64, 0), b);
921 }
922 {
923 var a: error{}!u64 = 0;
924 _ = &a;
925 const b = if (a) |*x| x.* else |err| switch (err) {
926 else => |e| return e,
927 };
928 try expectEqual(@as(u64, 0), b);
929 }
930 {
931 var a: error{MyError}!u64 = error.MyError;
932 _ = &a;
933 const b = if (a) |*x| x.* else |err| switch (err) {
934 error.MyError => 0,
935 else => unreachable,
936 };
937 try expectEqual(@as(u64, 0), b);
938 }
939 {
940 var a: error{MyError}!u64 = error.MyError;
941 _ = &a;
942 const b = if (a) |*x| x.* else |err| switch (err) {
943 error.MyError => 0,
944 else => return,
945 };
946 try expectEqual(@as(u64, 0), b);
947 }
948 {
949 var a: error{MyError}!u64 = error.MyError;
950 _ = &a;
951 const b = if (a) |*x| x.* else |err| switch (err) {
952 error.MyError => 0,
953 else => |e| return e,
954 };
955 try expectEqual(@as(u64, 0), b);
956 }
957 }
958
959 fn testErrNotInSet() !void {
960 {
961 var a: error{MyError}!u64 = 0;
962 _ = &a;
963 const b = if (a) |x| x else |err| switch (err) {
964 error.MyError => 1,
965 error.MyOtherError => comptime unreachable,
966 error.YetAnotherError, error.ThereIsAnother => comptime unreachable,
967 };
968 try expectEqual(@as(u64, 0), b);
969 }
970 {
971 var a: error{MyError}!u64 = error.MyError;
972 _ = &a;
973 const b = if (a) |x| x else |err| switch (err) {
974 error.MyError => 0,
975 error.MyOtherError => comptime unreachable,
976 error.YetAnotherError, error.ThereIsAnother => comptime unreachable,
977 };
978 try expectEqual(@as(u64, 0), b);
979 }
980 }
981
982 fn testAddressOf() !void {
983 {
984 const a: anyerror!usize = 0;
985 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
986 else => 3,
987 });
988 comptime assert(@TypeOf(ptr) == *const usize);
989 try expectEqual(ptr, &(a catch unreachable));
990 }
991 {
992 const a: anyerror!usize = error.A;
993 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
994 else => 3,
995 });
996 comptime assert(@TypeOf(ptr) == *const comptime_int);
997 try expectEqual(3, ptr.*);
998 }
999 {
1000 var a: anyerror!usize = 0;
1001 _ = &a;
1002 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
1003 else => return,
1004 });
1005 comptime assert(@TypeOf(ptr) == *usize);
1006 ptr.* += 1;
1007 try expectEqual(@as(usize, 1), a catch unreachable);
1008 }
1009 {
1010 var a: anyerror!usize = error.A;
1011 _ = &a;
1012 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
1013 else => return,
1014 });
1015 comptime assert(@TypeOf(ptr) == *usize);
1016 unreachable;
1017 }
1018 }
1019 };
1020
1021 try comptime S.doTheTest();
1022 try S.doTheTest();
1023}