| ... | ... | @@ -4688,7 +4688,7 @@ fn analyzeCall( |
| 4688 | 4688 | |
| 4689 | 4689 | const gpa = sema.gpa; |
| 4690 | 4690 | |
| 4691 | | const is_comptime_call = block.is_comptime or modifier == .compile_time or |
| 4691 | var is_comptime_call = block.is_comptime or modifier == .compile_time or |
| 4692 | 4692 | try sema.typeRequiresComptime(block, func_src, func_ty_info.return_type); |
| 4693 | 4693 | var is_inline_call = is_comptime_call or modifier == .always_inline or |
| 4694 | 4694 | func_ty_info.cc == .Inline; |
| ... | ... | @@ -4706,7 +4706,13 @@ fn analyzeCall( |
| 4706 | 4706 | )) |some| { |
| 4707 | 4707 | return some; |
| 4708 | 4708 | } else |err| switch (err) { |
| 4709 | | error.GenericPoison => is_inline_call = true, |
| 4709 | error.GenericPoison => { |
| 4710 | is_inline_call = true; |
| 4711 | }, |
| 4712 | error.ComptimeReturn => { |
| 4713 | is_inline_call = true; |
| 4714 | is_comptime_call = true; |
| 4715 | }, |
| 4710 | 4716 | else => |e| return e, |
| 4711 | 4717 | } |
| 4712 | 4718 | } |
| ... | ... | @@ -5149,7 +5155,13 @@ fn instantiateGenericCall( |
| 5149 | 5155 | // of each of its instantiations. |
| 5150 | 5156 | assert(new_decl.dependencies.keys().len == 0); |
| 5151 | 5157 | try mod.declareDeclDependency(new_decl, module_fn.owner_decl); |
| 5152 | | errdefer assert(module_fn.owner_decl.dependants.orderedRemove(new_decl)); |
| 5158 | // Resolving the new function type below will possibly declare more decl dependencies |
| 5159 | // and so we remove them all here in case of error. |
| 5160 | errdefer { |
| 5161 | for (new_decl.dependencies.keys()) |dep| { |
| 5162 | dep.removeDependant(new_decl); |
| 5163 | } |
| 5164 | } |
| 5153 | 5165 | |
| 5154 | 5166 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| 5155 | 5167 | errdefer new_decl_arena.deinit(); |
| ... | ... | @@ -5285,8 +5297,17 @@ fn instantiateGenericCall( |
| 5285 | 5297 | |
| 5286 | 5298 | // Populate the Decl ty/val with the function and its type. |
| 5287 | 5299 | new_decl.ty = try child_sema.typeOf(new_func_inst).copy(new_decl_arena_allocator); |
| 5288 | | // If the call evaluated to a generic type return errror and call inline. |
| 5289 | | if (new_decl.ty.fnInfo().is_generic) return error.GenericPoison; |
| 5300 | // If the call evaluated to a return type that requires comptime, never mind |
| 5301 | // our generic instantiation. Instead we need to perform a comptime call. |
| 5302 | const new_fn_info = new_decl.ty.fnInfo(); |
| 5303 | if (try sema.typeRequiresComptime(block, call_src, new_fn_info.return_type)) { |
| 5304 | return error.ComptimeReturn; |
| 5305 | } |
| 5306 | // Similarly, if the call evaluated to a generic type we need to instead |
| 5307 | // call it inline. |
| 5308 | if (new_fn_info.is_generic or new_fn_info.cc == .Inline) { |
| 5309 | return error.GenericPoison; |
| 5310 | } |
| 5290 | 5311 | |
| 5291 | 5312 | new_decl.val = try Value.Tag.function.create(new_decl_arena_allocator, new_func); |
| 5292 | 5313 | new_decl.has_tv = true; |
| ... | ... | @@ -12978,10 +12999,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 12978 | 12999 | new_decl.owns_tv = true; |
| 12979 | 13000 | errdefer mod.abortAnonDecl(new_decl); |
| 12980 | 13001 | |
| 13002 | // Enum tag type |
| 13003 | var buffer: Value.ToTypeBuffer = undefined; |
| 13004 | const int_tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator); |
| 13005 | |
| 12981 | 13006 | enum_obj.* = .{ |
| 12982 | 13007 | .owner_decl = new_decl, |
| 12983 | | .tag_ty = Type.@"null", |
| 12984 | | .tag_ty_inferred = true, |
| 13008 | .tag_ty = int_tag_ty, |
| 13009 | .tag_ty_inferred = false, |
| 12985 | 13010 | .fields = .{}, |
| 12986 | 13011 | .values = .{}, |
| 12987 | 13012 | .node_offset = src.node_offset, |
| ... | ... | @@ -12992,10 +13017,6 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 12992 | 13017 | }, |
| 12993 | 13018 | }; |
| 12994 | 13019 | |
| 12995 | | // Enum tag type |
| 12996 | | var buffer: Value.ToTypeBuffer = undefined; |
| 12997 | | enum_obj.tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator); |
| 12998 | | |
| 12999 | 13020 | // Fields |
| 13000 | 13021 | const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target)); |
| 13001 | 13022 | if (fields_len > 0) { |
| ... | ... | @@ -21111,8 +21132,18 @@ fn resolveInferredErrorSet( |
| 21111 | 21132 | return sema.fail(block, src, "unable to resolve inferred error set", .{}); |
| 21112 | 21133 | } |
| 21113 | 21134 | |
| 21114 | | // To ensure that all dependencies are properly added to the set. |
| 21115 | | try sema.ensureFuncBodyAnalyzed(ies.func); |
| 21135 | // In order to ensure that all dependencies are properly added to the set, we |
| 21136 | // need to ensure the function body is analyzed of the inferred error set. |
| 21137 | // However, in the case of comptime/inline function calls with inferred error sets, |
| 21138 | // each call gets a new InferredErrorSet object, which points to the same |
| 21139 | // `*Module.Fn`. Not only is the function not relevant to the inferred error set |
| 21140 | // in this case, it may be a generic function which would cause an assertion failure |
| 21141 | // if we called `ensureFuncBodyAnalyzed` on it here. |
| 21142 | if (ies.func.owner_decl.ty.fnInfo().return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) { |
| 21143 | // In this case we are dealing with the actual InferredErrorSet object that |
| 21144 | // corresponds to the function, not one created to track an inline/comptime call. |
| 21145 | try sema.ensureFuncBodyAnalyzed(ies.func); |
| 21146 | } |
| 21116 | 21147 | |
| 21117 | 21148 | ies.is_resolved = true; |
| 21118 | 21149 | |