From 60d6037f236379e521ccb7a8e1b7d24ed469ac3f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 11 Mar 2022 20:44:10 -0700 Subject: [PATCH] Sema: fix inline/comptime function calls with inferred errors --- src/Module.zig | 15 +++++++++++++++ src/Sema.zig | 24 +++++++++++------------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index b3e0344d77..868ce578eb 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -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 { diff --git a/src/Sema.zig b/src/Sema.zig index 31295707de..82acbab9e5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -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; };