Commit 7a92b89a9d

Veikka Tuominen <git@vexu.eu>
2022-02-27 12:32:55
stage2: forward discard result loc to more expressions
1 parent 813f368
Changed files (3)
lib
src
test
behavior
lib/std/Progress.zig
@@ -289,10 +289,9 @@ fn refreshWithHeldLock(self: *Progress) void {
         }
     }
 
-    _ = file.write(self.output_buffer[0..end]) catch blk: {
+    _ = file.write(self.output_buffer[0..end]) catch {
         // Stop trying to write to this file once it errors.
         self.terminal = null;
-        break :blk 0; // TODO stage2 requires this
     };
     if (self.timer) |*timer| {
         self.prev_refresh_timestamp = timer.read();
src/AstGen.zig
@@ -244,10 +244,14 @@ pub const ResultLoc = union(enum) {
     fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy {
         switch (rl) {
             // In this branch there will not be any store_to_block_ptr instructions.
-            .discard, .none, .ty, .coerced_ty, .ref => return .{
+            .none, .ty, .coerced_ty, .ref => return .{
                 .tag = .break_operand,
                 .elide_store_to_block_ptr_instructions = false,
             },
+            .discard => return .{
+                .tag = .break_void,
+                .elide_store_to_block_ptr_instructions = false,
+            },
             // The pointer got passed through to the sub-expressions, so we will use
             // break_void here.
             // In this branch there will not be any store_to_block_ptr instructions.
@@ -1766,6 +1770,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
                         // we assume the result location is written, and we break with void.
                         _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
                     },
+                    .discard => {
+                        _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
+                    },
                     else => {
                         _ = try parent_gz.addBreak(break_tag, block_inst, operand);
                     },
test/behavior/basic.zig
@@ -819,3 +819,37 @@ test "if expression type coercion" {
     const x: u16 = if (cond) 1 else 0;
     try expect(@as(u16, x) == 1);
 }
+
+test "discarding the result of various expressions" {
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn foo() !u32 {
+            return 1;
+        }
+        fn bar() ?u32 {
+            return 1;
+        }
+    };
+    _ = S.bar() orelse {
+        // do nothing
+    };
+    _ = S.foo() catch {
+        // do nothing
+    };
+    _ = switch (1) {
+        1 => 1,
+        2 => {},
+        else => return,
+    };
+    _ = try S.foo();
+    _ = if (S.bar()) |some| some else {};
+    _ = blk: {
+        if (S.bar()) |some| break :blk some;
+        break :blk;
+    };
+    _ = while (S.bar()) |some| break some else {};
+    _ = for ("foo") |char| break char else {};
+}