AstGen: preserve result type in comptime block

This commit is contained in:
mlugg
2023-11-17 04:58:49 +00:00
parent 38b373bf0b
commit 3c585730f2
2 changed files with 26 additions and 7 deletions

View File

@@ -1971,6 +1971,17 @@ fn comptimeExpr(
.block_two, .block_two_semicolon, .block, .block_semicolon => {
const token_tags = tree.tokens.items(.tag);
const lbrace = main_tokens[node];
// Careful! We can't pass in the real result location here, since it may
// refer to runtime memory. A runtime-to-comptime boundary has to remove
// result location information, compute the result, and copy it to the true
// result location at runtime. We do this below as well.
const ty_only_ri: ResultInfo = .{
.ctx = ri.ctx,
.rl = if (try ri.rl.resultType(gz, node)) |res_ty|
.{ .coerced_ty = res_ty }
else
.none,
};
if (token_tags[lbrace - 1] == .colon and
token_tags[lbrace - 2] == .identifier)
{
@@ -1985,17 +1996,13 @@ fn comptimeExpr(
else
stmts[0..2];
// Careful! We can't pass in the real result location here, since it may
// refer to runtime memory. A runtime-to-comptime boundary has to remove
// result location information, compute the result, and copy it to the true
// result location at runtime. We do this below as well.
const block_ref = try labeledBlockExpr(gz, scope, .{ .rl = .none }, node, stmt_slice, true);
const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmt_slice, true);
return rvalue(gz, ri, block_ref, node);
},
.block, .block_semicolon => {
const stmts = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
// Replace result location and copy back later - see above.
const block_ref = try labeledBlockExpr(gz, scope, .{ .rl = .none }, node, stmts, true);
const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmts, true);
return rvalue(gz, ri, block_ref, node);
},
else => unreachable,
@@ -2013,7 +2020,14 @@ fn comptimeExpr(
const block_inst = try gz.makeBlockInst(.block_comptime, node);
// Replace result location and copy back later - see above.
const block_result = try expr(&block_scope, scope, .{ .rl = .none }, node);
const ty_only_ri: ResultInfo = .{
.ctx = ri.ctx,
.rl = if (try ri.rl.resultType(gz, node)) |res_ty|
.{ .coerced_ty = res_ty }
else
.none,
};
const block_result = try expr(&block_scope, scope, ty_only_ri, node);
if (!gz.refIsNoReturn(block_result)) {
_ = try block_scope.addBreak(.@"break", block_inst, block_result);
}

View File

@@ -2522,3 +2522,8 @@ test "@intCast vector of signed integer" {
try expect(y[2] == 3);
try expect(y[3] == 4);
}
test "result type is preserved into comptime block" {
const x: u32 = comptime @intCast(123);
try expect(x == 123);
}