master
  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 testAddressOf();
 22        }
 23
 24        fn testScalar() !void {
 25            {
 26                var a: Error!u64 = 3;
 27                _ = &a;
 28                const b: u64 = a catch |err| switch (err) {
 29                    error.A => 0,
 30                    error.B => 1,
 31                    error.C => 2,
 32                };
 33                try expectEqual(@as(u64, 3), b);
 34            }
 35            {
 36                var a: Error!u64 = 3;
 37                _ = &a;
 38                const b: u64 = a catch |err| switch (err) {
 39                    error.A => 0,
 40                    error.B => @intFromError(err) + 4,
 41                    error.C => @intFromError(err) + 4,
 42                };
 43                try expectEqual(@as(u64, 3), b);
 44            }
 45            {
 46                var a: Error!u64 = error.A;
 47                _ = &a;
 48                const b: u64 = a catch |err| switch (err) {
 49                    error.A => 0,
 50                    error.B => @intFromError(err) + 4,
 51                    error.C => @intFromError(err) + 4,
 52                };
 53                try expectEqual(@as(u64, 0), b);
 54            }
 55        }
 56
 57        fn testMulti() !void {
 58            {
 59                var a: Error!u64 = 3;
 60                _ = &a;
 61                const b: u64 = a catch |err| switch (err) {
 62                    error.A, error.B => 0,
 63                    error.C => @intFromError(err) + 4,
 64                };
 65                try expectEqual(@as(u64, 3), b);
 66            }
 67            {
 68                var a: Error!u64 = 3;
 69                _ = &a;
 70                const b: u64 = a catch |err| switch (err) {
 71                    error.A => 0,
 72                    error.B, error.C => @intFromError(err) + 4,
 73                };
 74                try expectEqual(@as(u64, 3), b);
 75            }
 76            {
 77                var a: Error!u64 = error.A;
 78                _ = &a;
 79                const b: u64 = a catch |err| switch (err) {
 80                    error.A, error.B => 0,
 81                    error.C => @intFromError(err) + 4,
 82                };
 83                try expectEqual(@as(u64, 0), b);
 84            }
 85            {
 86                var a: Error!u64 = error.A;
 87                _ = &a;
 88                const b: u64 = a catch |err| switch (err) {
 89                    error.A => 0,
 90                    error.B, error.C => @intFromError(err) + 4,
 91                };
 92                try expectEqual(@as(u64, 0), b);
 93            }
 94            {
 95                var a: Error!u64 = error.B;
 96                _ = &a;
 97                const b: u64 = a catch |err| switch (err) {
 98                    error.A => 0,
 99                    error.B, error.C => @intFromError(err) + 4,
100                };
101                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
102            }
103        }
104
105        fn testElse() !void {
106            {
107                var a: Error!u64 = 3;
108                _ = &a;
109                const b: u64 = a catch |err| switch (err) {
110                    error.A => 0,
111                    else => 1,
112                };
113                try expectEqual(@as(u64, 3), b);
114            }
115            {
116                var a: Error!u64 = 3;
117                _ = &a;
118                const b: u64 = a catch |err| switch (err) {
119                    error.A => 0,
120                    else => @intFromError(err) + 4,
121                };
122                try expectEqual(@as(u64, 3), b);
123            }
124            {
125                var a: Error!u64 = error.A;
126                _ = &a;
127                const b: u64 = a catch |err| switch (err) {
128                    error.A => 1,
129                    else => @intFromError(err) + 4,
130                };
131                try expectEqual(@as(u64, 1), b);
132            }
133            {
134                var a: Error!u64 = error.B;
135                _ = &a;
136                const b: u64 = a catch |err| switch (err) {
137                    error.A => 0,
138                    else => 1,
139                };
140                try expectEqual(@as(u64, 1), b);
141            }
142            {
143                var a: Error!u64 = error.B;
144                _ = &a;
145                const b: u64 = a catch |err| switch (err) {
146                    error.A => 0,
147                    else => @intFromError(err) + 4,
148                };
149                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
150            }
151        }
152
153        fn testCapture() !void {
154            {
155                var a: Error!u64 = error.A;
156                _ = &a;
157                const b: u64 = a catch |err| switch (err) {
158                    error.A => |e| @intFromError(e) + 4,
159                    else => 0,
160                };
161                try expectEqual(@as(u64, @intFromError(error.A) + 4), b);
162            }
163            {
164                var a: Error!u64 = error.A;
165                _ = &a;
166                const b: u64 = a catch |err| switch (err) {
167                    error.A => 0,
168                    else => |e| @intFromError(e) + 4,
169                };
170                try expectEqual(@as(u64, 0), b);
171            }
172            {
173                var a: Error!u64 = error.B;
174                _ = &a;
175                const b: u64 = a catch |err| switch (err) {
176                    error.A => 0,
177                    else => |e| @intFromError(e) + 4,
178                };
179                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
180            }
181            {
182                var a: Error!u64 = error.B;
183                _ = &a;
184                const b: u64 = a catch |err| switch (err) {
185                    error.A => |e| @intFromError(e) + 4,
186                    else => |e| @intFromError(e) + 4,
187                };
188                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
189            }
190            {
191                var a: Error!u64 = error.B;
192                _ = &a;
193                const b: u64 = a catch |err| switch (err) {
194                    error.A => 0,
195                    error.B, error.C => |e| @intFromError(e) + 4,
196                };
197                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
198            }
199        }
200
201        fn testInline() !void {
202            {
203                var a: Error!u64 = error.B;
204                _ = &a;
205                const b: u64 = a catch |err| switch (err) {
206                    error.A => 0,
207                    inline else => @intFromError(err) + 4,
208                };
209                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
210            }
211            {
212                var a: Error!u64 = error.B;
213                _ = &a;
214                const b: u64 = a catch |err| switch (err) {
215                    error.A => |e| @intFromError(e) + 4,
216                    inline else => @intFromError(err) + 4,
217                };
218                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
219            }
220            {
221                var a: Error!u64 = error.B;
222                _ = &a;
223                const b: u64 = a catch |err| switch (err) {
224                    inline else => |e| @intFromError(e) + 4,
225                };
226                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
227            }
228            {
229                var a: Error!u64 = error.B;
230                _ = &a;
231                const b: u64 = a catch |err| switch (err) {
232                    error.A => 0,
233                    inline error.B, error.C => |e| @intFromError(e) + 4,
234                };
235                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
236            }
237        }
238
239        fn testEmptyErrSet() !void {
240            {
241                var a: error{}!u64 = 0;
242                _ = &a;
243                const b: u64 = a catch |err| switch (err) {
244                    else => |e| return e,
245                };
246                try expectEqual(@as(u64, 0), b);
247            }
248            {
249                var a: error{}!u64 = 0;
250                _ = &a;
251                const b: u64 = a catch |err| switch (err) {
252                    error.UnknownError => return error.Fail,
253                    else => |e| return e,
254                };
255                try expectEqual(@as(u64, 0), b);
256            }
257        }
258
259        fn testAddressOf() !void {
260            {
261                const a: anyerror!usize = 0;
262                const ptr = &(a catch |e| switch (e) {
263                    else => 3,
264                });
265                comptime assert(@TypeOf(ptr) == *const usize);
266                try expectEqual(ptr, &(a catch unreachable));
267            }
268            {
269                const a: anyerror!usize = error.A;
270                const ptr = &(a catch |e| switch (e) {
271                    else => 3,
272                });
273                comptime assert(@TypeOf(ptr) == *const comptime_int);
274                try expectEqual(3, ptr.*);
275            }
276            {
277                var a: anyerror!usize = 0;
278                _ = &a;
279                const ptr = &(a catch |e| switch (e) {
280                    else => return,
281                });
282                comptime assert(@TypeOf(ptr) == *usize);
283                ptr.* += 1;
284                try expectEqual(@as(usize, 1), a catch unreachable);
285            }
286            {
287                var a: anyerror!usize = error.A;
288                _ = &a;
289                const ptr = &(a catch |e| switch (e) {
290                    else => return,
291                });
292                comptime assert(@TypeOf(ptr) == *usize);
293                unreachable;
294            }
295        }
296    };
297
298    try comptime S.doTheTest();
299    try S.doTheTest();
300}
301
302test "switch on error union if else capture" {
303    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
304    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
305
306    const S = struct {
307        const Error = error{ A, B, C };
308        fn doTheTest() !void {
309            try testScalar();
310            try testScalarPtr();
311            try testMulti();
312            try testMultiPtr();
313            try testElse();
314            try testElsePtr();
315            try testCapture();
316            try testCapturePtr();
317            try testInline();
318            try testInlinePtr();
319            try testEmptyErrSet();
320            try testEmptyErrSetPtr();
321            try testAddressOf();
322        }
323
324        fn testScalar() !void {
325            {
326                var a: Error!u64 = 3;
327                _ = &a;
328                const b: u64 = if (a) |x| x else |err| switch (err) {
329                    error.A => 0,
330                    error.B => 1,
331                    error.C => 2,
332                };
333                try expectEqual(@as(u64, 3), b);
334            }
335            {
336                var a: Error!u64 = 3;
337                _ = &a;
338                const b: u64 = if (a) |x| x else |err| switch (err) {
339                    error.A => 0,
340                    error.B => @intFromError(err) + 4,
341                    error.C => @intFromError(err) + 4,
342                };
343                try expectEqual(@as(u64, 3), b);
344            }
345            {
346                var a: Error!u64 = error.A;
347                _ = &a;
348                const b: u64 = if (a) |x| x else |err| switch (err) {
349                    error.A => 0,
350                    error.B => @intFromError(err) + 4,
351                    error.C => @intFromError(err) + 4,
352                };
353                try expectEqual(@as(u64, 0), b);
354            }
355        }
356
357        fn testScalarPtr() !void {
358            {
359                var a: Error!u64 = 3;
360                _ = &a;
361                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
362                    error.A => 0,
363                    error.B => 1,
364                    error.C => 2,
365                };
366                try expectEqual(@as(u64, 3), b);
367            }
368            {
369                var a: Error!u64 = 3;
370                _ = &a;
371                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
372                    error.A => 0,
373                    error.B => @intFromError(err) + 4,
374                    error.C => @intFromError(err) + 4,
375                };
376                try expectEqual(@as(u64, 3), b);
377            }
378            {
379                var a: Error!u64 = error.A;
380                _ = &a;
381                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
382                    error.A => 0,
383                    error.B => @intFromError(err) + 4,
384                    error.C => @intFromError(err) + 4,
385                };
386                try expectEqual(@as(u64, 0), b);
387            }
388        }
389
390        fn testMulti() !void {
391            {
392                var a: Error!u64 = 3;
393                _ = &a;
394                const b: u64 = if (a) |x| x else |err| switch (err) {
395                    error.A, error.B => 0,
396                    error.C => @intFromError(err) + 4,
397                };
398                try expectEqual(@as(u64, 3), b);
399            }
400            {
401                var a: Error!u64 = 3;
402                _ = &a;
403                const b: u64 = if (a) |x| x else |err| switch (err) {
404                    error.A => 0,
405                    error.B, error.C => @intFromError(err) + 4,
406                };
407                try expectEqual(@as(u64, 3), b);
408            }
409            {
410                var a: Error!u64 = error.A;
411                _ = &a;
412                const b: u64 = if (a) |x| x else |err| switch (err) {
413                    error.A, error.B => 0,
414                    error.C => @intFromError(err) + 4,
415                };
416                try expectEqual(@as(u64, 0), 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, error.C => @intFromError(err) + 4,
424                };
425                try expectEqual(@as(u64, 0), b);
426            }
427            {
428                var a: Error!u64 = error.B;
429                _ = &a;
430                const b: u64 = if (a) |x| x else |err| switch (err) {
431                    error.A => 0,
432                    error.B, error.C => @intFromError(err) + 4,
433                };
434                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
435            }
436        }
437
438        fn testMultiPtr() !void {
439            {
440                var a: Error!u64 = 3;
441                _ = &a;
442                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
443                    error.A, error.B => 0,
444                    error.C => @intFromError(err) + 4,
445                };
446                try expectEqual(@as(u64, 3), b);
447            }
448            {
449                var a: Error!u64 = 3;
450                _ = &a;
451                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
452                    error.A => 0,
453                    error.B, error.C => @intFromError(err) + 4,
454                };
455                try expectEqual(@as(u64, 3), b);
456            }
457            {
458                var a: Error!u64 = error.A;
459                _ = &a;
460                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
461                    error.A, error.B => 0,
462                    error.C => @intFromError(err) + 4,
463                };
464                try expectEqual(@as(u64, 0), b);
465            }
466            {
467                var a: Error!u64 = error.A;
468                _ = &a;
469                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
470                    error.A => 0,
471                    error.B, error.C => @intFromError(err) + 4,
472                };
473                try expectEqual(@as(u64, 0), b);
474            }
475            {
476                var a: Error!u64 = error.B;
477                _ = &a;
478                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
479                    error.A => 0,
480                    error.B, error.C => @intFromError(err) + 4,
481                };
482                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
483            }
484        }
485
486        fn testElse() !void {
487            {
488                var a: Error!u64 = 3;
489                _ = &a;
490                const b: u64 = if (a) |x| x else |err| switch (err) {
491                    error.A => 0,
492                    else => 1,
493                };
494                try expectEqual(@as(u64, 3), b);
495            }
496            {
497                var a: Error!u64 = 3;
498                _ = &a;
499                const b: u64 = if (a) |x| x else |err| switch (err) {
500                    error.A => 0,
501                    else => @intFromError(err) + 4,
502                };
503                try expectEqual(@as(u64, 3), b);
504            }
505            {
506                var a: Error!u64 = error.A;
507                _ = &a;
508                const b: u64 = if (a) |x| x else |err| switch (err) {
509                    error.A => 1,
510                    else => @intFromError(err) + 4,
511                };
512                try expectEqual(@as(u64, 1), b);
513            }
514            {
515                var a: Error!u64 = error.B;
516                _ = &a;
517                const b: u64 = if (a) |x| x else |err| switch (err) {
518                    error.A => 0,
519                    else => 1,
520                };
521                try expectEqual(@as(u64, 1), b);
522            }
523            {
524                var a: Error!u64 = error.B;
525                _ = &a;
526                const b: u64 = if (a) |x| x else |err| switch (err) {
527                    error.A => 0,
528                    else => @intFromError(err) + 4,
529                };
530                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
531            }
532        }
533
534        fn testElsePtr() !void {
535            {
536                var a: Error!u64 = 3;
537                _ = &a;
538                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
539                    error.A => 0,
540                    else => 1,
541                };
542                try expectEqual(@as(u64, 3), b);
543            }
544            {
545                var a: Error!u64 = 3;
546                _ = &a;
547                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
548                    error.A => 0,
549                    else => @intFromError(err) + 4,
550                };
551                try expectEqual(@as(u64, 3), b);
552            }
553            {
554                var a: Error!u64 = error.A;
555                _ = &a;
556                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
557                    error.A => 1,
558                    else => @intFromError(err) + 4,
559                };
560                try expectEqual(@as(u64, 1), b);
561            }
562            {
563                var a: Error!u64 = error.B;
564                _ = &a;
565                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
566                    error.A => 0,
567                    else => 1,
568                };
569                try expectEqual(@as(u64, 1), b);
570            }
571            {
572                var a: Error!u64 = error.B;
573                _ = &a;
574                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
575                    error.A => 0,
576                    else => @intFromError(err) + 4,
577                };
578                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
579            }
580        }
581
582        fn testCapture() !void {
583            {
584                var a: Error!u64 = error.A;
585                _ = &a;
586                const b: u64 = if (a) |x| x else |err| switch (err) {
587                    error.A => |e| @intFromError(e) + 4,
588                    else => 0,
589                };
590                try expectEqual(@as(u64, @intFromError(error.A) + 4), b);
591            }
592            {
593                var a: Error!u64 = error.A;
594                _ = &a;
595                const b: u64 = if (a) |x| x else |err| switch (err) {
596                    error.A => 0,
597                    else => |e| @intFromError(e) + 4,
598                };
599                try expectEqual(@as(u64, 0), b);
600            }
601            {
602                var a: Error!u64 = error.B;
603                _ = &a;
604                const b: u64 = if (a) |x| x else |err| switch (err) {
605                    error.A => 0,
606                    else => |e| @intFromError(e) + 4,
607                };
608                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
609            }
610            {
611                var a: Error!u64 = error.B;
612                _ = &a;
613                const b: u64 = if (a) |x| x else |err| switch (err) {
614                    error.A => |e| @intFromError(e) + 4,
615                    else => |e| @intFromError(e) + 4,
616                };
617                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
618            }
619            {
620                var a: Error!u64 = error.B;
621                _ = &a;
622                const b: u64 = if (a) |x| x else |err| switch (err) {
623                    error.A => 0,
624                    error.B, error.C => |e| @intFromError(e) + 4,
625                };
626                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
627            }
628        }
629
630        fn testCapturePtr() !void {
631            {
632                var a: Error!u64 = error.A;
633                _ = &a;
634                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
635                    error.A => |e| @intFromError(e) + 4,
636                    else => 0,
637                };
638                try expectEqual(@as(u64, @intFromError(error.A) + 4), b);
639            }
640            {
641                var a: Error!u64 = error.A;
642                _ = &a;
643                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
644                    error.A => 0,
645                    else => |e| @intFromError(e) + 4,
646                };
647                try expectEqual(@as(u64, 0), b);
648            }
649            {
650                var a: Error!u64 = error.B;
651                _ = &a;
652                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
653                    error.A => 0,
654                    else => |e| @intFromError(e) + 4,
655                };
656                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
657            }
658            {
659                var a: Error!u64 = error.B;
660                _ = &a;
661                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
662                    error.A => |e| @intFromError(e) + 4,
663                    else => |e| @intFromError(e) + 4,
664                };
665                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
666            }
667            {
668                var a: Error!u64 = error.B;
669                _ = &a;
670                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
671                    error.A => 0,
672                    error.B, error.C => |e| @intFromError(e) + 4,
673                };
674                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
675            }
676        }
677
678        fn testInline() !void {
679            {
680                var a: Error!u64 = error.B;
681                _ = &a;
682                const b: u64 = if (a) |x| x else |err| switch (err) {
683                    error.A => 0,
684                    inline else => @intFromError(err) + 4,
685                };
686                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
687            }
688            {
689                var a: Error!u64 = error.B;
690                _ = &a;
691                const b: u64 = if (a) |x| x else |err| switch (err) {
692                    error.A => |e| @intFromError(e) + 4,
693                    inline else => @intFromError(err) + 4,
694                };
695                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
696            }
697            {
698                var a: Error!u64 = error.B;
699                _ = &a;
700                const b: u64 = if (a) |x| x else |err| switch (err) {
701                    inline else => |e| @intFromError(e) + 4,
702                };
703                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
704            }
705            {
706                var a: Error!u64 = error.B;
707                _ = &a;
708                const b: u64 = if (a) |x| x else |err| switch (err) {
709                    error.A => 0,
710                    inline error.B, error.C => |e| @intFromError(e) + 4,
711                };
712                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
713            }
714        }
715
716        fn testInlinePtr() !void {
717            {
718                var a: Error!u64 = error.B;
719                _ = &a;
720                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
721                    error.A => 0,
722                    inline else => @intFromError(err) + 4,
723                };
724                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
725            }
726            {
727                var a: Error!u64 = error.B;
728                _ = &a;
729                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
730                    error.A => |e| @intFromError(e) + 4,
731                    inline else => @intFromError(err) + 4,
732                };
733                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
734            }
735            {
736                var a: Error!u64 = error.B;
737                _ = &a;
738                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
739                    inline else => |e| @intFromError(e) + 4,
740                };
741                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
742            }
743            {
744                var a: Error!u64 = error.B;
745                _ = &a;
746                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
747                    error.A => 0,
748                    inline error.B, error.C => |e| @intFromError(e) + 4,
749                };
750                try expectEqual(@as(u64, @intFromError(error.B) + 4), b);
751            }
752        }
753
754        fn testEmptyErrSet() !void {
755            {
756                var a: error{}!u64 = 0;
757                _ = &a;
758                const b: u64 = if (a) |x| x else |err| switch (err) {
759                    else => |e| return e,
760                };
761                try expectEqual(@as(u64, 0), b);
762            }
763            {
764                var a: error{}!u64 = 0;
765                _ = &a;
766                const b: u64 = if (a) |x| x else |err| switch (err) {
767                    error.UnknownError => return error.Fail,
768                    else => |e| return e,
769                };
770                try expectEqual(@as(u64, 0), b);
771            }
772        }
773
774        fn testEmptyErrSetPtr() !void {
775            {
776                var a: error{}!u64 = 0;
777                _ = &a;
778                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
779                    else => |e| return e,
780                };
781                try expectEqual(@as(u64, 0), b);
782            }
783            {
784                var a: error{}!u64 = 0;
785                _ = &a;
786                const b: u64 = if (a) |*x| x.* else |err| switch (err) {
787                    error.UnknownError => return error.Fail,
788                    else => |e| return e,
789                };
790                try expectEqual(@as(u64, 0), b);
791            }
792        }
793
794        fn testAddressOf() !void {
795            {
796                const a: anyerror!usize = 0;
797                const ptr = &(if (a) |*v| v.* else |e| switch (e) {
798                    else => 3,
799                });
800                comptime assert(@TypeOf(ptr) == *const usize);
801                try expectEqual(ptr, &(a catch unreachable));
802            }
803            {
804                const a: anyerror!usize = error.A;
805                const ptr = &(if (a) |*v| v.* else |e| switch (e) {
806                    else => 3,
807                });
808                comptime assert(@TypeOf(ptr) == *const comptime_int);
809                try expectEqual(3, ptr.*);
810            }
811            {
812                var a: anyerror!usize = 0;
813                _ = &a;
814                const ptr = &(if (a) |*v| v.* else |e| switch (e) {
815                    else => return,
816                });
817                comptime assert(@TypeOf(ptr) == *usize);
818                ptr.* += 1;
819                try expectEqual(@as(usize, 1), a catch unreachable);
820            }
821            {
822                var a: anyerror!usize = error.A;
823                _ = &a;
824                const ptr = &(if (a) |*v| v.* else |e| switch (e) {
825                    else => return,
826                });
827                comptime assert(@TypeOf(ptr) == *usize);
828                unreachable;
829            }
830        }
831    };
832
833    try comptime S.doTheTest();
834    try S.doTheTest();
835}