| ... | @@ -4688,7 +4688,7 @@ fn analyzeCall( | ... | @@ -4688,7 +4688,7 @@ fn analyzeCall( |
| 4688 | | 4688 | |
| 4689 | const gpa = sema.gpa; | 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 | try sema.typeRequiresComptime(block, func_src, func_ty_info.return_type); | 4692 | try sema.typeRequiresComptime(block, func_src, func_ty_info.return_type); |
| 4693 | var is_inline_call = is_comptime_call or modifier == .always_inline or | 4693 | var is_inline_call = is_comptime_call or modifier == .always_inline or |
| 4694 | func_ty_info.cc == .Inline; | 4694 | func_ty_info.cc == .Inline; |
| ... | @@ -4706,7 +4706,13 @@ fn analyzeCall( | ... | @@ -4706,7 +4706,13 @@ fn analyzeCall( |
| 4706 | )) |some| { | 4706 | )) |some| { |
| 4707 | return some; | 4707 | return some; |
| 4708 | } else |err| switch (err) { | 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 | else => |e| return e, | 4716 | else => |e| return e, |
| 4711 | } | 4717 | } |
| 4712 | } | 4718 | } |
| ... | @@ -5149,7 +5155,13 @@ fn instantiateGenericCall( | ... | @@ -5149,7 +5155,13 @@ fn instantiateGenericCall( |
| 5149 | // of each of its instantiations. | 5155 | // of each of its instantiations. |
| 5150 | assert(new_decl.dependencies.keys().len == 0); | 5156 | assert(new_decl.dependencies.keys().len == 0); |
| 5151 | try mod.declareDeclDependency(new_decl, module_fn.owner_decl); | 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 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); | 5166 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| 5155 | errdefer new_decl_arena.deinit(); | 5167 | errdefer new_decl_arena.deinit(); |
| ... | @@ -5285,8 +5297,17 @@ fn instantiateGenericCall( | ... | @@ -5285,8 +5297,17 @@ fn instantiateGenericCall( |
| 5285 | | 5297 | |
| 5286 | // Populate the Decl ty/val with the function and its type. | 5298 | // Populate the Decl ty/val with the function and its type. |
| 5287 | new_decl.ty = try child_sema.typeOf(new_func_inst).copy(new_decl_arena_allocator); | 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. | 5300 | // If the call evaluated to a return type that requires comptime, never mind |
| 5289 | if (new_decl.ty.fnInfo().is_generic) return error.GenericPoison; | 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 | new_decl.val = try Value.Tag.function.create(new_decl_arena_allocator, new_func); | 5312 | new_decl.val = try Value.Tag.function.create(new_decl_arena_allocator, new_func); |
| 5292 | new_decl.has_tv = true; | 5313 | new_decl.has_tv = true; |
| ... | @@ -12978,10 +12999,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I | ... | @@ -12978,10 +12999,14 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 12978 | new_decl.owns_tv = true; | 12999 | new_decl.owns_tv = true; |
| 12979 | errdefer mod.abortAnonDecl(new_decl); | 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 | enum_obj.* = .{ | 13006 | enum_obj.* = .{ |
| 12982 | .owner_decl = new_decl, | 13007 | .owner_decl = new_decl, |
| 12983 | .tag_ty = Type.@"null", | 13008 | .tag_ty = int_tag_ty, |
| 12984 | .tag_ty_inferred = true, | 13009 | .tag_ty_inferred = false, |
| 12985 | .fields = .{}, | 13010 | .fields = .{}, |
| 12986 | .values = .{}, | 13011 | .values = .{}, |
| 12987 | .node_offset = src.node_offset, | 13012 | .node_offset = src.node_offset, |
| ... | @@ -12992,10 +13017,6 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I | ... | @@ -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 | // Fields | 13020 | // Fields |
| 13000 | const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target)); | 13021 | const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target)); |
| 13001 | if (fields_len > 0) { | 13022 | if (fields_len > 0) { |
| ... | @@ -21111,8 +21132,18 @@ fn resolveInferredErrorSet( | ... | @@ -21111,8 +21132,18 @@ fn resolveInferredErrorSet( |
| 21111 | return sema.fail(block, src, "unable to resolve inferred error set", .{}); | 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. | 21135 | // In order to ensure that all dependencies are properly added to the set, we |
| 21115 | try sema.ensureFuncBodyAnalyzed(ies.func); | 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 | ies.is_resolved = true; | 21148 | ies.is_resolved = true; |
| 21118 | | 21149 | |