AstGen: fix src loc for invalid if expression rls coercions

Closes #12509
This commit is contained in:
Jacob Young 2023-08-11 22:21:33 -04:00
parent 5e0107fbce
commit ffc116de78
2 changed files with 65 additions and 14 deletions

View file

@ -5657,7 +5657,7 @@ fn finishThenElseBlock(
0; 0;
if (strat.elide_store_to_block_ptr_instructions) { if (strat.elide_store_to_block_ptr_instructions) {
try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, then_break, else_scope, else_break, block_scope.rl_ptr); try setCondBrPayloadElideBlockStorePtr(condbr, cond, then_scope, then_break, then_src_node, else_scope, else_break, else_src_node, block_scope.rl_ptr);
} else { } else {
try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break); try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break);
} }
@ -6082,8 +6082,10 @@ fn setCondBrPayloadElideBlockStorePtr(
cond: Zir.Inst.Ref, cond: Zir.Inst.Ref,
then_scope: *GenZir, then_scope: *GenZir,
then_break: Zir.Inst.Index, then_break: Zir.Inst.Index,
then_src_node: Ast.Node.Index,
else_scope: *GenZir, else_scope: *GenZir,
else_break: Zir.Inst.Index, else_break: Zir.Inst.Index,
else_src_node: Ast.Node.Index,
block_ptr: Zir.Inst.Ref, block_ptr: Zir.Inst.Ref,
) !void { ) !void {
defer then_scope.unstack(); defer then_scope.unstack();
@ -6097,7 +6099,8 @@ fn setCondBrPayloadElideBlockStorePtr(
const else_body_len = astgen.countBodyLenAfterFixups(else_body) + @intFromBool(has_else_break); const else_body_len = astgen.countBodyLenAfterFixups(else_body) + @intFromBool(has_else_break);
try astgen.extra.ensureUnusedCapacity( try astgen.extra.ensureUnusedCapacity(
astgen.gpa, astgen.gpa,
@typeInfo(Zir.Inst.CondBr).Struct.fields.len + then_body_len + else_body_len, @typeInfo(Zir.Inst.CondBr).Struct.fields.len + then_body_len + else_body_len +
@typeInfo(Zir.Inst.As).Struct.fields.len * 2,
); );
const zir_tags = astgen.instructions.items(.tag); const zir_tags = astgen.instructions.items(.tag);
@ -6117,17 +6120,13 @@ fn setCondBrPayloadElideBlockStorePtr(
// `store_to_block_ptr` instruction with an `as` instruction and repurpose // `store_to_block_ptr` instruction with an `as` instruction and repurpose
// it as the break operand. // it as the break operand.
// This corresponds to similar code in `labeledBlockExpr`. // This corresponds to similar code in `labeledBlockExpr`.
var then_as_inst: Zir.Inst.Index = 0;
for (then_body) |src_inst| { for (then_body) |src_inst| {
if (zir_tags[src_inst] == .store_to_block_ptr and if (zir_tags[src_inst] == .store_to_block_ptr and
zir_datas[src_inst].bin.lhs == block_ptr) zir_datas[src_inst].bin.lhs == block_ptr)
{ {
if (then_scope.rl_ty_inst != .none and has_then_break) { if (then_scope.rl_ty_inst != .none and has_then_break) {
zir_tags[src_inst] = .as; then_as_inst = src_inst;
zir_datas[src_inst].bin = .{
.lhs = then_scope.rl_ty_inst,
.rhs = zir_datas[then_break].@"break".operand,
};
zir_datas[then_break].@"break".operand = indexToRef(src_inst);
} else { } else {
astgen.extra.items[then_body_len_index] -= 1; astgen.extra.items[then_body_len_index] -= 1;
continue; continue;
@ -6137,17 +6136,13 @@ fn setCondBrPayloadElideBlockStorePtr(
} }
if (has_then_break) astgen.extra.appendAssumeCapacity(then_break); if (has_then_break) astgen.extra.appendAssumeCapacity(then_break);
var else_as_inst: Zir.Inst.Index = 0;
for (else_body) |src_inst| { for (else_body) |src_inst| {
if (zir_tags[src_inst] == .store_to_block_ptr and if (zir_tags[src_inst] == .store_to_block_ptr and
zir_datas[src_inst].bin.lhs == block_ptr) zir_datas[src_inst].bin.lhs == block_ptr)
{ {
if (else_scope.rl_ty_inst != .none and has_else_break) { if (else_scope.rl_ty_inst != .none and has_else_break) {
zir_tags[src_inst] = .as; else_as_inst = src_inst;
zir_datas[src_inst].bin = .{
.lhs = else_scope.rl_ty_inst,
.rhs = zir_datas[else_break].@"break".operand,
};
zir_datas[else_break].@"break".operand = indexToRef(src_inst);
} else { } else {
astgen.extra.items[else_body_len_index] -= 1; astgen.extra.items[else_body_len_index] -= 1;
continue; continue;
@ -6156,6 +6151,30 @@ fn setCondBrPayloadElideBlockStorePtr(
appendPossiblyRefdBodyInst(astgen, &astgen.extra, src_inst); appendPossiblyRefdBodyInst(astgen, &astgen.extra, src_inst);
} }
if (has_else_break) astgen.extra.appendAssumeCapacity(else_break); if (has_else_break) astgen.extra.appendAssumeCapacity(else_break);
if (then_as_inst != 0) {
zir_tags[then_as_inst] = .as_node;
zir_datas[then_as_inst] = .{ .pl_node = .{
.src_node = then_scope.nodeIndexToRelative(then_src_node),
.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.As{
.dest_type = then_scope.rl_ty_inst,
.operand = zir_datas[then_break].@"break".operand,
}),
} };
zir_datas[then_break].@"break".operand = indexToRef(then_as_inst);
}
if (else_as_inst != 0) {
zir_tags[else_as_inst] = .as_node;
zir_datas[else_as_inst] = .{ .pl_node = .{
.src_node = else_scope.nodeIndexToRelative(else_src_node),
.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.As{
.dest_type = else_scope.rl_ty_inst,
.operand = zir_datas[else_break].@"break".operand,
}),
} };
zir_datas[else_break].@"break".operand = indexToRef(else_as_inst);
}
} }
fn whileExpr( fn whileExpr(

View file

@ -0,0 +1,32 @@
export fn invalidRuntimeThen(cond: bool) u0 {
const invalid: u16 = 256;
const result: u8 = if (cond) invalid else 0;
return result;
}
export fn invalidComptimeThen() u0 {
const invalid: u16 = 256;
const result: u8 = if (true) invalid else 0;
return result;
}
export fn invalidRuntimeElse(cond: bool) u0 {
const invalid: u16 = 256;
const result: u8 = if (cond) 0 else invalid;
return result;
}
export fn invalidComptimeElse() u0 {
const invalid: u16 = 256;
const result: u8 = if (false) 0 else invalid;
return result;
}
// error
// backend=stage2
// target=native
//
// :3:34: error: type 'u8' cannot represent integer value '256'
// :9:34: error: type 'u8' cannot represent integer value '256'
// :15:41: error: type 'u8' cannot represent integer value '256'
// :21:42: error: type 'u8' cannot represent integer value '256'