| ... | ... | @@ -5643,6 +5643,37 @@ const GenericCallAdapter = struct { |
| 5643 | 5643 | } |
| 5644 | 5644 | }; |
| 5645 | 5645 | |
| 5646 | fn addComptimeReturnTypeNote( |
| 5647 | sema: *Sema, |
| 5648 | block: *Block, |
| 5649 | func: Air.Inst.Ref, |
| 5650 | func_src: LazySrcLoc, |
| 5651 | return_ty: Type, |
| 5652 | parent: *Module.ErrorMsg, |
| 5653 | requires_comptime: bool, |
| 5654 | ) !void { |
| 5655 | if (!requires_comptime) return; |
| 5656 | |
| 5657 | const src_loc = if (try sema.funcDeclSrc(block, func_src, func)) |capture| blk: { |
| 5658 | var src_loc = capture; |
| 5659 | src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 }; |
| 5660 | break :blk src_loc; |
| 5661 | } else blk: { |
| 5662 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 5663 | break :blk func_src.toSrcLoc(src_decl); |
| 5664 | }; |
| 5665 | if (return_ty.tag() == .generic_poison) { |
| 5666 | return sema.mod.errNoteNonLazy(src_loc, parent, "generic function is instantiated with a comptime only return type", .{}); |
| 5667 | } |
| 5668 | try sema.mod.errNoteNonLazy( |
| 5669 | src_loc, |
| 5670 | parent, |
| 5671 | "function is being called at comptime because it returns a comptime only type '{}'", |
| 5672 | .{return_ty.fmt(sema.mod)}, |
| 5673 | ); |
| 5674 | try sema.explainWhyTypeIsComptime(block, func_src, parent, src_loc, return_ty); |
| 5675 | } |
| 5676 | |
| 5646 | 5677 | fn analyzeCall( |
| 5647 | 5678 | sema: *Sema, |
| 5648 | 5679 | block: *Block, |
| ... | ... | @@ -5733,9 +5764,11 @@ fn analyzeCall( |
| 5733 | 5764 | |
| 5734 | 5765 | var is_generic_call = func_ty_info.is_generic; |
| 5735 | 5766 | var is_comptime_call = block.is_comptime or modifier == .compile_time; |
| 5767 | var comptime_only_ret_ty = false; |
| 5736 | 5768 | if (!is_comptime_call) { |
| 5737 | 5769 | if (sema.typeRequiresComptime(block, func_src, func_ty_info.return_type)) |ct| { |
| 5738 | 5770 | is_comptime_call = ct; |
| 5771 | comptime_only_ret_ty = ct; |
| 5739 | 5772 | } else |err| switch (err) { |
| 5740 | 5773 | error.GenericPoison => is_generic_call = true, |
| 5741 | 5774 | else => |e| return e, |
| ... | ... | @@ -5764,6 +5797,7 @@ fn analyzeCall( |
| 5764 | 5797 | error.ComptimeReturn => { |
| 5765 | 5798 | is_inline_call = true; |
| 5766 | 5799 | is_comptime_call = true; |
| 5800 | comptime_only_ret_ty = true; |
| 5767 | 5801 | }, |
| 5768 | 5802 | else => |e| return e, |
| 5769 | 5803 | } |
| ... | ... | @@ -5774,8 +5808,12 @@ fn analyzeCall( |
| 5774 | 5808 | } |
| 5775 | 5809 | |
| 5776 | 5810 | const result: Air.Inst.Ref = if (is_inline_call) res: { |
| 5777 | | // TODO explain why function is being called at comptime |
| 5778 | | const func_val = try sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known"); |
| 5811 | const func_val = sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known") catch |err| { |
| 5812 | if (err == error.AnalysisFail and sema.err != null) { |
| 5813 | try sema.addComptimeReturnTypeNote(block, func, func_src, func_ty_info.return_type, sema.err.?, comptime_only_ret_ty); |
| 5814 | } |
| 5815 | return err; |
| 5816 | }; |
| 5779 | 5817 | const module_fn = switch (func_val.tag()) { |
| 5780 | 5818 | .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data, |
| 5781 | 5819 | .function => func_val.castTag(.function).?.data, |
| ... | ... | @@ -5887,6 +5925,11 @@ fn analyzeCall( |
| 5887 | 5925 | is_comptime_call, |
| 5888 | 5926 | &should_memoize, |
| 5889 | 5927 | memoized_call_key, |
| 5928 | // last 4 arguments are only used when reporting errors |
| 5929 | undefined, |
| 5930 | undefined, |
| 5931 | undefined, |
| 5932 | undefined, |
| 5890 | 5933 | ) catch |err| switch (err) { |
| 5891 | 5934 | error.NeededSourceLocation => { |
| 5892 | 5935 | sema.inst_map.clearRetainingCapacity(); |
| ... | ... | @@ -5904,6 +5947,10 @@ fn analyzeCall( |
| 5904 | 5947 | is_comptime_call, |
| 5905 | 5948 | &should_memoize, |
| 5906 | 5949 | memoized_call_key, |
| 5950 | func, |
| 5951 | func_src, |
| 5952 | func_ty_info.return_type, |
| 5953 | comptime_only_ret_ty, |
| 5907 | 5954 | ); |
| 5908 | 5955 | return error.AnalysisFail; |
| 5909 | 5956 | }, |
| ... | ... | @@ -6119,6 +6166,10 @@ fn analyzeInlineCallArg( |
| 6119 | 6166 | is_comptime_call: bool, |
| 6120 | 6167 | should_memoize: *bool, |
| 6121 | 6168 | memoized_call_key: Module.MemoizedCall.Key, |
| 6169 | func: Air.Inst.Ref, |
| 6170 | func_src: LazySrcLoc, |
| 6171 | ret_ty: Type, |
| 6172 | comptime_only_ret_ty: bool, |
| 6122 | 6173 | ) !void { |
| 6123 | 6174 | const zir_tags = sema.code.instructions.items(.tag); |
| 6124 | 6175 | switch (zir_tags[inst]) { |
| ... | ... | @@ -6134,14 +6185,23 @@ fn analyzeInlineCallArg( |
| 6134 | 6185 | new_fn_info.param_types[arg_i.*] = param_ty; |
| 6135 | 6186 | const uncasted_arg = uncasted_args[arg_i.*]; |
| 6136 | 6187 | if (try sema.typeRequiresComptime(arg_block, arg_src, param_ty)) { |
| 6137 | | _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known"); |
| 6188 | _ = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known") catch |err| { |
| 6189 | if (err == error.AnalysisFail and sema.err != null) { |
| 6190 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); |
| 6191 | } |
| 6192 | return err; |
| 6193 | }; |
| 6138 | 6194 | } |
| 6139 | 6195 | const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src); |
| 6140 | 6196 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); |
| 6141 | 6197 | |
| 6142 | 6198 | if (is_comptime_call) { |
| 6143 | | // TODO explain why function is being called at comptime |
| 6144 | | const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known"); |
| 6199 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known") catch |err| { |
| 6200 | if (err == error.AnalysisFail and sema.err != null) { |
| 6201 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); |
| 6202 | } |
| 6203 | return err; |
| 6204 | }; |
| 6145 | 6205 | switch (arg_val.tag()) { |
| 6146 | 6206 | .generic_poison, .generic_poison_type => { |
| 6147 | 6207 | // This function is currently evaluated as part of an as-of-yet unresolvable |
| ... | ... | @@ -6171,8 +6231,12 @@ fn analyzeInlineCallArg( |
| 6171 | 6231 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); |
| 6172 | 6232 | |
| 6173 | 6233 | if (is_comptime_call) { |
| 6174 | | // TODO explain why function is being called at comptime |
| 6175 | | const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known"); |
| 6234 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known") catch |err| { |
| 6235 | if (err == error.AnalysisFail and sema.err != null) { |
| 6236 | try sema.addComptimeReturnTypeNote(arg_block, func, func_src, ret_ty, sema.err.?, comptime_only_ret_ty); |
| 6237 | } |
| 6238 | return err; |
| 6239 | }; |
| 6176 | 6240 | switch (arg_val.tag()) { |
| 6177 | 6241 | .generic_poison, .generic_poison_type => { |
| 6178 | 6242 | // This function is currently evaluated as part of an as-of-yet unresolvable |