mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 11:13:08 +00:00
Improve error messages for break type coercion
This commit is contained in:
parent
8642770eff
commit
ec445fb6b8
169
src/AstGen.zig
169
src/AstGen.zig
@ -1280,7 +1280,7 @@ fn fnProtoExpr(
|
|||||||
defer param_gz.unstack();
|
defer param_gz.unstack();
|
||||||
const param_type = try expr(¶m_gz, scope, coerced_type_ri, param_type_node);
|
const param_type = try expr(¶m_gz, scope, coerced_type_ri, param_type_node);
|
||||||
const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);
|
const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);
|
||||||
_ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type);
|
_ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);
|
||||||
const main_tokens = tree.nodes.items(.main_token);
|
const main_tokens = tree.nodes.items(.main_token);
|
||||||
const name_token = param.name_token orelse main_tokens[param_type_node];
|
const name_token = param.name_token orelse main_tokens[param_type_node];
|
||||||
const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param;
|
const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param;
|
||||||
@ -1991,7 +1991,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
|||||||
|
|
||||||
switch (block_gz.break_result_info.rl) {
|
switch (block_gz.break_result_info.rl) {
|
||||||
.block_ptr => {
|
.block_ptr => {
|
||||||
const br = try parent_gz.addBreak(break_tag, block_inst, operand);
|
const br = try parent_gz.addBreakWithSrcNode(break_tag, block_inst, operand, rhs);
|
||||||
try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index });
|
try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index });
|
||||||
},
|
},
|
||||||
.ptr => {
|
.ptr => {
|
||||||
@ -2003,7 +2003,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
|||||||
_ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
|
_ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
_ = try parent_gz.addBreak(break_tag, block_inst, operand);
|
_ = try parent_gz.addBreakWithSrcNode(break_tag, block_inst, operand, rhs);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return Zir.Inst.Ref.unreachable_value;
|
return Zir.Inst.Ref.unreachable_value;
|
||||||
@ -3754,7 +3754,7 @@ fn fnDecl(
|
|||||||
defer param_gz.unstack();
|
defer param_gz.unstack();
|
||||||
const param_type = try expr(¶m_gz, params_scope, coerced_type_ri, param_type_node);
|
const param_type = try expr(¶m_gz, params_scope, coerced_type_ri, param_type_node);
|
||||||
const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);
|
const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);
|
||||||
_ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type);
|
_ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);
|
||||||
|
|
||||||
const main_tokens = tree.nodes.items(.main_token);
|
const main_tokens = tree.nodes.items(.main_token);
|
||||||
const name_token = param.name_token orelse main_tokens[param_type_node];
|
const name_token = param.name_token orelse main_tokens[param_type_node];
|
||||||
@ -4114,7 +4114,7 @@ fn globalVarDecl(
|
|||||||
};
|
};
|
||||||
// We do this at the end so that the instruction index marks the end
|
// We do this at the end so that the instruction index marks the end
|
||||||
// range of a top level declaration.
|
// range of a top level declaration.
|
||||||
_ = try block_scope.addBreak(.break_inline, block_inst, var_inst);
|
_ = try block_scope.addBreakWithSrcNode(.break_inline, block_inst, var_inst, node);
|
||||||
try block_scope.setBlockBody(block_inst);
|
try block_scope.setBlockBody(block_inst);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -5456,7 +5456,9 @@ fn orelseCatchExpr(
|
|||||||
condbr,
|
condbr,
|
||||||
cond,
|
cond,
|
||||||
then_result,
|
then_result,
|
||||||
|
node,
|
||||||
else_result,
|
else_result,
|
||||||
|
rhs,
|
||||||
block,
|
block,
|
||||||
block,
|
block,
|
||||||
break_tag,
|
break_tag,
|
||||||
@ -5475,7 +5477,9 @@ fn finishThenElseBlock(
|
|||||||
condbr: Zir.Inst.Index,
|
condbr: Zir.Inst.Index,
|
||||||
cond: Zir.Inst.Ref,
|
cond: Zir.Inst.Ref,
|
||||||
then_result: Zir.Inst.Ref,
|
then_result: Zir.Inst.Ref,
|
||||||
|
then_src_node: Ast.Node.Index,
|
||||||
else_result: Zir.Inst.Ref,
|
else_result: Zir.Inst.Ref,
|
||||||
|
else_src_node: Ast.Node.Index,
|
||||||
main_block: Zir.Inst.Index,
|
main_block: Zir.Inst.Index,
|
||||||
then_break_block: Zir.Inst.Index,
|
then_break_block: Zir.Inst.Index,
|
||||||
break_tag: Zir.Inst.Tag,
|
break_tag: Zir.Inst.Tag,
|
||||||
@ -5498,11 +5502,11 @@ fn finishThenElseBlock(
|
|||||||
return indexToRef(main_block);
|
return indexToRef(main_block);
|
||||||
},
|
},
|
||||||
.break_operand => {
|
.break_operand => {
|
||||||
const then_break = if (!then_no_return) try then_scope.makeBreak(break_tag, then_break_block, then_result) else 0;
|
const then_break = if (!then_no_return) try then_scope.makeBreakWithSrcNode(break_tag, then_break_block, then_result, then_src_node) else 0;
|
||||||
const else_break = if (else_result == .none)
|
const else_break = if (else_result == .none)
|
||||||
try else_scope.makeBreak(break_tag, main_block, .void_value)
|
try else_scope.makeBreak(break_tag, main_block, .void_value)
|
||||||
else if (!else_no_return)
|
else if (!else_no_return)
|
||||||
try else_scope.makeBreak(break_tag, main_block, else_result)
|
try else_scope.makeBreakWithSrcNode(break_tag, main_block, else_result, else_src_node)
|
||||||
else
|
else
|
||||||
0;
|
0;
|
||||||
|
|
||||||
@ -5683,7 +5687,7 @@ fn boolBinOp(
|
|||||||
defer rhs_scope.unstack();
|
defer rhs_scope.unstack();
|
||||||
const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs);
|
const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs);
|
||||||
if (!gz.refIsNoReturn(rhs)) {
|
if (!gz.refIsNoReturn(rhs)) {
|
||||||
_ = try rhs_scope.addBreak(.break_inline, bool_br, rhs);
|
_ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs);
|
||||||
}
|
}
|
||||||
try rhs_scope.setBoolBrBody(bool_br);
|
try rhs_scope.setBoolBrBody(bool_br);
|
||||||
|
|
||||||
@ -5758,6 +5762,7 @@ fn ifExpr(
|
|||||||
var payload_val_scope: Scope.LocalVal = undefined;
|
var payload_val_scope: Scope.LocalVal = undefined;
|
||||||
|
|
||||||
try then_scope.addDbgBlockBegin();
|
try then_scope.addDbgBlockBegin();
|
||||||
|
const then_node = if_full.ast.then_expr;
|
||||||
const then_sub_scope = s: {
|
const then_sub_scope = s: {
|
||||||
if (if_full.error_token != null) {
|
if (if_full.error_token != null) {
|
||||||
if (if_full.payload_token) |payload_token| {
|
if (if_full.payload_token) |payload_token| {
|
||||||
@ -5765,7 +5770,7 @@ fn ifExpr(
|
|||||||
.err_union_payload_unsafe_ptr
|
.err_union_payload_unsafe_ptr
|
||||||
else
|
else
|
||||||
.err_union_payload_unsafe;
|
.err_union_payload_unsafe;
|
||||||
const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr);
|
const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);
|
||||||
const token_name_index = payload_token + @boolToInt(payload_is_ref);
|
const token_name_index = payload_token + @boolToInt(payload_is_ref);
|
||||||
const ident_name = try astgen.identAsString(token_name_index);
|
const ident_name = try astgen.identAsString(token_name_index);
|
||||||
const token_name_str = tree.tokenSlice(token_name_index);
|
const token_name_str = tree.tokenSlice(token_name_index);
|
||||||
@ -5795,7 +5800,7 @@ fn ifExpr(
|
|||||||
const ident_bytes = tree.tokenSlice(ident_token);
|
const ident_bytes = tree.tokenSlice(ident_token);
|
||||||
if (mem.eql(u8, "_", ident_bytes))
|
if (mem.eql(u8, "_", ident_bytes))
|
||||||
break :s &then_scope.base;
|
break :s &then_scope.base;
|
||||||
const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr);
|
const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);
|
||||||
const ident_name = try astgen.identAsString(ident_token);
|
const ident_name = try astgen.identAsString(ident_token);
|
||||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
|
try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
|
||||||
payload_val_scope = .{
|
payload_val_scope = .{
|
||||||
@ -5813,7 +5818,7 @@ fn ifExpr(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, if_full.ast.then_expr);
|
const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node);
|
||||||
if (!then_scope.endsWithNoReturn()) {
|
if (!then_scope.endsWithNoReturn()) {
|
||||||
block_scope.break_count += 1;
|
block_scope.break_count += 1;
|
||||||
}
|
}
|
||||||
@ -5878,7 +5883,7 @@ fn ifExpr(
|
|||||||
.result = e,
|
.result = e,
|
||||||
};
|
};
|
||||||
} else .{
|
} else .{
|
||||||
.src = if_full.ast.then_expr,
|
.src = then_node,
|
||||||
.result = switch (ri.rl) {
|
.result = switch (ri.rl) {
|
||||||
// Explicitly store void to ptr result loc if there is no else branch
|
// Explicitly store void to ptr result loc if there is no else branch
|
||||||
.ptr, .block_ptr => try rvalue(&else_scope, ri, .void_value, node),
|
.ptr, .block_ptr => try rvalue(&else_scope, ri, .void_value, node),
|
||||||
@ -5897,7 +5902,9 @@ fn ifExpr(
|
|||||||
condbr,
|
condbr,
|
||||||
cond.bool_bit,
|
cond.bool_bit,
|
||||||
then_result,
|
then_result,
|
||||||
|
then_node,
|
||||||
else_info.result,
|
else_info.result,
|
||||||
|
else_info.src,
|
||||||
block,
|
block,
|
||||||
block,
|
block,
|
||||||
break_tag,
|
break_tag,
|
||||||
@ -6185,6 +6192,7 @@ fn whileExpr(
|
|||||||
then_scope.instructions_top = then_scope.instructions.items.len;
|
then_scope.instructions_top = then_scope.instructions.items.len;
|
||||||
|
|
||||||
try then_scope.addDbgBlockBegin();
|
try then_scope.addDbgBlockBegin();
|
||||||
|
const then_node = while_full.ast.then_expr;
|
||||||
if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);
|
if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);
|
||||||
if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst);
|
if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst);
|
||||||
try then_scope.instructions.append(astgen.gpa, continue_block);
|
try then_scope.instructions.append(astgen.gpa, continue_block);
|
||||||
@ -6198,7 +6206,7 @@ fn whileExpr(
|
|||||||
try then_scope.addDbgBlockEnd();
|
try then_scope.addDbgBlockEnd();
|
||||||
|
|
||||||
continue_scope.instructions_top = continue_scope.instructions.items.len;
|
continue_scope.instructions_top = continue_scope.instructions.items.len;
|
||||||
_ = try unusedResultExpr(&continue_scope, &continue_scope.base, while_full.ast.then_expr);
|
_ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node);
|
||||||
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
||||||
const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
|
const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
|
||||||
if (!continue_scope.endsWithNoReturn()) {
|
if (!continue_scope.endsWithNoReturn()) {
|
||||||
@ -6261,7 +6269,7 @@ fn whileExpr(
|
|||||||
.result = else_result,
|
.result = else_result,
|
||||||
};
|
};
|
||||||
} else .{
|
} else .{
|
||||||
.src = while_full.ast.then_expr,
|
.src = then_node,
|
||||||
.result = .none,
|
.result = .none,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -6280,7 +6288,9 @@ fn whileExpr(
|
|||||||
condbr,
|
condbr,
|
||||||
cond.bool_bit,
|
cond.bool_bit,
|
||||||
.void_value,
|
.void_value,
|
||||||
|
then_node,
|
||||||
else_info.result,
|
else_info.result,
|
||||||
|
else_info.src,
|
||||||
loop_block,
|
loop_block,
|
||||||
cond_block,
|
cond_block,
|
||||||
break_tag,
|
break_tag,
|
||||||
@ -6468,6 +6478,7 @@ fn forExpr(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var then_node = for_full.ast.then_expr;
|
||||||
var then_scope = parent_gz.makeSubBlock(&cond_scope.base);
|
var then_scope = parent_gz.makeSubBlock(&cond_scope.base);
|
||||||
defer then_scope.unstack();
|
defer then_scope.unstack();
|
||||||
|
|
||||||
@ -6535,8 +6546,8 @@ fn forExpr(
|
|||||||
break :blk capture_sub_scope;
|
break :blk capture_sub_scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, for_full.ast.then_expr);
|
const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, then_node);
|
||||||
_ = try addEnsureResult(&then_scope, then_result, for_full.ast.then_expr);
|
_ = try addEnsureResult(&then_scope, then_result, then_node);
|
||||||
|
|
||||||
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
||||||
try then_scope.addDbgBlockEnd();
|
try then_scope.addDbgBlockEnd();
|
||||||
@ -6567,7 +6578,7 @@ fn forExpr(
|
|||||||
.result = else_result,
|
.result = else_result,
|
||||||
};
|
};
|
||||||
} else .{
|
} else .{
|
||||||
.src = for_full.ast.then_expr,
|
.src = then_node,
|
||||||
.result = .none,
|
.result = .none,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -6587,7 +6598,9 @@ fn forExpr(
|
|||||||
condbr,
|
condbr,
|
||||||
cond,
|
cond,
|
||||||
then_result,
|
then_result,
|
||||||
|
then_node,
|
||||||
else_info.result,
|
else_info.result,
|
||||||
|
else_info.src,
|
||||||
loop_block,
|
loop_block,
|
||||||
cond_block,
|
cond_block,
|
||||||
break_tag,
|
break_tag,
|
||||||
@ -6949,12 +6962,13 @@ fn switchExpr(
|
|||||||
if (dbg_var_tag_name) |some| {
|
if (dbg_var_tag_name) |some| {
|
||||||
try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst);
|
try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst);
|
||||||
}
|
}
|
||||||
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, case.ast.target_expr);
|
const target_expr_node = case.ast.target_expr;
|
||||||
|
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
|
||||||
try checkUsed(parent_gz, &case_scope.base, sub_scope);
|
try checkUsed(parent_gz, &case_scope.base, sub_scope);
|
||||||
try case_scope.addDbgBlockEnd();
|
try case_scope.addDbgBlockEnd();
|
||||||
if (!parent_gz.refIsNoReturn(case_result)) {
|
if (!parent_gz.refIsNoReturn(case_result)) {
|
||||||
block_scope.break_count += 1;
|
block_scope.break_count += 1;
|
||||||
_ = try case_scope.addBreak(.@"break", switch_block, case_result);
|
_ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
const case_slice = case_scope.instructionsSlice();
|
const case_slice = case_scope.instructionsSlice();
|
||||||
@ -7057,10 +7071,12 @@ fn switchExpr(
|
|||||||
.break_void => {
|
.break_void => {
|
||||||
assert(!strat.elide_store_to_block_ptr_instructions);
|
assert(!strat.elide_store_to_block_ptr_instructions);
|
||||||
const last_inst = payloads.items[end_index - 1];
|
const last_inst = payloads.items[end_index - 1];
|
||||||
if (zir_tags[last_inst] == .@"break" and
|
if (zir_tags[last_inst] == .@"break") {
|
||||||
zir_datas[last_inst].@"break".block_inst == switch_block)
|
const inst_data = zir_datas[last_inst].@"break";
|
||||||
{
|
const block_inst = astgen.extra.items[inst_data.payload_index];
|
||||||
zir_datas[last_inst].@"break".operand = .void_value;
|
if (block_inst == switch_block) {
|
||||||
|
zir_datas[last_inst].@"break".operand = .void_value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -8856,7 +8872,7 @@ fn callExpr(
|
|||||||
// `call_inst` is reused to provide the param type.
|
// `call_inst` is reused to provide the param type.
|
||||||
arg_block.rl_ty_inst = call_inst;
|
arg_block.rl_ty_inst = call_inst;
|
||||||
const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);
|
const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);
|
||||||
_ = try arg_block.addBreak(.break_inline, call_index, arg_ref);
|
_ = try arg_block.addBreakWithSrcNode(.break_inline, call_index, arg_ref, param_node);
|
||||||
|
|
||||||
const body = arg_block.instructionsSlice();
|
const body = arg_block.instructionsSlice();
|
||||||
try astgen.scratch.ensureUnusedCapacity(astgen.gpa, countBodyLenAfterFixups(astgen, body));
|
try astgen.scratch.ensureUnusedCapacity(astgen.gpa, countBodyLenAfterFixups(astgen, body));
|
||||||
@ -11262,35 +11278,40 @@ const GenZir = struct {
|
|||||||
if (align_body.len != 0) {
|
if (align_body.len != 0) {
|
||||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
|
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
|
||||||
astgen.appendBodyWithFixups(align_body);
|
astgen.appendBodyWithFixups(align_body);
|
||||||
zir_datas[align_body[align_body.len - 1]].@"break".block_inst = new_index;
|
const inst_data = zir_datas[align_body[align_body.len - 1]].@"break";
|
||||||
|
astgen.extra.items[inst_data.payload_index] = new_index;
|
||||||
} else if (args.align_ref != .none) {
|
} else if (args.align_ref != .none) {
|
||||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref));
|
astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref));
|
||||||
}
|
}
|
||||||
if (addrspace_body.len != 0) {
|
if (addrspace_body.len != 0) {
|
||||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
|
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
|
||||||
astgen.appendBodyWithFixups(addrspace_body);
|
astgen.appendBodyWithFixups(addrspace_body);
|
||||||
zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".block_inst = new_index;
|
const inst_data = zir_datas[addrspace_body[addrspace_body.len - 1]].@"break";
|
||||||
|
astgen.extra.items[inst_data.payload_index] = new_index;
|
||||||
} else if (args.addrspace_ref != .none) {
|
} else if (args.addrspace_ref != .none) {
|
||||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref));
|
astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref));
|
||||||
}
|
}
|
||||||
if (section_body.len != 0) {
|
if (section_body.len != 0) {
|
||||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
|
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
|
||||||
astgen.appendBodyWithFixups(section_body);
|
astgen.appendBodyWithFixups(section_body);
|
||||||
zir_datas[section_body[section_body.len - 1]].@"break".block_inst = new_index;
|
const inst_data = zir_datas[section_body[section_body.len - 1]].@"break";
|
||||||
|
astgen.extra.items[inst_data.payload_index] = new_index;
|
||||||
} else if (args.section_ref != .none) {
|
} else if (args.section_ref != .none) {
|
||||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref));
|
astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref));
|
||||||
}
|
}
|
||||||
if (cc_body.len != 0) {
|
if (cc_body.len != 0) {
|
||||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
|
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
|
||||||
astgen.appendBodyWithFixups(cc_body);
|
astgen.appendBodyWithFixups(cc_body);
|
||||||
zir_datas[cc_body[cc_body.len - 1]].@"break".block_inst = new_index;
|
const inst_data = zir_datas[cc_body[cc_body.len - 1]].@"break";
|
||||||
|
astgen.extra.items[inst_data.payload_index] = new_index;
|
||||||
} else if (args.cc_ref != .none) {
|
} else if (args.cc_ref != .none) {
|
||||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref));
|
astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref));
|
||||||
}
|
}
|
||||||
if (ret_body.len != 0) {
|
if (ret_body.len != 0) {
|
||||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
|
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
|
||||||
astgen.appendBodyWithFixups(ret_body);
|
astgen.appendBodyWithFixups(ret_body);
|
||||||
zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
|
const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";
|
||||||
|
astgen.extra.items[inst_data.payload_index] = new_index;
|
||||||
} else if (ret_ref != .none) {
|
} else if (ret_ref != .none) {
|
||||||
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
|
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
|
||||||
}
|
}
|
||||||
@ -11344,7 +11365,9 @@ const GenZir = struct {
|
|||||||
const zir_datas = astgen.instructions.items(.data);
|
const zir_datas = astgen.instructions.items(.data);
|
||||||
if (ret_body.len != 0) {
|
if (ret_body.len != 0) {
|
||||||
astgen.appendBodyWithFixups(ret_body);
|
astgen.appendBodyWithFixups(ret_body);
|
||||||
zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
|
|
||||||
|
const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";
|
||||||
|
astgen.extra.items[inst_data.payload_index] = new_index;
|
||||||
} else if (ret_ref != .none) {
|
} else if (ret_ref != .none) {
|
||||||
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
|
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
|
||||||
}
|
}
|
||||||
@ -11790,30 +11813,104 @@ const GenZir = struct {
|
|||||||
fn addBreak(
|
fn addBreak(
|
||||||
gz: *GenZir,
|
gz: *GenZir,
|
||||||
tag: Zir.Inst.Tag,
|
tag: Zir.Inst.Tag,
|
||||||
break_block: Zir.Inst.Index,
|
block_inst: Zir.Inst.Index,
|
||||||
operand: Zir.Inst.Ref,
|
operand: Zir.Inst.Ref,
|
||||||
) !Zir.Inst.Index {
|
) !Zir.Inst.Index {
|
||||||
return gz.addAsIndex(.{
|
const gpa = gz.astgen.gpa;
|
||||||
|
try gz.instructions.ensureUnusedCapacity(gpa, 1);
|
||||||
|
try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
|
||||||
|
|
||||||
|
const extra: Zir.Inst.Break = .{
|
||||||
|
.block_inst = block_inst,
|
||||||
|
.operand_src_node = Zir.Inst.Break.no_src_node,
|
||||||
|
};
|
||||||
|
const payload_index = try gz.astgen.addExtra(extra);
|
||||||
|
const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
|
||||||
|
gz.astgen.instructions.appendAssumeCapacity(.{
|
||||||
.tag = tag,
|
.tag = tag,
|
||||||
.data = .{ .@"break" = .{
|
.data = .{ .@"break" = .{
|
||||||
.block_inst = break_block,
|
|
||||||
.operand = operand,
|
.operand = operand,
|
||||||
|
.payload_index = payload_index,
|
||||||
} },
|
} },
|
||||||
});
|
});
|
||||||
|
gz.instructions.appendAssumeCapacity(new_index);
|
||||||
|
return new_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn makeBreak(
|
fn makeBreak(
|
||||||
gz: *GenZir,
|
gz: *GenZir,
|
||||||
tag: Zir.Inst.Tag,
|
tag: Zir.Inst.Tag,
|
||||||
break_block: Zir.Inst.Index,
|
block_inst: Zir.Inst.Index,
|
||||||
operand: Zir.Inst.Ref,
|
operand: Zir.Inst.Ref,
|
||||||
) !Zir.Inst.Index {
|
) !Zir.Inst.Index {
|
||||||
|
const gpa = gz.astgen.gpa;
|
||||||
|
try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
|
||||||
|
|
||||||
|
const extra: Zir.Inst.Break = .{
|
||||||
|
.block_inst = block_inst,
|
||||||
|
.operand_src_node = Zir.Inst.Break.no_src_node,
|
||||||
|
};
|
||||||
|
const payload_index = try gz.astgen.addExtra(extra);
|
||||||
const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
|
const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
|
||||||
try gz.astgen.instructions.append(gz.astgen.gpa, .{
|
gz.astgen.instructions.appendAssumeCapacity(.{
|
||||||
.tag = tag,
|
.tag = tag,
|
||||||
.data = .{ .@"break" = .{
|
.data = .{ .@"break" = .{
|
||||||
.block_inst = break_block,
|
|
||||||
.operand = operand,
|
.operand = operand,
|
||||||
|
.payload_index = payload_index,
|
||||||
|
} },
|
||||||
|
});
|
||||||
|
return new_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addBreakWithSrcNode(
|
||||||
|
gz: *GenZir,
|
||||||
|
tag: Zir.Inst.Tag,
|
||||||
|
block_inst: Zir.Inst.Index,
|
||||||
|
operand: Zir.Inst.Ref,
|
||||||
|
operand_src_node: Ast.Node.Index,
|
||||||
|
) !Zir.Inst.Index {
|
||||||
|
const gpa = gz.astgen.gpa;
|
||||||
|
try gz.instructions.ensureUnusedCapacity(gpa, 1);
|
||||||
|
try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
|
||||||
|
|
||||||
|
const extra: Zir.Inst.Break = .{
|
||||||
|
.block_inst = block_inst,
|
||||||
|
.operand_src_node = gz.nodeIndexToRelative(operand_src_node),
|
||||||
|
};
|
||||||
|
const payload_index = try gz.astgen.addExtra(extra);
|
||||||
|
const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
|
||||||
|
gz.astgen.instructions.appendAssumeCapacity(.{
|
||||||
|
.tag = tag,
|
||||||
|
.data = .{ .@"break" = .{
|
||||||
|
.operand = operand,
|
||||||
|
.payload_index = payload_index,
|
||||||
|
} },
|
||||||
|
});
|
||||||
|
gz.instructions.appendAssumeCapacity(new_index);
|
||||||
|
return new_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn makeBreakWithSrcNode(
|
||||||
|
gz: *GenZir,
|
||||||
|
tag: Zir.Inst.Tag,
|
||||||
|
block_inst: Zir.Inst.Index,
|
||||||
|
operand: Zir.Inst.Ref,
|
||||||
|
operand_src_node: Ast.Node.Index,
|
||||||
|
) !Zir.Inst.Index {
|
||||||
|
const gpa = gz.astgen.gpa;
|
||||||
|
try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
|
||||||
|
|
||||||
|
const extra: Zir.Inst.Break = .{
|
||||||
|
.block_inst = block_inst,
|
||||||
|
.operand_src_node = gz.nodeIndexToRelative(operand_src_node),
|
||||||
|
};
|
||||||
|
const payload_index = try gz.astgen.addExtra(extra);
|
||||||
|
const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
|
||||||
|
gz.astgen.instructions.appendAssumeCapacity(.{
|
||||||
|
.tag = tag,
|
||||||
|
.data = .{ .@"break" = .{
|
||||||
|
.operand = operand,
|
||||||
|
.payload_index = payload_index,
|
||||||
} },
|
} },
|
||||||
});
|
});
|
||||||
return new_index;
|
return new_index;
|
||||||
|
|||||||
@ -5949,7 +5949,7 @@ pub const PeerTypeCandidateSrc = union(enum) {
|
|||||||
none: void,
|
none: void,
|
||||||
/// When we want to know the the src of candidate i, look up at
|
/// When we want to know the the src of candidate i, look up at
|
||||||
/// index i in this slice
|
/// index i in this slice
|
||||||
override: []LazySrcLoc,
|
override: []?LazySrcLoc,
|
||||||
/// resolvePeerTypes originates from a @TypeOf(...) call
|
/// resolvePeerTypes originates from a @TypeOf(...) call
|
||||||
typeof_builtin_call_node_offset: i32,
|
typeof_builtin_call_node_offset: i32,
|
||||||
|
|
||||||
|
|||||||
75
src/Sema.zig
75
src/Sema.zig
@ -349,6 +349,16 @@ pub const Block = struct {
|
|||||||
/// if we need to add type coercion at the end of block analysis.
|
/// if we need to add type coercion at the end of block analysis.
|
||||||
/// Same indexes, capacity, length as `results`.
|
/// Same indexes, capacity, length as `results`.
|
||||||
br_list: std.ArrayListUnmanaged(Air.Inst.Index),
|
br_list: std.ArrayListUnmanaged(Air.Inst.Index),
|
||||||
|
/// Keeps the source location of the rhs operand of the break instruction,
|
||||||
|
/// to enable more precise compile errors.
|
||||||
|
/// Same indexes, capacity, length as `results`.
|
||||||
|
src_locs: std.ArrayListUnmanaged(?LazySrcLoc),
|
||||||
|
|
||||||
|
pub fn deinit(merges: *@This(), allocator: mem.Allocator) void {
|
||||||
|
merges.results.deinit(allocator);
|
||||||
|
merges.br_list.deinit(allocator);
|
||||||
|
merges.src_locs.deinit(allocator);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// For debugging purposes.
|
/// For debugging purposes.
|
||||||
@ -722,8 +732,7 @@ const LabeledBlock = struct {
|
|||||||
|
|
||||||
fn destroy(lb: *LabeledBlock, gpa: Allocator) void {
|
fn destroy(lb: *LabeledBlock, gpa: Allocator) void {
|
||||||
lb.block.instructions.deinit(gpa);
|
lb.block.instructions.deinit(gpa);
|
||||||
lb.label.merges.results.deinit(gpa);
|
lb.label.merges.deinit(gpa);
|
||||||
lb.label.merges.br_list.deinit(gpa);
|
|
||||||
gpa.destroy(lb);
|
gpa.destroy(lb);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -777,8 +786,9 @@ fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.In
|
|||||||
error.ComptimeBreak => {
|
error.ComptimeBreak => {
|
||||||
const zir_datas = sema.code.instructions.items(.data);
|
const zir_datas = sema.code.instructions.items(.data);
|
||||||
const break_data = zir_datas[sema.comptime_break_inst].@"break";
|
const break_data = zir_datas[sema.comptime_break_inst].@"break";
|
||||||
|
const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
|
||||||
try sema.addRuntimeBreak(block, .{
|
try sema.addRuntimeBreak(block, .{
|
||||||
.block_inst = break_data.block_inst,
|
.block_inst = extra.block_inst,
|
||||||
.operand = break_data.operand,
|
.operand = break_data.operand,
|
||||||
.inst = sema.comptime_break_inst,
|
.inst = sema.comptime_break_inst,
|
||||||
});
|
});
|
||||||
@ -817,8 +827,9 @@ pub fn analyzeBodyBreak(
|
|||||||
sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())
|
sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())
|
||||||
return null;
|
return null;
|
||||||
const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
|
const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
|
||||||
|
const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
|
||||||
return BreakData{
|
return BreakData{
|
||||||
.block_inst = break_data.block_inst,
|
.block_inst = extra.block_inst,
|
||||||
.operand = break_data.operand,
|
.operand = break_data.operand,
|
||||||
.inst = break_inst,
|
.inst = break_inst,
|
||||||
};
|
};
|
||||||
@ -5238,6 +5249,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
|
|||||||
var label: Block.Label = .{
|
var label: Block.Label = .{
|
||||||
.zir_block = inst,
|
.zir_block = inst,
|
||||||
.merges = .{
|
.merges = .{
|
||||||
|
.src_locs = .{},
|
||||||
.results = .{},
|
.results = .{},
|
||||||
.br_list = .{},
|
.br_list = .{},
|
||||||
.block_inst = block_inst,
|
.block_inst = block_inst,
|
||||||
@ -5251,8 +5263,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
|
|||||||
const merges = &child_block.label.?.merges;
|
const merges = &child_block.label.?.merges;
|
||||||
|
|
||||||
defer child_block.instructions.deinit(gpa);
|
defer child_block.instructions.deinit(gpa);
|
||||||
defer merges.results.deinit(gpa);
|
defer merges.deinit(gpa);
|
||||||
defer merges.br_list.deinit(gpa);
|
|
||||||
|
|
||||||
var loop_block = child_block.makeSubBlock();
|
var loop_block = child_block.makeSubBlock();
|
||||||
defer loop_block.instructions.deinit(gpa);
|
defer loop_block.instructions.deinit(gpa);
|
||||||
@ -5422,6 +5433,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
|
|||||||
var label: Block.Label = .{
|
var label: Block.Label = .{
|
||||||
.zir_block = inst,
|
.zir_block = inst,
|
||||||
.merges = .{
|
.merges = .{
|
||||||
|
.src_locs = .{},
|
||||||
.results = .{},
|
.results = .{},
|
||||||
.br_list = .{},
|
.br_list = .{},
|
||||||
.block_inst = block_inst,
|
.block_inst = block_inst,
|
||||||
@ -5450,8 +5462,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
|
|||||||
};
|
};
|
||||||
|
|
||||||
defer child_block.instructions.deinit(gpa);
|
defer child_block.instructions.deinit(gpa);
|
||||||
defer label.merges.results.deinit(gpa);
|
defer label.merges.deinit(gpa);
|
||||||
defer label.merges.br_list.deinit(gpa);
|
|
||||||
|
|
||||||
return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
|
return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
|
||||||
}
|
}
|
||||||
@ -5480,7 +5491,8 @@ fn resolveBlockBody(
|
|||||||
|
|
||||||
const break_inst = sema.comptime_break_inst;
|
const break_inst = sema.comptime_break_inst;
|
||||||
const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
|
const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
|
||||||
if (break_data.block_inst == body_inst) {
|
const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
|
||||||
|
if (extra.block_inst == body_inst) {
|
||||||
return try sema.resolveInst(break_data.operand);
|
return try sema.resolveInst(break_data.operand);
|
||||||
} else {
|
} else {
|
||||||
return error.ComptimeBreak;
|
return error.ComptimeBreak;
|
||||||
@ -5533,7 +5545,7 @@ fn analyzeBlockBody(
|
|||||||
// Need to set the type and emit the Block instruction. This allows machine code generation
|
// Need to set the type and emit the Block instruction. This allows machine code generation
|
||||||
// to emit a jump instruction to after the block when it encounters the break.
|
// to emit a jump instruction to after the block when it encounters the break.
|
||||||
try parent_block.instructions.append(gpa, merges.block_inst);
|
try parent_block.instructions.append(gpa, merges.block_inst);
|
||||||
const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none);
|
const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .{ .override = merges.src_locs.items });
|
||||||
// TODO add note "missing else causes void value"
|
// TODO add note "missing else causes void value"
|
||||||
|
|
||||||
const type_src = src; // TODO: better source location
|
const type_src = src; // TODO: better source location
|
||||||
@ -5842,14 +5854,20 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
|
|||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
const inst_data = sema.code.instructions.items(.data)[inst].@"break";
|
const inst_data = sema.code.instructions.items(.data)[inst].@"break";
|
||||||
|
const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
|
||||||
const operand = try sema.resolveInst(inst_data.operand);
|
const operand = try sema.resolveInst(inst_data.operand);
|
||||||
const zir_block = inst_data.block_inst;
|
const zir_block = extra.block_inst;
|
||||||
|
|
||||||
var block = start_block;
|
var block = start_block;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (block.label) |label| {
|
if (block.label) |label| {
|
||||||
if (label.zir_block == zir_block) {
|
if (label.zir_block == zir_block) {
|
||||||
const br_ref = try start_block.addBr(label.merges.block_inst, operand);
|
const br_ref = try start_block.addBr(label.merges.block_inst, operand);
|
||||||
|
const src_loc = if (extra.operand_src_node != Zir.Inst.Break.no_src_node)
|
||||||
|
LazySrcLoc.nodeOffset(extra.operand_src_node)
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
try label.merges.src_locs.append(sema.gpa, src_loc);
|
||||||
try label.merges.results.append(sema.gpa, operand);
|
try label.merges.results.append(sema.gpa, operand);
|
||||||
try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
|
try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
|
||||||
block.runtime_index.increment();
|
block.runtime_index.increment();
|
||||||
@ -6643,6 +6661,7 @@ fn analyzeCall(
|
|||||||
.func = null,
|
.func = null,
|
||||||
.comptime_result = undefined,
|
.comptime_result = undefined,
|
||||||
.merges = .{
|
.merges = .{
|
||||||
|
.src_locs = .{},
|
||||||
.results = .{},
|
.results = .{},
|
||||||
.br_list = .{},
|
.br_list = .{},
|
||||||
.block_inst = block_inst,
|
.block_inst = block_inst,
|
||||||
@ -6692,8 +6711,7 @@ fn analyzeCall(
|
|||||||
const merges = &child_block.inlining.?.merges;
|
const merges = &child_block.inlining.?.merges;
|
||||||
|
|
||||||
defer child_block.instructions.deinit(gpa);
|
defer child_block.instructions.deinit(gpa);
|
||||||
defer merges.results.deinit(gpa);
|
defer merges.deinit(gpa);
|
||||||
defer merges.br_list.deinit(gpa);
|
|
||||||
|
|
||||||
// If it's a comptime function call, we need to memoize it as long as no external
|
// If it's a comptime function call, we need to memoize it as long as no external
|
||||||
// comptime memory is mutated.
|
// comptime memory is mutated.
|
||||||
@ -10780,6 +10798,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
|||||||
var label: Block.Label = .{
|
var label: Block.Label = .{
|
||||||
.zir_block = inst,
|
.zir_block = inst,
|
||||||
.merges = .{
|
.merges = .{
|
||||||
|
.src_locs = .{},
|
||||||
.results = .{},
|
.results = .{},
|
||||||
.br_list = .{},
|
.br_list = .{},
|
||||||
.block_inst = block_inst,
|
.block_inst = block_inst,
|
||||||
@ -10807,8 +10826,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
|||||||
};
|
};
|
||||||
const merges = &child_block.label.?.merges;
|
const merges = &child_block.label.?.merges;
|
||||||
defer child_block.instructions.deinit(gpa);
|
defer child_block.instructions.deinit(gpa);
|
||||||
defer merges.results.deinit(gpa);
|
defer merges.deinit(gpa);
|
||||||
defer merges.br_list.deinit(gpa);
|
|
||||||
|
|
||||||
if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {
|
if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {
|
||||||
var extra_index: usize = special.end;
|
var extra_index: usize = special.end;
|
||||||
@ -12298,7 +12316,7 @@ fn zirBitwise(
|
|||||||
try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
|
try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
|
||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
|
||||||
const scalar_type = resolved_type.scalarType();
|
const scalar_type = resolved_type.scalarType();
|
||||||
const scalar_tag = scalar_type.zigTypeTag();
|
const scalar_tag = scalar_type.zigTypeTag();
|
||||||
|
|
||||||
@ -12502,7 +12520,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||||||
try trash_block.addBitCast(rhs_info.elem_type, .void_value),
|
try trash_block.addBitCast(rhs_info.elem_type, .void_value),
|
||||||
};
|
};
|
||||||
break :t try sema.resolvePeerTypes(block, src, &instructions, .{
|
break :t try sema.resolvePeerTypes(block, src, &instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13002,7 +13020,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
||||||
@ -13162,7 +13180,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
||||||
@ -13325,7 +13343,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
||||||
@ -13441,7 +13459,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
||||||
@ -13683,7 +13701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
||||||
@ -13866,7 +13884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
|
const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
|
||||||
@ -13968,7 +13986,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
|
const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
|
||||||
@ -14081,7 +14099,7 @@ fn zirOverflowArithmetic(
|
|||||||
lhs_ty
|
lhs_ty
|
||||||
else
|
else
|
||||||
try sema.resolvePeerTypes(block, src, instructions, .{
|
try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const rhs_dest_ty = if (zir_tag == .shl_with_overflow)
|
const rhs_dest_ty = if (zir_tag == .shl_with_overflow)
|
||||||
@ -14312,7 +14330,7 @@ fn analyzeArithmetic(
|
|||||||
|
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
|
|
||||||
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
const is_vector = resolved_type.zigTypeTag() == .Vector;
|
||||||
@ -15200,7 +15218,7 @@ fn analyzeCmp(
|
|||||||
return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
|
return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
|
||||||
}
|
}
|
||||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
|
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
|
||||||
if (!resolved_type.isSelfComparable(is_equality_cmp)) {
|
if (!resolved_type.isSelfComparable(is_equality_cmp)) {
|
||||||
return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
|
return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
|
||||||
compareOperatorName(op), resolved_type.fmt(sema.mod),
|
compareOperatorName(op), resolved_type.fmt(sema.mod),
|
||||||
@ -17024,6 +17042,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi
|
|||||||
.label = .{
|
.label = .{
|
||||||
.zir_block = break_data.block_inst,
|
.zir_block = break_data.block_inst,
|
||||||
.merges = .{
|
.merges = .{
|
||||||
|
.src_locs = .{},
|
||||||
.results = .{},
|
.results = .{},
|
||||||
.br_list = .{},
|
.br_list = .{},
|
||||||
.block_inst = new_block_inst,
|
.block_inst = new_block_inst,
|
||||||
@ -20605,7 +20624,7 @@ fn checkSimdBinOp(
|
|||||||
try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
|
try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
|
||||||
var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null;
|
var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null;
|
||||||
const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{
|
const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{
|
||||||
.override = &[_]LazySrcLoc{ lhs_src, rhs_src },
|
.override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
|
||||||
});
|
});
|
||||||
const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src);
|
const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src);
|
||||||
const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src);
|
const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src);
|
||||||
|
|||||||
@ -2603,8 +2603,8 @@ pub const Inst = struct {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
@"break": struct {
|
@"break": struct {
|
||||||
block_inst: Index,
|
|
||||||
operand: Ref,
|
operand: Ref,
|
||||||
|
payload_index: u32,
|
||||||
},
|
},
|
||||||
switch_capture: struct {
|
switch_capture: struct {
|
||||||
switch_inst: Index,
|
switch_inst: Index,
|
||||||
@ -2690,6 +2690,13 @@ pub const Inst = struct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Break = struct {
|
||||||
|
pub const no_src_node = std.math.maxInt(i32);
|
||||||
|
|
||||||
|
block_inst: Index,
|
||||||
|
operand_src_node: i32,
|
||||||
|
};
|
||||||
|
|
||||||
/// Trailing:
|
/// Trailing:
|
||||||
/// 0. Output for every outputs_len
|
/// 0. Output for every outputs_len
|
||||||
/// 1. Input for every inputs_len
|
/// 1. Input for every inputs_len
|
||||||
|
|||||||
@ -2321,8 +2321,9 @@ const Writer = struct {
|
|||||||
|
|
||||||
fn writeBreak(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
|
fn writeBreak(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
|
||||||
const inst_data = self.code.instructions.items(.data)[inst].@"break";
|
const inst_data = self.code.instructions.items(.data)[inst].@"break";
|
||||||
|
const extra = self.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
|
||||||
|
|
||||||
try self.writeInstIndex(stream, inst_data.block_inst);
|
try self.writeInstIndex(stream, extra.block_inst);
|
||||||
try stream.writeAll(", ");
|
try stream.writeAll(", ");
|
||||||
try self.writeInstRef(stream, inst_data.operand);
|
try self.writeInstRef(stream, inst_data.operand);
|
||||||
try stream.writeAll(")");
|
try stream.writeAll(")");
|
||||||
|
|||||||
@ -25,3 +25,5 @@ export fn entry() void {
|
|||||||
// target=native
|
// target=native
|
||||||
//
|
//
|
||||||
// :14:17: error: incompatible types: '*align(1:0:1) u2' and '*align(2:8:2) u2'
|
// :14:17: error: incompatible types: '*align(1:0:1) u2' and '*align(2:8:2) u2'
|
||||||
|
// :15:14: note: type '*align(1:0:1) u2' here
|
||||||
|
// :16:14: note: type '*align(2:8:2) u2' here
|
||||||
|
|||||||
@ -31,7 +31,9 @@ export fn entry() void {
|
|||||||
// target=native
|
// target=native
|
||||||
//
|
//
|
||||||
// :2:21: error: incompatible types: 'i32' and 'void'
|
// :2:21: error: incompatible types: 'i32' and 'void'
|
||||||
|
// :6:25: note: type 'i32' here
|
||||||
// :6:15: error: incompatible types: 'i32' and 'void'
|
// :6:15: error: incompatible types: 'i32' and 'void'
|
||||||
|
// :2:31: note: type 'i32' here
|
||||||
// :12:16: error: expected type 'tmp.h.T', found 'void'
|
// :12:16: error: expected type 'tmp.h.T', found 'void'
|
||||||
// :11:15: note: struct declared here
|
// :11:15: note: struct declared here
|
||||||
// :18:9: error: incompatible types: 'void' and 'tmp.k.T'
|
// :18:9: error: incompatible types: 'void' and 'tmp.k.T'
|
||||||
|
|||||||
@ -10,3 +10,5 @@ export fn entry() void {
|
|||||||
// target=native
|
// target=native
|
||||||
//
|
//
|
||||||
// :5:11: error: incompatible types: 'void' and 'comptime_int'
|
// :5:11: error: incompatible types: 'void' and 'comptime_int'
|
||||||
|
// :5:11: note: type 'void' here
|
||||||
|
// :5:17: note: type 'comptime_int' here
|
||||||
|
|||||||
@ -12,3 +12,5 @@ export fn entry() void {
|
|||||||
// target=native
|
// target=native
|
||||||
//
|
//
|
||||||
// :3:18: error: incompatible types: 'comptime_int' and 'void'
|
// :3:18: error: incompatible types: 'comptime_int' and 'void'
|
||||||
|
// :4:14: note: type 'comptime_int' here
|
||||||
|
// :5:16: note: type 'void' here
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user