Sema: fix inline/comptime function calls with inferred errors

This commit is contained in:
Andrew Kelley 2022-03-11 20:44:10 -07:00
parent 55ba335e0f
commit 60d6037f23
2 changed files with 26 additions and 13 deletions

View File

@ -1542,6 +1542,21 @@ pub const Fn = struct {
// const zir = func.owner_decl.getFileScope().zir;
return func.param_names[index];
}
pub fn hasInferredErrorSet(func: Fn) bool {
const zir = func.owner_decl.getFileScope().zir;
const zir_tags = zir.instructions.items(.tag);
switch (zir_tags[func.zir_body_inst]) {
.func => return false,
.func_inferred => return true,
.extended => {
const extended = zir.instructions.items(.data)[func.zir_body_inst].extended;
const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
return small.is_inferred_error;
},
else => unreachable,
}
}
};
pub const Var = struct {

View File

@ -4666,20 +4666,18 @@ fn analyzeCall(
const bare_return_type = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst);
// Create a fresh inferred error set type for inline/comptime calls.
const fn_ret_ty = blk: {
if (func_ty_info.return_type.castTag(.error_union)) |payload| {
if (payload.data.error_set.tag() == .error_set_inferred) {
const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);
node.data = .{ .func = module_fn };
if (parent_func) |some| {
some.inferred_error_sets.prepend(node);
}
const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data);
break :blk try Type.Tag.error_union.create(sema.arena, .{
.error_set = error_set_ty,
.payload = bare_return_type,
});
if (module_fn.hasInferredErrorSet()) {
const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);
node.data = .{ .func = module_fn };
if (parent_func) |some| {
some.inferred_error_sets.prepend(node);
}
const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data);
break :blk try Type.Tag.error_union.create(sema.arena, .{
.error_set = error_set_ty,
.payload = bare_return_type,
});
}
break :blk bare_return_type;
};