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(...@@ -1971,6 +1971,17 @@ fn comptimeExpr(
1971 .block_two, .block_two_semicolon, .block, .block_semicolon => {1971 .block_two, .block_two_semicolon, .block, .block_semicolon => {
1972 const token_tags = tree.tokens.items(.tag);1972 const token_tags = tree.tokens.items(.tag);
1973 const lbrace = main_tokens[node];1973 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 };
1974 if (token_tags[lbrace - 1] == .colon and1985 if (token_tags[lbrace - 1] == .colon and
1975 token_tags[lbrace - 2] == .identifier)1986 token_tags[lbrace - 2] == .identifier)
1976 {1987 {
...@@ -1985,17 +1996,13 @@ fn comptimeExpr(...@@ -1985,17 +1996,13 @@ fn comptimeExpr(
1985 else1996 else
1986 stmts[0..2];1997 stmts[0..2];
19871998
1988 // Careful! We can't pass in the real result location here, since it may1999 const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmt_slice, true);
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);
1993 return rvalue(gz, ri, block_ref, node);2000 return rvalue(gz, ri, block_ref, node);
1994 },2001 },
1995 .block, .block_semicolon => {2002 .block, .block_semicolon => {
1996 const stmts = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];2003 const stmts = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
1997 // Replace result location and copy back later - see above.2004 // 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);
1999 return rvalue(gz, ri, block_ref, node);2006 return rvalue(gz, ri, block_ref, node);
2000 },2007 },
2001 else => unreachable,2008 else => unreachable,
...@@ -2013,7 +2020,14 @@ fn comptimeExpr(...@@ -2013,7 +2020,14 @@ fn comptimeExpr(
20132020
2014 const block_inst = try gz.makeBlockInst(.block_comptime, node);2021 const block_inst = try gz.makeBlockInst(.block_comptime, node);
2015 // Replace result location and copy back later - see above.2022 // 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);
2017 if (!gz.refIsNoReturn(block_result)) {2031 if (!gz.refIsNoReturn(block_result)) {
2018 _ = try block_scope.addBreak(.@"break", block_inst, block_result);2032 _ = try block_scope.addBreak(.@"break", block_inst, block_result);
2019 }2033 }
test/behavior/cast.zig+5
...@@ -2522,3 +2522,8 @@ test "@intCast vector of signed integer" {...@@ -2522,3 +2522,8 @@ test "@intCast vector of signed integer" {
2522 try expect(y[2] == 3);2522 try expect(y[2] == 3);
2523 try expect(y[3] == 4);2523 try expect(y[3] == 4);
2524}2524}
2525
2526test "result type is preserved into comptime block" {
2527 const x: u32 = comptime @intCast(123);
2528 try expect(x == 123);
2529}