| ... | @@ -2793,16 +2793,24 @@ fn analyzeCall( | ... | @@ -2793,16 +2793,24 @@ fn analyzeCall( |
| 2793 | } else if (is_comptime) { | 2793 | } else if (is_comptime) { |
| 2794 | return sema.failWithNeededComptime(block, arg_src); | 2794 | return sema.failWithNeededComptime(block, arg_src); |
| 2795 | } else if (is_anytype) { | 2795 | } else if (is_anytype) { |
| 2796 | const child_arg = try child_sema.addConstant( | 2796 | // We insert into the map an instruction which is runtime-known |
| 2797 | sema.typeOf(arg), | 2797 | // but has the type of the comptime argument. |
| 2798 | Value.initTag(.generic_poison), | 2798 | const child_arg = try child_block.addArg(sema.typeOf(arg), 0); |
| 2799 | ); | | |
| 2800 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); | 2799 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 2801 | } | 2800 | } |
| 2802 | arg_i += 1; | 2801 | arg_i += 1; |
| 2803 | } | 2802 | } |
| 2804 | const new_func_inst = try child_sema.resolveBody(&child_block, fn_info.param_body); | 2803 | const new_func_inst = child_sema.resolveBody(&child_block, fn_info.param_body) catch |err| { |
| 2805 | const new_func_val = try child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst); | 2804 | // TODO look up the compile error that happened here and attach a note to it |
| | 2805 | // pointing here, at the generic instantiation callsite. |
| | 2806 | if (sema.owner_func) |owner_func| { |
| | 2807 | owner_func.state = .dependency_failure; |
| | 2808 | } else { |
| | 2809 | sema.owner_decl.analysis = .dependency_failure; |
| | 2810 | } |
| | 2811 | return err; |
| | 2812 | }; |
| | 2813 | const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst) catch unreachable; |
| 2806 | const new_func = new_func_val.castTag(.function).?.data; | 2814 | const new_func = new_func_val.castTag(.function).?.data; |
| 2807 | assert(new_func == new_module_func); | 2815 | assert(new_func == new_module_func); |
| 2808 | | 2816 | |
| ... | @@ -2813,12 +2821,22 @@ fn analyzeCall( | ... | @@ -2813,12 +2821,22 @@ fn analyzeCall( |
| 2813 | else => continue, | 2821 | else => continue, |
| 2814 | } | 2822 | } |
| 2815 | const arg = child_sema.inst_map.get(inst).?; | 2823 | const arg = child_sema.inst_map.get(inst).?; |
| 2816 | const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(&child_block, .unneeded, arg) catch unreachable).?; | 2824 | const copied_arg_ty = try child_sema.typeOf(arg).copy(&new_decl_arena.allocator); |
| 2817 | | 2825 | if (child_sema.resolveMaybeUndefValAllowVariables( |
| 2818 | child_sema.comptime_args[arg_i] = .{ | 2826 | &child_block, |
| 2819 | .ty = try child_sema.typeOf(arg).copy(&new_decl_arena.allocator), | 2827 | .unneeded, |
| 2820 | .val = try arg_val.copy(&new_decl_arena.allocator), | 2828 | arg, |
| 2821 | }; | 2829 | ) catch unreachable) |arg_val| { |
| | 2830 | child_sema.comptime_args[arg_i] = .{ |
| | 2831 | .ty = copied_arg_ty, |
| | 2832 | .val = try arg_val.copy(&new_decl_arena.allocator), |
| | 2833 | }; |
| | 2834 | } else { |
| | 2835 | child_sema.comptime_args[arg_i] = .{ |
| | 2836 | .ty = copied_arg_ty, |
| | 2837 | .val = Value.initTag(.generic_poison), |
| | 2838 | }; |
| | 2839 | } |
| 2822 | | 2840 | |
| 2823 | arg_i += 1; | 2841 | arg_i += 1; |
| 2824 | } | 2842 | } |
| ... | @@ -2828,17 +2846,10 @@ fn analyzeCall( | ... | @@ -2828,17 +2846,10 @@ fn analyzeCall( |
| 2828 | new_decl.val = try Value.Tag.function.create(&new_decl_arena.allocator, new_func); | 2846 | new_decl.val = try Value.Tag.function.create(&new_decl_arena.allocator, new_func); |
| 2829 | new_decl.analysis = .complete; | 2847 | new_decl.analysis = .complete; |
| 2830 | | 2848 | |
| 2831 | if (new_decl.ty.fnInfo().is_generic) { | | |
| 2832 | // TODO improve this error message. This can happen because of the parameter | | |
| 2833 | // type expression or return type expression depending on runtime-provided values. | | |
| 2834 | // The error message should be emitted in zirParam or funcCommon when it | | |
| 2835 | // is determined that we are trying to instantiate a generic function. | | |
| 2836 | return mod.fail(&block.base, call_src, "unable to monomorphize function", .{}); | | |
| 2837 | } | | |
| 2838 | | | |
| 2839 | log.debug("generic function '{s}' instantiated with type {}", .{ | 2849 | log.debug("generic function '{s}' instantiated with type {}", .{ |
| 2840 | new_decl.name, new_decl.ty, | 2850 | new_decl.name, new_decl.ty, |
| 2841 | }); | 2851 | }); |
| | 2852 | assert(!new_decl.ty.fnInfo().is_generic); |
| 2842 | | 2853 | |
| 2843 | // The generic function Decl is guaranteed to be the first dependency | 2854 | // The generic function Decl is guaranteed to be the first dependency |
| 2844 | // of each of its instantiations. | 2855 | // of each of its instantiations. |
| ... | @@ -8371,8 +8382,8 @@ fn analyzeDeclVal( | ... | @@ -8371,8 +8382,8 @@ fn analyzeDeclVal( |
| 8371 | fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { | 8382 | fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { |
| 8372 | try sema.mod.declareDeclDependency(sema.owner_decl, decl); | 8383 | try sema.mod.declareDeclDependency(sema.owner_decl, decl); |
| 8373 | sema.mod.ensureDeclAnalyzed(decl) catch |err| { | 8384 | sema.mod.ensureDeclAnalyzed(decl) catch |err| { |
| 8374 | if (sema.func) |func| { | 8385 | if (sema.owner_func) |owner_func| { |
| 8375 | func.state = .dependency_failure; | 8386 | owner_func.state = .dependency_failure; |
| 8376 | } else { | 8387 | } else { |
| 8377 | sema.owner_decl.analysis = .dependency_failure; | 8388 | sema.owner_decl.analysis = .dependency_failure; |
| 8378 | } | 8389 | } |