authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-11-17 04:58:49+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-11-19 11:11:50+00:00
log3c585730f2d259963716684ede87dcfce2607973
tree36b5011dde6d6438528e8a8c3d5da2ada5f21c24
parent38b373bf0b78bfe3b332c9fbb115e2ce3e9768d0
signaturelock-open Commit is signed but in an unrecognized format.

AstGen: preserve result type in comptime block


2 files changed, 26 insertions(+), 7 deletions(-)

src/AstGen.zig+21-7
......@@ -1971,6 +1971,17 @@ fn comptimeExpr(
19711971 .block_two, .block_two_semicolon, .block, .block_semicolon => {
19721972 const token_tags = tree.tokens.items(.tag);
19731973 const lbrace = main_tokens[node];
1974 // Careful! We can't pass in the real result location here, since it may
1975 // refer to runtime memory. A runtime-to-comptime boundary has to remove
1976 // result location information, compute the result, and copy it to the true
1977 // result location at runtime. We do this below as well.
1978 const ty_only_ri: ResultInfo = .{
1979 .ctx = ri.ctx,
1980 .rl = if (try ri.rl.resultType(gz, node)) |res_ty|
1981 .{ .coerced_ty = res_ty }
1982 else
1983 .none,
1984 };
19741985 if (token_tags[lbrace - 1] == .colon and
19751986 token_tags[lbrace - 2] == .identifier)
19761987 {
......@@ -1985,17 +1996,13 @@ fn comptimeExpr(
19851996 else
19861997 stmts[0..2];
19871998
1988 // Careful! We can't pass in the real result location here, since it may
1989 // refer to runtime memory. A runtime-to-comptime boundary has to remove
1990 // result location information, compute the result, and copy it to the true
1991 // result location at runtime. We do this below as well.
1992 const block_ref = try labeledBlockExpr(gz, scope, .{ .rl = .none }, node, stmt_slice, true);
1999 const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmt_slice, true);
19932000 return rvalue(gz, ri, block_ref, node);
19942001 },
19952002 .block, .block_semicolon => {
19962003 const stmts = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
19972004 // Replace result location and copy back later - see above.
1998 const block_ref = try labeledBlockExpr(gz, scope, .{ .rl = .none }, node, stmts, true);
2005 const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmts, true);
19992006 return rvalue(gz, ri, block_ref, node);
20002007 },
20012008 else => unreachable,
......@@ -2013,7 +2020,14 @@ fn comptimeExpr(
20132020
20142021 const block_inst = try gz.makeBlockInst(.block_comptime, node);
20152022 // Replace result location and copy back later - see above.
2016 const block_result = try expr(&block_scope, scope, .{ .rl = .none }, node);
2023 const ty_only_ri: ResultInfo = .{
2024 .ctx = ri.ctx,
2025 .rl = if (try ri.rl.resultType(gz, node)) |res_ty|
2026 .{ .coerced_ty = res_ty }
2027 else
2028 .none,
2029 };
2030 const block_result = try expr(&block_scope, scope, ty_only_ri, node);
20172031 if (!gz.refIsNoReturn(block_result)) {
20182032 _ = try block_scope.addBreak(.@"break", block_inst, block_result);
20192033 }
test/behavior/cast.zig+5
......@@ -2522,3 +2522,8 @@ test "@intCast vector of signed integer" {
25222522 try expect(y[2] == 3);
25232523 try expect(y[3] == 4);
25242524}
2525
2526test "result type is preserved into comptime block" {
2527 const x: u32 = comptime @intCast(123);
2528 try expect(x == 123);
2529}