authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-17 19:52:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-17 19:52:24-07:00
log2600978a9ddc295c347fd6ffe7c6ba20931b956e
tree7fe1f3ae85145879b12fdc3b4a6c9bbf4e700fc5
parente69cb9105a716dfd4a8cc2684417545b2438f606

behavior tests: a couple more switch cases are passing


3 files changed, 222 insertions(+), 215 deletions(-)

test/behavior.zig-1
......@@ -191,7 +191,6 @@ test {
191191 _ = @import("behavior/struct_stage1.zig");
192192 _ = @import("behavior/switch_prong_err_enum.zig");
193193 _ = @import("behavior/switch_prong_implicit_cast.zig");
194 _ = @import("behavior/switch_stage1.zig");
195194 _ = @import("behavior/truncate_stage1.zig");
196195 _ = @import("behavior/tuple.zig");
197196 _ = @import("behavior/type_stage1.zig");
test/behavior/switch.zig+222
......@@ -347,3 +347,225 @@ fn switchWithUnreachable(x: i32) i32 {
347347 }
348348 return 10;
349349}
350
351test "capture value of switch with all unreachable prongs" {
352 const x = return_a_number() catch |err| switch (err) {
353 else => unreachable,
354 };
355 try expect(x == 1);
356}
357
358fn return_a_number() anyerror!i32 {
359 return 1;
360}
361
362test "else prong of switch on error set excludes other cases" {
363 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
364
365 const S = struct {
366 fn doTheTest() !void {
367 try expectError(error.C, bar());
368 }
369 const E = error{
370 A,
371 B,
372 } || E2;
373
374 const E2 = error{
375 C,
376 D,
377 };
378
379 fn foo() E!void {
380 return error.C;
381 }
382
383 fn bar() E2!void {
384 foo() catch |err| switch (err) {
385 error.A, error.B => {},
386 else => |e| return e,
387 };
388 }
389 };
390 try S.doTheTest();
391 comptime try S.doTheTest();
392}
393
394test "switch prongs with error set cases make a new error set type for capture value" {
395 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
396
397 const S = struct {
398 fn doTheTest() !void {
399 try expectError(error.B, bar());
400 }
401 const E = E1 || E2;
402
403 const E1 = error{
404 A,
405 B,
406 };
407
408 const E2 = error{
409 C,
410 D,
411 };
412
413 fn foo() E!void {
414 return error.B;
415 }
416
417 fn bar() E1!void {
418 foo() catch |err| switch (err) {
419 error.A, error.B => |e| return e,
420 else => {},
421 };
422 }
423 };
424 try S.doTheTest();
425 comptime try S.doTheTest();
426}
427
428test "return result loc and then switch with range implicit casted to error union" {
429 const S = struct {
430 fn doTheTest() !void {
431 try expect((func(0xb) catch unreachable) == 0xb);
432 }
433 fn func(d: u8) anyerror!u8 {
434 return switch (d) {
435 0xa...0xf => d,
436 else => unreachable,
437 };
438 }
439 };
440 try S.doTheTest();
441 comptime try S.doTheTest();
442}
443
444test "switch with null and T peer types and inferred result location type" {
445 const S = struct {
446 fn doTheTest(c: u8) !void {
447 if (switch (c) {
448 0 => true,
449 else => null,
450 }) |v| {
451 _ = v;
452 @panic("fail");
453 }
454 }
455 };
456 try S.doTheTest(1);
457 comptime try S.doTheTest(1);
458}
459
460test "switch prongs with cases with identical payload types" {
461 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
462
463 const Union = union(enum) {
464 A: usize,
465 B: isize,
466 C: usize,
467 };
468 const S = struct {
469 fn doTheTest() !void {
470 try doTheSwitch1(Union{ .A = 8 });
471 try doTheSwitch2(Union{ .B = -8 });
472 }
473 fn doTheSwitch1(u: Union) !void {
474 switch (u) {
475 .A, .C => |e| {
476 try expect(@TypeOf(e) == usize);
477 try expect(e == 8);
478 },
479 .B => |e| {
480 _ = e;
481 @panic("fail");
482 },
483 }
484 }
485 fn doTheSwitch2(u: Union) !void {
486 switch (u) {
487 .A, .C => |e| {
488 _ = e;
489 @panic("fail");
490 },
491 .B => |e| {
492 try expect(@TypeOf(e) == isize);
493 try expect(e == -8);
494 },
495 }
496 }
497 };
498 try S.doTheTest();
499 comptime try S.doTheTest();
500}
501
502test "switch on pointer type" {
503 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
504
505 const S = struct {
506 const X = struct {
507 field: u32,
508 };
509
510 const P1 = @intToPtr(*X, 0x400);
511 const P2 = @intToPtr(*X, 0x800);
512 const P3 = @intToPtr(*X, 0xC00);
513
514 fn doTheTest(arg: *X) i32 {
515 switch (arg) {
516 P1 => return 1,
517 P2 => return 2,
518 else => return 3,
519 }
520 }
521 };
522
523 try expect(1 == S.doTheTest(S.P1));
524 try expect(2 == S.doTheTest(S.P2));
525 try expect(3 == S.doTheTest(S.P3));
526 comptime try expect(1 == S.doTheTest(S.P1));
527 comptime try expect(2 == S.doTheTest(S.P2));
528 comptime try expect(3 == S.doTheTest(S.P3));
529}
530
531test "switch on error set with single else" {
532 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
533
534 const S = struct {
535 fn doTheTest() !void {
536 var some: error{Foo} = error.Foo;
537 try expect(switch (some) {
538 else => |a| blk: {
539 a catch {};
540 break :blk true;
541 },
542 });
543 }
544 };
545
546 try S.doTheTest();
547 comptime try S.doTheTest();
548}
549
550test "switch capture copies its payload" {
551 if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
552
553 const S = struct {
554 fn doTheTest() !void {
555 var tmp: union(enum) {
556 A: u8,
557 B: u32,
558 } = .{ .A = 42 };
559 switch (tmp) {
560 .A => |value| {
561 // Modify the original union
562 tmp = .{ .B = 0x10101010 };
563 try expectEqual(@as(u8, 42), value);
564 },
565 else => unreachable,
566 }
567 }
568 };
569 try S.doTheTest();
570 comptime try S.doTheTest();
571}
test/behavior/switch_stage1.zig deleted-214
......@@ -1,214 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectError = std.testing.expectError;
4const expectEqual = std.testing.expectEqual;
5
6fn return_a_number() anyerror!i32 {
7 return 1;
8}
9
10test "capture value of switch with all unreachable prongs" {
11 const x = return_a_number() catch |err| switch (err) {
12 else => unreachable,
13 };
14 try expect(x == 1);
15}
16
17test "else prong of switch on error set excludes other cases" {
18 const S = struct {
19 fn doTheTest() !void {
20 try expectError(error.C, bar());
21 }
22 const E = error{
23 A,
24 B,
25 } || E2;
26
27 const E2 = error{
28 C,
29 D,
30 };
31
32 fn foo() E!void {
33 return error.C;
34 }
35
36 fn bar() E2!void {
37 foo() catch |err| switch (err) {
38 error.A, error.B => {},
39 else => |e| return e,
40 };
41 }
42 };
43 try S.doTheTest();
44 comptime try S.doTheTest();
45}
46
47test "switch prongs with error set cases make a new error set type for capture value" {
48 const S = struct {
49 fn doTheTest() !void {
50 try expectError(error.B, bar());
51 }
52 const E = E1 || E2;
53
54 const E1 = error{
55 A,
56 B,
57 };
58
59 const E2 = error{
60 C,
61 D,
62 };
63
64 fn foo() E!void {
65 return error.B;
66 }
67
68 fn bar() E1!void {
69 foo() catch |err| switch (err) {
70 error.A, error.B => |e| return e,
71 else => {},
72 };
73 }
74 };
75 try S.doTheTest();
76 comptime try S.doTheTest();
77}
78
79test "return result loc and then switch with range implicit casted to error union" {
80 const S = struct {
81 fn doTheTest() !void {
82 try expect((func(0xb) catch unreachable) == 0xb);
83 }
84 fn func(d: u8) anyerror!u8 {
85 return switch (d) {
86 0xa...0xf => d,
87 else => unreachable,
88 };
89 }
90 };
91 try S.doTheTest();
92 comptime try S.doTheTest();
93}
94
95test "switch with null and T peer types and inferred result location type" {
96 const S = struct {
97 fn doTheTest(c: u8) !void {
98 if (switch (c) {
99 0 => true,
100 else => null,
101 }) |v| {
102 _ = v;
103 @panic("fail");
104 }
105 }
106 };
107 try S.doTheTest(1);
108 comptime try S.doTheTest(1);
109}
110
111test "switch prongs with cases with identical payload types" {
112 const Union = union(enum) {
113 A: usize,
114 B: isize,
115 C: usize,
116 };
117 const S = struct {
118 fn doTheTest() !void {
119 try doTheSwitch1(Union{ .A = 8 });
120 try doTheSwitch2(Union{ .B = -8 });
121 }
122 fn doTheSwitch1(u: Union) !void {
123 switch (u) {
124 .A, .C => |e| {
125 try expect(@TypeOf(e) == usize);
126 try expect(e == 8);
127 },
128 .B => |e| {
129 _ = e;
130 @panic("fail");
131 },
132 }
133 }
134 fn doTheSwitch2(u: Union) !void {
135 switch (u) {
136 .A, .C => |e| {
137 _ = e;
138 @panic("fail");
139 },
140 .B => |e| {
141 try expect(@TypeOf(e) == isize);
142 try expect(e == -8);
143 },
144 }
145 }
146 };
147 try S.doTheTest();
148 comptime try S.doTheTest();
149}
150
151test "switch on pointer type" {
152 const S = struct {
153 const X = struct {
154 field: u32,
155 };
156
157 const P1 = @intToPtr(*X, 0x400);
158 const P2 = @intToPtr(*X, 0x800);
159 const P3 = @intToPtr(*X, 0xC00);
160
161 fn doTheTest(arg: *X) i32 {
162 switch (arg) {
163 P1 => return 1,
164 P2 => return 2,
165 else => return 3,
166 }
167 }
168 };
169
170 try expect(1 == S.doTheTest(S.P1));
171 try expect(2 == S.doTheTest(S.P2));
172 try expect(3 == S.doTheTest(S.P3));
173 comptime try expect(1 == S.doTheTest(S.P1));
174 comptime try expect(2 == S.doTheTest(S.P2));
175 comptime try expect(3 == S.doTheTest(S.P3));
176}
177
178test "switch on error set with single else" {
179 const S = struct {
180 fn doTheTest() !void {
181 var some: error{Foo} = error.Foo;
182 try expect(switch (some) {
183 else => |a| blk: {
184 a catch {};
185 break :blk true;
186 },
187 });
188 }
189 };
190
191 try S.doTheTest();
192 comptime try S.doTheTest();
193}
194
195test "switch capture copies its payload" {
196 const S = struct {
197 fn doTheTest() !void {
198 var tmp: union(enum) {
199 A: u8,
200 B: u32,
201 } = .{ .A = 42 };
202 switch (tmp) {
203 .A => |value| {
204 // Modify the original union
205 tmp = .{ .B = 0x10101010 };
206 try expectEqual(@as(u8, 42), value);
207 },
208 else => unreachable,
209 }
210 }
211 };
212 try S.doTheTest();
213 comptime try S.doTheTest();
214}