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(...@@ -5657,7 +5657,7 @@ fn finishThenElseBlock(
5657 0;5657 0;
56585658
5659 if (strat.elide_store_to_block_ptr_instructions) {5659 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);
5661 } else {5661 } else {
5662 try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break);5662 try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break);
5663 }5663 }
...@@ -6082,8 +6082,10 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6082,8 +6082,10 @@ fn setCondBrPayloadElideBlockStorePtr(
6082 cond: Zir.Inst.Ref,6082 cond: Zir.Inst.Ref,
6083 then_scope: *GenZir,6083 then_scope: *GenZir,
6084 then_break: Zir.Inst.Index,6084 then_break: Zir.Inst.Index,
6085 then_src_node: Ast.Node.Index,
6085 else_scope: *GenZir,6086 else_scope: *GenZir,
6086 else_break: Zir.Inst.Index,6087 else_break: Zir.Inst.Index,
6088 else_src_node: Ast.Node.Index,
6087 block_ptr: Zir.Inst.Ref,6089 block_ptr: Zir.Inst.Ref,
6088) !void {6090) !void {
6089 defer then_scope.unstack();6091 defer then_scope.unstack();
...@@ -6097,7 +6099,8 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6097,7 +6099,8 @@ fn setCondBrPayloadElideBlockStorePtr(
6097 const else_body_len = astgen.countBodyLenAfterFixups(else_body) + @intFromBool(has_else_break);6099 const else_body_len = astgen.countBodyLenAfterFixups(else_body) + @intFromBool(has_else_break);
6098 try astgen.extra.ensureUnusedCapacity(6100 try astgen.extra.ensureUnusedCapacity(
6099 astgen.gpa,6101 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,
6101 );6104 );
61026105
6103 const zir_tags = astgen.instructions.items(.tag);6106 const zir_tags = astgen.instructions.items(.tag);
...@@ -6117,17 +6120,13 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6117,17 +6120,13 @@ fn setCondBrPayloadElideBlockStorePtr(
6117 // `store_to_block_ptr` instruction with an `as` instruction and repurpose6120 // `store_to_block_ptr` instruction with an `as` instruction and repurpose
6118 // it as the break operand.6121 // it as the break operand.
6119 // This corresponds to similar code in `labeledBlockExpr`.6122 // This corresponds to similar code in `labeledBlockExpr`.
6123 var then_as_inst: Zir.Inst.Index = 0;
6120 for (then_body) |src_inst| {6124 for (then_body) |src_inst| {
6121 if (zir_tags[src_inst] == .store_to_block_ptr and6125 if (zir_tags[src_inst] == .store_to_block_ptr and
6122 zir_datas[src_inst].bin.lhs == block_ptr)6126 zir_datas[src_inst].bin.lhs == block_ptr)
6123 {6127 {
6124 if (then_scope.rl_ty_inst != .none and has_then_break) {6128 if (then_scope.rl_ty_inst != .none and has_then_break) {
6125 zir_tags[src_inst] = .as;6129 then_as_inst = src_inst;
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);
6131 } else {6130 } else {
6132 astgen.extra.items[then_body_len_index] -= 1;6131 astgen.extra.items[then_body_len_index] -= 1;
6133 continue;6132 continue;
...@@ -6137,17 +6136,13 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6137,17 +6136,13 @@ fn setCondBrPayloadElideBlockStorePtr(
6137 }6136 }
6138 if (has_then_break) astgen.extra.appendAssumeCapacity(then_break);6137 if (has_then_break) astgen.extra.appendAssumeCapacity(then_break);
61396138
6139 var else_as_inst: Zir.Inst.Index = 0;
6140 for (else_body) |src_inst| {6140 for (else_body) |src_inst| {
6141 if (zir_tags[src_inst] == .store_to_block_ptr and6141 if (zir_tags[src_inst] == .store_to_block_ptr and
6142 zir_datas[src_inst].bin.lhs == block_ptr)6142 zir_datas[src_inst].bin.lhs == block_ptr)
6143 {6143 {
6144 if (else_scope.rl_ty_inst != .none and has_else_break) {6144 if (else_scope.rl_ty_inst != .none and has_else_break) {
6145 zir_tags[src_inst] = .as;6145 else_as_inst = src_inst;
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);
6151 } else {6146 } else {
6152 astgen.extra.items[else_body_len_index] -= 1;6147 astgen.extra.items[else_body_len_index] -= 1;
6153 continue;6148 continue;
...@@ -6156,6 +6151,30 @@ fn setCondBrPayloadElideBlockStorePtr(...@@ -6156,6 +6151,30 @@ fn setCondBrPayloadElideBlockStorePtr(
6156 appendPossiblyRefdBodyInst(astgen, &astgen.extra, src_inst);6151 appendPossiblyRefdBodyInst(astgen, &astgen.extra, src_inst);
6157 }6152 }
6158 if (has_else_break) astgen.extra.appendAssumeCapacity(else_break);6153 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 }
6159}6178}
61606179
6161fn whileExpr(6180fn 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'