master
1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4
5test "try on error union" {
6 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7
8 try tryOnErrorUnionImpl();
9 try comptime tryOnErrorUnionImpl();
10}
11
12fn tryOnErrorUnionImpl() !void {
13 const x = if (returnsTen()) |val| val + 1 else |err| switch (err) {
14 error.ItBroke, error.NoMem => 1,
15 error.CrappedOut => @as(i32, 2),
16 else => unreachable,
17 };
18 try expect(x == 11);
19}
20
21fn returnsTen() anyerror!i32 {
22 return 10;
23}
24
25test "try without vars" {
26 const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2);
27 try expect(result1 == 2);
28
29 const result2 = if (failIfTrue(false)) 1 else |_| @as(i32, 2);
30 try expect(result2 == 1);
31}
32
33fn failIfTrue(ok: bool) anyerror!void {
34 if (ok) {
35 return error.ItBroke;
36 } else {
37 return;
38 }
39}
40
41test "try then not executed with assignment" {
42 if (failIfTrue(true)) {
43 unreachable;
44 } else |err| {
45 try expect(err == error.ItBroke);
46 }
47}
48
49test "`try`ing an if/else expression" {
50 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
53
54 const S = struct {
55 fn getError() !void {
56 return error.Test;
57 }
58
59 fn getError2() !void {
60 var a: u8 = 'c';
61 _ = &a;
62 try if (a == 'a') getError() else if (a == 'b') getError() else getError();
63 }
64 };
65
66 try std.testing.expectError(error.Test, S.getError2());
67}
68
69test "'return try' of empty error set in function returning non-error" {
70 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
71 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
72
73 const S = struct {
74 fn succeed0() error{}!u32 {
75 return 123;
76 }
77 fn succeed1() !u32 {
78 return 456;
79 }
80 fn tryNoError0() u32 {
81 return try succeed0();
82 }
83 fn tryNoError1() u32 {
84 return try succeed1();
85 }
86 fn tryNoError2() u32 {
87 const e: error{}!u32 = 789;
88 return try e;
89 }
90 fn doTheTest() !void {
91 const res0 = tryNoError0();
92 const res1 = tryNoError1();
93 const res2 = tryNoError2();
94 try expect(res0 == 123);
95 try expect(res1 == 456);
96 try expect(res2 == 789);
97 }
98 };
99 try S.doTheTest();
100 try comptime S.doTheTest();
101}
102
103test "'return try' through conditional" {
104 const S = struct {
105 fn get(t: bool) !u32 {
106 return try if (t) inner() else error.TestFailed;
107 }
108 fn inner() !u16 {
109 return 123;
110 }
111 };
112
113 {
114 const result = try S.get(true);
115 try expect(result == 123);
116 }
117
118 {
119 const result = try comptime S.get(true);
120 comptime std.debug.assert(result == 123);
121 }
122}
123
124test "try ptr propagation const" {
125 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
126 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
127 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
128 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
129
130 const S = struct {
131 fn foo0() !u32 {
132 return 0;
133 }
134
135 fn foo1() error{Bad}!u32 {
136 return 1;
137 }
138
139 fn foo2() anyerror!u32 {
140 return 2;
141 }
142
143 fn doTheTest() !void {
144 const res0: *const u32 = &(try foo0());
145 const res1: *const u32 = &(try foo1());
146 const res2: *const u32 = &(try foo2());
147 try expect(res0.* == 0);
148 try expect(res1.* == 1);
149 try expect(res2.* == 2);
150 }
151 };
152 try S.doTheTest();
153 try comptime S.doTheTest();
154}
155
156test "try ptr propagation mutate" {
157 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
158 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
159 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
160 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
161
162 const S = struct {
163 fn foo0() !u32 {
164 return 0;
165 }
166
167 fn foo1() error{Bad}!u32 {
168 return 1;
169 }
170
171 fn foo2() anyerror!u32 {
172 return 2;
173 }
174
175 fn doTheTest() !void {
176 var f0 = foo0();
177 var f1 = foo1();
178 var f2 = foo2();
179
180 const res0: *u32 = &(try f0);
181 const res1: *u32 = &(try f1);
182 const res2: *u32 = &(try f2);
183
184 res0.* += 1;
185 res1.* += 1;
186 res2.* += 1;
187
188 try expect(f0 catch unreachable == 1);
189 try expect(f1 catch unreachable == 2);
190 try expect(f2 catch unreachable == 3);
191
192 try expect(res0.* == 1);
193 try expect(res1.* == 2);
194 try expect(res2.* == 3);
195 }
196 };
197 try S.doTheTest();
198 try comptime S.doTheTest();
199}