| ... | ... | @@ -444,13 +444,19 @@ pub const Block = struct { |
| 444 | 444 | pub const Inlining = struct { |
| 445 | 445 | call_block: *Block, |
| 446 | 446 | call_src: LazySrcLoc, |
| 447 | | has_comptime_args: bool, |
| 448 | 447 | func: InternPool.Index, |
| 449 | | comptime_result: Air.Inst.Ref, |
| 450 | | merges: Merges, |
| 448 | |
| 451 | 449 | /// Populated lazily by `refFrame`. |
| 452 | 450 | ref_frame: Zcu.InlineReferenceFrame.Index.Optional = .none, |
| 453 | 451 | |
| 452 | /// If `true`, the following fields are `undefined`. This doesn't represent a true inline |
| 453 | /// call, but rather a generic call analyzing the instantiation's generic type bodies. |
| 454 | is_generic_instantiation: bool, |
| 455 | |
| 456 | has_comptime_args: bool, |
| 457 | comptime_result: Air.Inst.Ref, |
| 458 | merges: Merges, |
| 459 | |
| 454 | 460 | fn refFrame(inlining: *Inlining, zcu: *Zcu) Allocator.Error!Zcu.InlineReferenceFrame.Index { |
| 455 | 461 | if (inlining.ref_frame == .none) { |
| 456 | 462 | inlining.ref_frame = (try zcu.addInlineReferenceFrame(.{ |
| ... | ... | @@ -2604,12 +2610,12 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg |
| 2604 | 2610 | if (block) |start_block| { |
| 2605 | 2611 | var block_it = start_block; |
| 2606 | 2612 | while (block_it.inlining) |inlining| { |
| 2607 | | try sema.errNote( |
| 2608 | | inlining.call_src, |
| 2609 | | err_msg, |
| 2610 | | "called from here", |
| 2611 | | .{}, |
| 2612 | | ); |
| 2613 | const note_str = note: { |
| 2614 | if (inlining.is_generic_instantiation) break :note "generic function instantiated here"; |
| 2615 | if (inlining.call_block.isComptime()) break :note "called at comptime here"; |
| 2616 | break :note "called inline here"; |
| 2617 | }; |
| 2618 | try sema.errNote(inlining.call_src, err_msg, "{s}", .{note_str}); |
| 2613 | 2619 | block_it = inlining.call_block; |
| 2614 | 2620 | } |
| 2615 | 2621 | } |
| ... | ... | @@ -7736,9 +7742,10 @@ fn analyzeCall( |
| 7736 | 7742 | .call_block = block, |
| 7737 | 7743 | .call_src = call_src, |
| 7738 | 7744 | .func = func_val.?.toIntern(), |
| 7739 | | .has_comptime_args = false, // unused by error reporting |
| 7740 | | .comptime_result = .none, // unused by error reporting |
| 7741 | | .merges = undefined, // unused because we'll never `return` |
| 7745 | .is_generic_instantiation = true, // this allows the following fields to be `undefined` |
| 7746 | .has_comptime_args = undefined, |
| 7747 | .comptime_result = undefined, |
| 7748 | .merges = undefined, |
| 7742 | 7749 | } else undefined; |
| 7743 | 7750 | |
| 7744 | 7751 | // This is the block in which we evaluate generic function components: that is, generic parameter |
| ... | ... | @@ -8216,10 +8223,11 @@ fn analyzeCall( |
| 8216 | 8223 | var inlining: Block.Inlining = .{ |
| 8217 | 8224 | .call_block = block, |
| 8218 | 8225 | .call_src = call_src, |
| 8226 | .func = func_val.?.toIntern(), |
| 8227 | .is_generic_instantiation = false, |
| 8219 | 8228 | .has_comptime_args = for (args) |a| { |
| 8220 | 8229 | if (try sema.isComptimeKnown(a)) break true; |
| 8221 | 8230 | } else false, |
| 8222 | | .func = func_val.?.toIntern(), |
| 8223 | 8231 | .comptime_result = undefined, |
| 8224 | 8232 | .merges = .{ |
| 8225 | 8233 | .block_inst = block_inst, |
| ... | ... | @@ -8250,7 +8258,10 @@ fn analyzeCall( |
| 8250 | 8258 | if (!inlining.has_comptime_args) { |
| 8251 | 8259 | var block_it = block; |
| 8252 | 8260 | while (block_it.inlining) |parent_inlining| { |
| 8253 | | if (!parent_inlining.has_comptime_args and parent_inlining.func == func_val.?.toIntern()) { |
| 8261 | if (!parent_inlining.is_generic_instantiation and |
| 8262 | !parent_inlining.has_comptime_args and |
| 8263 | parent_inlining.func == func_val.?.toIntern()) |
| 8264 | { |
| 8254 | 8265 | return sema.fail(block, call_src, "inline call is recursive", .{}); |
| 8255 | 8266 | } |
| 8256 | 8267 | block_it = parent_inlining.call_block; |
| ... | ... | @@ -19454,6 +19465,7 @@ fn analyzeRet( |
| 19454 | 19465 | }; |
| 19455 | 19466 | |
| 19456 | 19467 | if (block.inlining) |inlining| { |
| 19468 | assert(!inlining.is_generic_instantiation); // can't `return` in a generic param/ret ty expr |
| 19457 | 19469 | if (block.isComptime()) { |
| 19458 | 19470 | const ret_val = try sema.resolveConstValue(block, operand_src, operand, null); |
| 19459 | 19471 | inlining.comptime_result = operand; |