| ... | @@ -5590,11 +5590,10 @@ const GenericCallAdapter = struct { | ... | @@ -5590,11 +5590,10 @@ const GenericCallAdapter = struct { |
| 5590 | | 5590 | |
| 5591 | pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool { | 5591 | pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool { |
| 5592 | _ = adapted_key; | 5592 | _ = adapted_key; |
| 5593 | // The generic function Decl is guaranteed to be the first dependency | 5593 | // Checking for equality may happen on an item that has been inserted |
| 5594 | // of each of its instantiations. | 5594 | // into the map but is not yet fully initialized. In such case, the |
| 5595 | const other_owner_decl = ctx.module.declPtr(other_key.owner_decl); | 5595 | // two initialized fields are `hash` and `generic_owner_decl`. |
| 5596 | const generic_owner_decl = other_owner_decl.dependencies.keys()[0]; | 5596 | if (ctx.generic_fn.owner_decl != other_key.generic_owner_decl.unwrap().?) return false; |
| 5597 | if (ctx.generic_fn.owner_decl != generic_owner_decl) return false; | | |
| 5598 | | 5597 | |
| 5599 | const other_comptime_args = other_key.comptime_args.?; | 5598 | const other_comptime_args = other_key.comptime_args.?; |
| 5600 | for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| { | 5599 | for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| { |
| ... | @@ -6447,11 +6446,14 @@ fn instantiateGenericCall( | ... | @@ -6447,11 +6446,14 @@ fn instantiateGenericCall( |
| 6447 | const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter); | 6446 | const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter); |
| 6448 | const callee = if (!gop.found_existing) callee: { | 6447 | const callee = if (!gop.found_existing) callee: { |
| 6449 | const new_module_func = try gpa.create(Module.Fn); | 6448 | const new_module_func = try gpa.create(Module.Fn); |
| | 6449 | errdefer gpa.destroy(new_module_func); |
| | 6450 | |
| 6450 | // This ensures that we can operate on the hash map before the Module.Fn | 6451 | // This ensures that we can operate on the hash map before the Module.Fn |
| 6451 | // struct is fully initialized. | 6452 | // struct is fully initialized. |
| 6452 | new_module_func.hash = precomputed_hash; | 6453 | new_module_func.hash = precomputed_hash; |
| | 6454 | new_module_func.generic_owner_decl = module_fn.owner_decl.toOptional(); |
| | 6455 | new_module_func.comptime_args = null; |
| 6453 | gop.key_ptr.* = new_module_func; | 6456 | gop.key_ptr.* = new_module_func; |
| 6454 | errdefer gpa.destroy(new_module_func); | | |
| 6455 | errdefer assert(mod.monomorphed_funcs.remove(new_module_func)); | 6457 | errdefer assert(mod.monomorphed_funcs.remove(new_module_func)); |
| 6456 | | 6458 | |
| 6457 | try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); | 6459 | try namespace.anon_decls.ensureUnusedCapacity(gpa, 1); |
| ... | @@ -8032,11 +8034,13 @@ fn funcCommon( | ... | @@ -8032,11 +8034,13 @@ fn funcCommon( |
| 8032 | } else null; | 8034 | } else null; |
| 8033 | | 8035 | |
| 8034 | const hash = new_func.hash; | 8036 | const hash = new_func.hash; |
| | 8037 | const generic_owner_decl = if (comptime_args == null) .none else new_func.generic_owner_decl; |
| 8035 | const fn_payload = try sema.arena.create(Value.Payload.Function); | 8038 | const fn_payload = try sema.arena.create(Value.Payload.Function); |
| 8036 | new_func.* = .{ | 8039 | new_func.* = .{ |
| 8037 | .state = anal_state, | 8040 | .state = anal_state, |
| 8038 | .zir_body_inst = func_inst, | 8041 | .zir_body_inst = func_inst, |
| 8039 | .owner_decl = sema.owner_decl_index, | 8042 | .owner_decl = sema.owner_decl_index, |
| | 8043 | .generic_owner_decl = generic_owner_decl, |
| 8040 | .comptime_args = comptime_args, | 8044 | .comptime_args = comptime_args, |
| 8041 | .hash = hash, | 8045 | .hash = hash, |
| 8042 | .lbrace_line = src_locs.lbrace_line, | 8046 | .lbrace_line = src_locs.lbrace_line, |