authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-11 22:21:33-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-12 01:57:07-04:00
logffc116de78dee6db8b3f2e0474f21bd88ef3895c
tree6de533285533bf39714a975a6c45a532a52a738e
parent5e0107fbce8f33f84af232c3edc912a81615175f

AstGen: fix src loc for invalid if expression rls coercions

Closes #12509

2 files changed, 65 insertions(+), 14 deletions(-)

src/AstGen.zig+33-14
......@@ -5657,7 +5657,7 @@ fn finishThenElseBlock(
56575657 0;
56585658
56595659 if (strat.elide_store_to_block_ptr_instructions) {
5660 try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, then_break, else_scope, else_break, block_scope.rl_ptr);
5660 try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, then_break, then_src_node, else_scope, else_break, else_src_node, block_scope.rl_ptr);
56615661 } else {
56625662 try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break);
56635663 }
......@@ -6082,8 +6082,10 @@ fn setCondBrPayloadElideBlockStorePtr(
60826082 cond: Zir.Inst.Ref,
60836083 then_scope: *GenZir,
60846084 then_break: Zir.Inst.Index,
6085 then_src_node: Ast.Node.Index,
60856086 else_scope: *GenZir,
60866087 else_break: Zir.Inst.Index,
6088 else_src_node: Ast.Node.Index,
60876089 block_ptr: Zir.Inst.Ref,
60886090) !void {
60896091 defer then_scope.unstack();
......@@ -6097,7 +6099,8 @@ fn setCondBrPayloadElideBlockStorePtr(
60976099 const else_body_len = astgen.countBodyLenAfterFixups(else_body) + @intFromBool(has_else_break);
60986100 try astgen.extra.ensureUnusedCapacity(
60996101 astgen.gpa,
6100 @typeInfo(Zir.Inst.CondBr).Struct.fields.len + then_body_len + else_body_len,
6102 @typeInfo(Zir.Inst.CondBr).Struct.fields.len + then_body_len + else_body_len +
6103 @typeInfo(Zir.Inst.As).Struct.fields.len * 2,
61016104 );
61026105
61036106 const zir_tags = astgen.instructions.items(.tag);
......@@ -6117,17 +6120,13 @@ fn setCondBrPayloadElideBlockStorePtr(
61176120 // `store_to_block_ptr` instruction with an `as` instruction and repurpose
61186121 // it as the break operand.
61196122 // This corresponds to similar code in `labeledBlockExpr`.
6123 var then_as_inst: Zir.Inst.Index = 0;
61206124 for (then_body) |src_inst| {
61216125 if (zir_tags[src_inst] == .store_to_block_ptr and
61226126 zir_datas[src_inst].bin.lhs == block_ptr)
61236127 {
61246128 if (then_scope.rl_ty_inst != .none and has_then_break) {
6125 zir_tags[src_inst] = .as;
6126 zir_datas[src_inst].bin = .{
6127 .lhs = then_scope.rl_ty_inst,
6128 .rhs = zir_datas[then_break].@"break".operand,
6129 };
6130 zir_datas[then_break].@"break".operand = indexToRef(src_inst);
6129 then_as_inst = src_inst;
61316130 } else {
61326131 astgen.extra.items[then_body_len_index] -= 1;
61336132 continue;
......@@ -6137,17 +6136,13 @@ fn setCondBrPayloadElideBlockStorePtr(
61376136 }
61386137 if (has_then_break) astgen.extra.appendAssumeCapacity(then_break);
61396138
6139 var else_as_inst: Zir.Inst.Index = 0;
61406140 for (else_body) |src_inst| {
61416141 if (zir_tags[src_inst] == .store_to_block_ptr and
61426142 zir_datas[src_inst].bin.lhs == block_ptr)
61436143 {
61446144 if (else_scope.rl_ty_inst != .none and has_else_break) {
6145 zir_tags[src_inst] = .as;
6146 zir_datas[src_inst].bin = .{
6147 .lhs = else_scope.rl_ty_inst,
6148 .rhs = zir_datas[else_break].@"break".operand,
6149 };
6150 zir_datas[else_break].@"break".operand = indexToRef(src_inst);
6145 else_as_inst = src_inst;
61516146 } else {
61526147 astgen.extra.items[else_body_len_index] -= 1;
61536148 continue;
......@@ -6156,6 +6151,30 @@ fn setCondBrPayloadElideBlockStorePtr(
61566151 appendPossiblyRefdBodyInst(astgen, &astgen.extra, src_inst);
61576152 }
61586153 if (has_else_break) astgen.extra.appendAssumeCapacity(else_break);
6154
6155 if (then_as_inst != 0) {
6156 zir_tags[then_as_inst] = .as_node;
6157 zir_datas[then_as_inst] = .{ .pl_node = .{
6158 .src_node = then_scope.nodeIndexToRelative(then_src_node),
6159 .payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.As{
6160 .dest_type = then_scope.rl_ty_inst,
6161 .operand = zir_datas[then_break].@"break".operand,
6162 }),
6163 } };
6164 zir_datas[then_break].@"break".operand = indexToRef(then_as_inst);
6165 }
6166
6167 if (else_as_inst != 0) {
6168 zir_tags[else_as_inst] = .as_node;
6169 zir_datas[else_as_inst] = .{ .pl_node = .{
6170 .src_node = else_scope.nodeIndexToRelative(else_src_node),
6171 .payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.As{
6172 .dest_type = else_scope.rl_ty_inst,
6173 .operand = zir_datas[else_break].@"break".operand,
6174 }),
6175 } };
6176 zir_datas[else_break].@"break".operand = indexToRef(else_as_inst);
6177 }
61596178}
61606179
61616180fn whileExpr(
test/cases/compile_errors/invalid_if_expr_result_location_coercion.zig created+32
......@@ -0,0 +1,32 @@
1export fn invalidRuntimeThen(cond: bool) u0 {
2 const invalid: u16 = 256;
3 const result: u8 = if (cond) invalid else 0;
4 return result;
5}
6
7export fn invalidComptimeThen() u0 {
8 const invalid: u16 = 256;
9 const result: u8 = if (true) invalid else 0;
10 return result;
11}
12
13export fn invalidRuntimeElse(cond: bool) u0 {
14 const invalid: u16 = 256;
15 const result: u8 = if (cond) 0 else invalid;
16 return result;
17}
18
19export fn invalidComptimeElse() u0 {
20 const invalid: u16 = 256;
21 const result: u8 = if (false) 0 else invalid;
22 return result;
23}
24
25// error
26// backend=stage2
27// target=native
28//
29// :3:34: error: type 'u8' cannot represent integer value '256'
30// :9:34: error: type 'u8' cannot represent integer value '256'
31// :15:41: error: type 'u8' cannot represent integer value '256'
32// :21:42: error: type 'u8' cannot represent integer value '256'