stage2: forward discard result loc to more expressions

This commit is contained in:
Veikka Tuominen
2022-02-27 13:32:55 +02:00
parent 813f368a3c
commit 7a92b89a9d
3 changed files with 43 additions and 3 deletions

View File

@@ -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();

View File

@@ -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);
},

View File

@@ -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 {};
}