| ... | ... | @@ -6748,7 +6748,7 @@ fn analyzeCall( |
| 6748 | 6748 | func, |
| 6749 | 6749 | func_src, |
| 6750 | 6750 | call_src, |
| 6751 | | func_ty_info, |
| 6751 | func_ty, |
| 6752 | 6752 | ensure_result_used, |
| 6753 | 6753 | uncasted_args, |
| 6754 | 6754 | call_tag, |
| ... | ... | @@ -7367,8 +7367,16 @@ fn analyzeGenericCallArg( |
| 7367 | 7367 | } |
| 7368 | 7368 | } |
| 7369 | 7369 | |
| 7370 | | fn analyzeGenericCallArgVal(sema: *Sema, block: *Block, arg_src: LazySrcLoc, uncasted_arg: Air.Inst.Ref) !Value { |
| 7371 | | return sema.resolveLazyValue(try sema.resolveValue(block, arg_src, uncasted_arg, "parameter is comptime")); |
| 7370 | fn analyzeGenericCallArgVal( |
| 7371 | sema: *Sema, |
| 7372 | block: *Block, |
| 7373 | arg_src: LazySrcLoc, |
| 7374 | arg_ty: Type, |
| 7375 | uncasted_arg: Air.Inst.Ref, |
| 7376 | reason: []const u8, |
| 7377 | ) !Value { |
| 7378 | const casted_arg = try sema.coerce(block, arg_ty, uncasted_arg, arg_src); |
| 7379 | return sema.resolveLazyValue(try sema.resolveValue(block, arg_src, casted_arg, reason)); |
| 7372 | 7380 | } |
| 7373 | 7381 | |
| 7374 | 7382 | fn instantiateGenericCall( |
| ... | ... | @@ -7377,7 +7385,7 @@ fn instantiateGenericCall( |
| 7377 | 7385 | func: Air.Inst.Ref, |
| 7378 | 7386 | func_src: LazySrcLoc, |
| 7379 | 7387 | call_src: LazySrcLoc, |
| 7380 | | func_ty_info: InternPool.Key.FuncType, |
| 7388 | generic_func_ty: Type, |
| 7381 | 7389 | ensure_result_used: bool, |
| 7382 | 7390 | uncasted_args: []const Air.Inst.Ref, |
| 7383 | 7391 | call_tag: Air.Inst.Tag, |
| ... | ... | @@ -7404,24 +7412,25 @@ fn instantiateGenericCall( |
| 7404 | 7412 | const fn_info = fn_zir.getFnInfo(module_fn.zir_body_inst); |
| 7405 | 7413 | const zir_tags = fn_zir.instructions.items(.tag); |
| 7406 | 7414 | |
| 7407 | | const generic_args = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); |
| 7415 | const monomorphed_args = try sema.arena.alloc(InternPool.Index, mod.typeToFunc(generic_func_ty).?.param_types.len); |
| 7408 | 7416 | const callee_index = callee: { |
| 7409 | 7417 | var arg_i: usize = 0; |
| 7410 | | var generic_arg_i: u32 = 0; |
| 7418 | var monomorphed_arg_i: u32 = 0; |
| 7411 | 7419 | var known_unique = false; |
| 7412 | 7420 | for (fn_info.param_body) |inst| { |
| 7421 | const generic_func_ty_info = mod.typeToFunc(generic_func_ty).?; |
| 7413 | 7422 | var is_comptime = false; |
| 7414 | 7423 | var is_anytype = false; |
| 7415 | 7424 | switch (zir_tags[inst]) { |
| 7416 | 7425 | .param => { |
| 7417 | | is_comptime = func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7426 | is_comptime = generic_func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7418 | 7427 | }, |
| 7419 | 7428 | .param_comptime => { |
| 7420 | 7429 | is_comptime = true; |
| 7421 | 7430 | }, |
| 7422 | 7431 | .param_anytype => { |
| 7423 | 7432 | is_anytype = true; |
| 7424 | | is_comptime = func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7433 | is_comptime = generic_func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7425 | 7434 | }, |
| 7426 | 7435 | .param_anytype_comptime => { |
| 7427 | 7436 | is_anytype = true; |
| ... | ... | @@ -7431,69 +7440,60 @@ fn instantiateGenericCall( |
| 7431 | 7440 | } |
| 7432 | 7441 | |
| 7433 | 7442 | defer arg_i += 1; |
| 7443 | const param_ty = generic_func_ty_info.param_types[arg_i]; |
| 7444 | const is_generic = !is_anytype and param_ty == .generic_poison_type; |
| 7445 | |
| 7434 | 7446 | if (known_unique) { |
| 7435 | | if (is_comptime or is_anytype) { |
| 7436 | | generic_arg_i += 1; |
| 7447 | if (is_comptime or is_anytype or is_generic) { |
| 7448 | monomorphed_arg_i += 1; |
| 7437 | 7449 | } |
| 7438 | 7450 | continue; |
| 7439 | 7451 | } |
| 7440 | 7452 | |
| 7441 | | const arg_ty = sema.typeOf(uncasted_args[arg_i]); |
| 7453 | const uncasted_arg = uncasted_args[arg_i]; |
| 7454 | const arg_ty = if (is_generic) mod.monomorphed_funcs.getAdapted( |
| 7455 | Module.MonomorphedFuncAdaptedKey{ |
| 7456 | .func = module_fn_index, |
| 7457 | .args = monomorphed_args[0..monomorphed_arg_i], |
| 7458 | }, |
| 7459 | Module.MonomorphedFuncsAdaptedContext{ .mod = mod }, |
| 7460 | ) orelse { |
| 7461 | known_unique = true; |
| 7462 | monomorphed_arg_i += 1; |
| 7463 | continue; |
| 7464 | } else if (is_anytype) sema.typeOf(uncasted_arg).toIntern() else param_ty; |
| 7465 | const was_comptime = is_comptime; |
| 7466 | if (!is_comptime and try sema.typeRequiresComptime(arg_ty.toType())) is_comptime = true; |
| 7442 | 7467 | if (is_comptime or is_anytype) { |
| 7443 | 7468 | // Tuple default values are a part of the type and need to be |
| 7444 | 7469 | // resolved to hash the type. |
| 7445 | | try sema.resolveTupleLazyValues(block, call_src, arg_ty); |
| 7470 | try sema.resolveTupleLazyValues(block, call_src, arg_ty.toType()); |
| 7446 | 7471 | } |
| 7447 | 7472 | |
| 7448 | 7473 | if (is_comptime) { |
| 7449 | | const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[arg_i]) catch |err| switch (err) { |
| 7474 | const casted_arg = sema.analyzeGenericCallArgVal(block, .unneeded, arg_ty.toType(), uncasted_arg, "") catch |err| switch (err) { |
| 7450 | 7475 | error.NeededSourceLocation => { |
| 7451 | 7476 | const decl = mod.declPtr(block.src_decl); |
| 7452 | 7477 | const arg_src = mod.argSrc(call_src.node_offset.x, decl, arg_i, bound_arg_src); |
| 7453 | | _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[arg_i]); |
| 7478 | _ = try sema.analyzeGenericCallArgVal( |
| 7479 | block, |
| 7480 | arg_src, |
| 7481 | arg_ty.toType(), |
| 7482 | uncasted_arg, |
| 7483 | if (was_comptime) |
| 7484 | "parameter is comptime" |
| 7485 | else |
| 7486 | "argument to parameter with comptime-only type must be comptime-known", |
| 7487 | ); |
| 7454 | 7488 | unreachable; |
| 7455 | 7489 | }, |
| 7456 | 7490 | else => |e| return e, |
| 7457 | 7491 | }; |
| 7458 | | |
| 7459 | | if (is_anytype) { |
| 7460 | | generic_args[generic_arg_i] = arg_val.toIntern(); |
| 7461 | | } else { |
| 7462 | | const final_arg_ty = mod.monomorphed_funcs.getAdapted( |
| 7463 | | Module.MonomorphedFuncAdaptedKey{ |
| 7464 | | .func = module_fn_index, |
| 7465 | | .args = generic_args[0..generic_arg_i], |
| 7466 | | }, |
| 7467 | | Module.MonomorphedFuncsAdaptedContext{ .mod = mod }, |
| 7468 | | ) orelse { |
| 7469 | | known_unique = true; |
| 7470 | | generic_arg_i += 1; |
| 7471 | | continue; |
| 7472 | | }; |
| 7473 | | const casted_arg = sema.coerce(block, final_arg_ty.toType(), uncasted_args[arg_i], .unneeded) catch |err| switch (err) { |
| 7474 | | error.NeededSourceLocation => { |
| 7475 | | const decl = mod.declPtr(block.src_decl); |
| 7476 | | const arg_src = mod.argSrc(call_src.node_offset.x, decl, arg_i, bound_arg_src); |
| 7477 | | _ = try sema.coerce(block, final_arg_ty.toType(), uncasted_args[arg_i], arg_src); |
| 7478 | | unreachable; |
| 7479 | | }, |
| 7480 | | else => |e| return e, |
| 7481 | | }; |
| 7482 | | const casted_arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, casted_arg) catch |err| switch (err) { |
| 7483 | | error.NeededSourceLocation => { |
| 7484 | | const decl = mod.declPtr(block.src_decl); |
| 7485 | | const arg_src = mod.argSrc(call_src.node_offset.x, decl, arg_i, bound_arg_src); |
| 7486 | | _ = try sema.analyzeGenericCallArgVal(block, arg_src, casted_arg); |
| 7487 | | unreachable; |
| 7488 | | }, |
| 7489 | | else => |e| return e, |
| 7490 | | }; |
| 7491 | | generic_args[generic_arg_i] = casted_arg_val.toIntern(); |
| 7492 | | } |
| 7493 | | generic_arg_i += 1; |
| 7494 | | } else if (is_anytype) { |
| 7495 | | generic_args[generic_arg_i] = arg_ty.toIntern(); |
| 7496 | | generic_arg_i += 1; |
| 7492 | monomorphed_args[monomorphed_arg_i] = casted_arg.toIntern(); |
| 7493 | monomorphed_arg_i += 1; |
| 7494 | } else if (is_anytype or is_generic) { |
| 7495 | monomorphed_args[monomorphed_arg_i] = try mod.intern(.{ .undef = arg_ty }); |
| 7496 | monomorphed_arg_i += 1; |
| 7497 | 7497 | } |
| 7498 | 7498 | } |
| 7499 | 7499 | |
| ... | ... | @@ -7501,7 +7501,7 @@ fn instantiateGenericCall( |
| 7501 | 7501 | if (mod.monomorphed_funcs.getAdapted( |
| 7502 | 7502 | Module.MonomorphedFuncAdaptedKey{ |
| 7503 | 7503 | .func = module_fn_index, |
| 7504 | | .args = generic_args[0..generic_arg_i], |
| 7504 | .args = monomorphed_args[0..monomorphed_arg_i], |
| 7505 | 7505 | }, |
| 7506 | 7506 | Module.MonomorphedFuncsAdaptedContext{ .mod = mod }, |
| 7507 | 7507 | )) |callee_func| break :callee mod.intern_pool.indexToKey(callee_func).func.index; |
| ... | ... | @@ -7550,11 +7550,11 @@ fn instantiateGenericCall( |
| 7550 | 7550 | new_decl, |
| 7551 | 7551 | new_decl_index, |
| 7552 | 7552 | uncasted_args, |
| 7553 | | generic_arg_i, |
| 7553 | monomorphed_arg_i, |
| 7554 | 7554 | module_fn_index, |
| 7555 | 7555 | new_module_func_index, |
| 7556 | 7556 | namespace_index, |
| 7557 | | func_ty_info, |
| 7557 | generic_func_ty, |
| 7558 | 7558 | call_src, |
| 7559 | 7559 | bound_arg_src, |
| 7560 | 7560 | ) catch |err| switch (err) { |
| ... | ... | @@ -7673,11 +7673,11 @@ fn resolveGenericInstantiationType( |
| 7673 | 7673 | new_decl: *Decl, |
| 7674 | 7674 | new_decl_index: Decl.Index, |
| 7675 | 7675 | uncasted_args: []const Air.Inst.Ref, |
| 7676 | | generic_args_len: u32, |
| 7676 | monomorphed_args_len: u32, |
| 7677 | 7677 | module_fn_index: Module.Fn.Index, |
| 7678 | 7678 | new_module_func: Module.Fn.Index, |
| 7679 | 7679 | namespace: Namespace.Index, |
| 7680 | | func_ty_info: InternPool.Key.FuncType, |
| 7680 | generic_func_ty: Type, |
| 7681 | 7681 | call_src: LazySrcLoc, |
| 7682 | 7682 | bound_arg_src: ?LazySrcLoc, |
| 7683 | 7683 | ) !Module.Fn.Index { |
| ... | ... | @@ -7737,18 +7737,19 @@ fn resolveGenericInstantiationType( |
| 7737 | 7737 | |
| 7738 | 7738 | var arg_i: usize = 0; |
| 7739 | 7739 | for (fn_info.param_body) |inst| { |
| 7740 | const generic_func_ty_info = mod.typeToFunc(generic_func_ty).?; |
| 7740 | 7741 | var is_comptime = false; |
| 7741 | 7742 | var is_anytype = false; |
| 7742 | 7743 | switch (zir_tags[inst]) { |
| 7743 | 7744 | .param => { |
| 7744 | | is_comptime = func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7745 | is_comptime = generic_func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7745 | 7746 | }, |
| 7746 | 7747 | .param_comptime => { |
| 7747 | 7748 | is_comptime = true; |
| 7748 | 7749 | }, |
| 7749 | 7750 | .param_anytype => { |
| 7750 | 7751 | is_anytype = true; |
| 7751 | | is_comptime = func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7752 | is_comptime = generic_func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7752 | 7753 | }, |
| 7753 | 7754 | .param_anytype_comptime => { |
| 7754 | 7755 | is_anytype = true; |
| ... | ... | @@ -7802,25 +7803,26 @@ fn resolveGenericInstantiationType( |
| 7802 | 7803 | const new_func = new_func_val.getFunctionIndex(mod).unwrap().?; |
| 7803 | 7804 | assert(new_func == new_module_func); |
| 7804 | 7805 | |
| 7805 | | const generic_args_index = @intCast(u32, mod.monomorphed_func_keys.items.len); |
| 7806 | | const generic_args = try mod.monomorphed_func_keys.addManyAsSlice(gpa, generic_args_len); |
| 7807 | | var generic_arg_i: u32 = 0; |
| 7808 | | try mod.monomorphed_funcs.ensureUnusedCapacityContext(gpa, generic_args_len + 1, .{ .mod = mod }); |
| 7806 | const monomorphed_args_index = @intCast(u32, mod.monomorphed_func_keys.items.len); |
| 7807 | const monomorphed_args = try mod.monomorphed_func_keys.addManyAsSlice(gpa, monomorphed_args_len); |
| 7808 | var monomorphed_arg_i: u32 = 0; |
| 7809 | try mod.monomorphed_funcs.ensureUnusedCapacityContext(gpa, monomorphed_args_len + 1, .{ .mod = mod }); |
| 7809 | 7810 | |
| 7810 | 7811 | arg_i = 0; |
| 7811 | 7812 | for (fn_info.param_body) |inst| { |
| 7813 | const generic_func_ty_info = mod.typeToFunc(generic_func_ty).?; |
| 7812 | 7814 | var is_comptime = false; |
| 7813 | 7815 | var is_anytype = false; |
| 7814 | 7816 | switch (zir_tags[inst]) { |
| 7815 | 7817 | .param => { |
| 7816 | | is_comptime = func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7818 | is_comptime = generic_func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7817 | 7819 | }, |
| 7818 | 7820 | .param_comptime => { |
| 7819 | 7821 | is_comptime = true; |
| 7820 | 7822 | }, |
| 7821 | 7823 | .param_anytype => { |
| 7822 | 7824 | is_anytype = true; |
| 7823 | | is_comptime = func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7825 | is_comptime = generic_func_ty_info.paramIsComptime(@intCast(u5, arg_i)); |
| 7824 | 7826 | }, |
| 7825 | 7827 | .param_anytype_comptime => { |
| 7826 | 7828 | is_anytype = true; |
| ... | ... | @@ -7829,40 +7831,30 @@ fn resolveGenericInstantiationType( |
| 7829 | 7831 | else => continue, |
| 7830 | 7832 | } |
| 7831 | 7833 | |
| 7832 | | // We populate the Type here regardless because it is needed by |
| 7833 | | // `GenericCallAdapter.eql` as well as function body analysis. |
| 7834 | | // Whether it is anytype is communicated by `isAnytypeParam`. |
| 7834 | const param_ty = generic_func_ty_info.param_types[arg_i]; |
| 7835 | const is_generic = !is_anytype and param_ty == .generic_poison_type; |
| 7836 | |
| 7835 | 7837 | const arg = child_sema.inst_map.get(inst).?; |
| 7836 | 7838 | const arg_ty = child_sema.typeOf(arg); |
| 7837 | 7839 | |
| 7838 | | if (try sema.typeRequiresComptime(arg_ty)) { |
| 7839 | | is_comptime = true; |
| 7840 | | } |
| 7840 | if (is_generic) if (mod.monomorphed_funcs.fetchPutAssumeCapacityContext(.{ |
| 7841 | .func = module_fn_index, |
| 7842 | .args_index = monomorphed_args_index, |
| 7843 | .args_len = monomorphed_arg_i, |
| 7844 | }, arg_ty.toIntern(), .{ .mod = mod })) |kv| assert(kv.value == arg_ty.toIntern()); |
| 7845 | if (!is_comptime and try sema.typeRequiresComptime(arg_ty)) is_comptime = true; |
| 7841 | 7846 | |
| 7842 | 7847 | if (is_comptime) { |
| 7843 | 7848 | const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(arg) catch unreachable).?; |
| 7844 | | if (!is_anytype) { |
| 7845 | | if (mod.monomorphed_funcs.fetchPutAssumeCapacityContext(.{ |
| 7846 | | .func = module_fn_index, |
| 7847 | | .args_index = generic_args_index, |
| 7848 | | .args_len = generic_arg_i, |
| 7849 | | }, arg_ty.toIntern(), .{ .mod = mod })) |kv| assert(kv.value == arg_ty.toIntern()); |
| 7850 | | } |
| 7851 | | generic_args[generic_arg_i] = arg_val.toIntern(); |
| 7852 | | generic_arg_i += 1; |
| 7853 | | child_sema.comptime_args[arg_i] = .{ |
| 7854 | | .ty = arg_ty, |
| 7855 | | .val = (try arg_val.intern(arg_ty, mod)).toValue(), |
| 7856 | | }; |
| 7849 | monomorphed_args[monomorphed_arg_i] = arg_val.toIntern(); |
| 7850 | monomorphed_arg_i += 1; |
| 7851 | child_sema.comptime_args[arg_i] = .{ .ty = arg_ty, .val = arg_val }; |
| 7857 | 7852 | } else { |
| 7858 | | if (is_anytype) { |
| 7859 | | generic_args[generic_arg_i] = arg_ty.toIntern(); |
| 7860 | | generic_arg_i += 1; |
| 7853 | if (is_anytype or is_generic) { |
| 7854 | monomorphed_args[monomorphed_arg_i] = try mod.intern(.{ .undef = arg_ty.toIntern() }); |
| 7855 | monomorphed_arg_i += 1; |
| 7861 | 7856 | } |
| 7862 | | child_sema.comptime_args[arg_i] = .{ |
| 7863 | | .ty = arg_ty, |
| 7864 | | .val = Value.generic_poison, |
| 7865 | | }; |
| 7857 | child_sema.comptime_args[arg_i] = .{ .ty = arg_ty, .val = Value.generic_poison }; |
| 7866 | 7858 | } |
| 7867 | 7859 | |
| 7868 | 7860 | arg_i += 1; |
| ... | ... | @@ -7895,8 +7887,8 @@ fn resolveGenericInstantiationType( |
| 7895 | 7887 | |
| 7896 | 7888 | mod.monomorphed_funcs.putAssumeCapacityNoClobberContext(.{ |
| 7897 | 7889 | .func = module_fn_index, |
| 7898 | | .args_index = generic_args_index, |
| 7899 | | .args_len = generic_arg_i, |
| 7890 | .args_index = monomorphed_args_index, |
| 7891 | .args_len = monomorphed_arg_i, |
| 7900 | 7892 | }, new_decl.val.toIntern(), .{ .mod = mod }); |
| 7901 | 7893 | |
| 7902 | 7894 | // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field |