aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-08-27 18:48:01 +0300
committerAndrew Kelley <andrew@ziglang.org>2022-09-12 01:52:44 -0400
commite323cf1264f390911dcc2efea71d46be1d631d92 (patch)
treeffe4c716e299e94ef1ed797f32aed8451e8090c9 /test
parentc97d64b677eb891144fb356e1f4b9011c60cc0e2 (diff)
downloadzig-e323cf1264f390911dcc2efea71d46be1d631d92.tar.gz
zig-e323cf1264f390911dcc2efea71d46be1d631d92.zip
stage2: change how defers are stored in Zir
Storing defers this way has the benefits that the defer doesn't get analyzed multiple times in AstGen, it takes up less space, and it makes Sema aware of defers allowing for 'unreachable else prong' error on error sets in generic code. The disadvantage is that it is a bit more complex and errdefers with payloads now emit a placeholder instruction (but those are rare). Sema.zig before: Total ZIR bytes: 3.7794370651245117MiB Instructions: 238996 (2.051319122314453MiB) String Table Bytes: 89.2802734375KiB Extra Data Items: 430144 (1.640869140625MiB) Sema.zig after: Total ZIR bytes: 3.3344192504882812MiB Instructions: 211829 (1.8181428909301758MiB) String Table Bytes: 89.2802734375KiB Extra Data Items: 374611 (1.4290275573730469MiB)
Diffstat (limited to 'test')
-rw-r--r--test/behavior/defer.zig17
-rw-r--r--test/cases/compile_errors/return_from_defer_expression.zig1
-rw-r--r--test/cases/compile_errors/uncreachable_else_prong_err_set.zig25
-rw-r--r--test/cases/returns_in_try.zig2
4 files changed, 45 insertions, 0 deletions
diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig
index 70053ba01f..7bf66496a4 100644
--- a/test/behavior/defer.zig
+++ b/test/behavior/defer.zig
@@ -127,3 +127,20 @@ test "errdefer with payload" {
try S.doTheTest();
comptime try S.doTheTest();
}
+
+test "simple else prong doesn't emit an error for unreachable else prong" {
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+
+ const S = struct {
+ fn foo() error{Foo}!void {
+ return error.Foo;
+ }
+ };
+ var a: u32 = 0;
+ defer a += 1;
+ S.foo() catch |err| switch (err) {
+ error.Foo => a += 1,
+ else => |e| return e,
+ };
+ try expect(a == 1);
+}
diff --git a/test/cases/compile_errors/return_from_defer_expression.zig b/test/cases/compile_errors/return_from_defer_expression.zig
index e60b8ae848..12aa08a11c 100644
--- a/test/cases/compile_errors/return_from_defer_expression.zig
+++ b/test/cases/compile_errors/return_from_defer_expression.zig
@@ -19,3 +19,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(testTrickyDefer)); }
// target=native
//
// :4:11: error: 'try' not allowed inside defer expression
+// :4:5: note: defer expression here
diff --git a/test/cases/compile_errors/uncreachable_else_prong_err_set.zig b/test/cases/compile_errors/uncreachable_else_prong_err_set.zig
new file mode 100644
index 0000000000..4b0ae462d6
--- /dev/null
+++ b/test/cases/compile_errors/uncreachable_else_prong_err_set.zig
@@ -0,0 +1,25 @@
+pub export fn complex() void {
+ var a: error{ Foo, Bar } = error.Foo;
+ switch (a) {
+ error.Foo => unreachable,
+ error.Bar => unreachable,
+ else => {
+ @compileError("<something complex here>");
+ },
+ }
+}
+
+pub export fn simple() void {
+ var a: error{ Foo, Bar } = error.Foo;
+ switch (a) {
+ error.Foo => unreachable,
+ error.Bar => unreachable,
+ else => |e| return e,
+ }
+}
+
+// error
+// backend=llvm
+// target=native
+//
+// :6:14: error: unreachable else prong; all cases already handled
diff --git a/test/cases/returns_in_try.zig b/test/cases/returns_in_try.zig
index de5a9a3258..e283b93db2 100644
--- a/test/cases/returns_in_try.zig
+++ b/test/cases/returns_in_try.zig
@@ -13,4 +13,6 @@ pub fn b() !void {
// error
//
// :7:11: error: 'try' not allowed inside defer expression
+// :7:5: note: defer expression here
// :10:11: error: cannot return from defer expression
+// :10:5: note: defer expression here