authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-28 17:43:19-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-28 17:43:19-04:00
log232077dcf90a19316261ac5745a2a947e538c3f5
treec28297faec95ec64d5f68e84a362fef3881bd8c9
parentfe737d7a8f9a801e2db103c085a200a7477cfb08

Sema: create "called from here" notes before reference traces

This allows reference traces to begin at the outermost inline call.

1 files changed, 29 insertions(+), 25 deletions(-)

src/Sema.zig+29-25
...@@ -405,7 +405,9 @@ pub const Block = struct {...@@ -405,7 +405,9 @@ pub const Block = struct {
405 /// It is shared among all the blocks in an inline or comptime called405 /// It is shared among all the blocks in an inline or comptime called
406 /// function.406 /// function.
407 pub const Inlining = struct {407 pub const Inlining = struct {
408 /// Might be `none`.408 call_block: *Block,
409 call_src: LazySrcLoc,
410 has_comptime_args: bool,
409 func: InternPool.Index,411 func: InternPool.Index,
410 comptime_result: Air.Inst.Ref,412 comptime_result: Air.Inst.Ref,
411 merges: Merges,413 merges: Merges,
...@@ -2390,7 +2392,6 @@ pub fn fail(...@@ -2390,7 +2392,6 @@ pub fn fail(
2390}2392}
23912393
2392fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) CompileError {2394fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg) CompileError {
2393 _ = block;
2394 @setCold(true);2395 @setCold(true);
2395 const gpa = sema.gpa;2396 const gpa = sema.gpa;
2396 const mod = sema.mod;2397 const mod = sema.mod;
...@@ -2414,6 +2415,16 @@ fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg)...@@ -2414,6 +2415,16 @@ fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.ErrorMsg)
2414 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);2415 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
2415 try mod.failed_files.ensureUnusedCapacity(gpa, 1);2416 try mod.failed_files.ensureUnusedCapacity(gpa, 1);
24162417
2418 var func_index: InternPool.Index = .none;
2419 if (block) |start_block| {
2420 var block_it = start_block;
2421 while (block_it.inlining) |inlining| {
2422 func_index = inlining.func;
2423 block_it = inlining.call_block;
2424 try sema.errNote(block_it, inlining.call_src, err_msg, "called from here", .{});
2425 }
2426 }
2427
2417 const max_references = blk: {2428 const max_references = blk: {
2418 if (mod.comp.reference_trace) |num| break :blk num;2429 if (mod.comp.reference_trace) |num| break :blk num;
2419 // Do not add multiple traces without explicit request.2430 // Do not add multiple traces without explicit request.
...@@ -7268,7 +7279,10 @@ fn analyzeCall(...@@ -7268,7 +7279,10 @@ fn analyzeCall(
7268 // This one is shared among sub-blocks within the same callee, but not7279 // This one is shared among sub-blocks within the same callee, but not
7269 // shared among the entire inline/comptime call stack.7280 // shared among the entire inline/comptime call stack.
7270 var inlining: Block.Inlining = .{7281 var inlining: Block.Inlining = .{
7271 .func = .none,7282 .call_block = block,
7283 .call_src = call_src,
7284 .has_comptime_args = false,
7285 .func = module_fn_index,
7272 .comptime_result = undefined,7286 .comptime_result = undefined,
7273 .merges = .{7287 .merges = .{
7274 .src_locs = .{},7288 .src_locs = .{},
...@@ -7352,7 +7366,6 @@ fn analyzeCall(...@@ -7352,7 +7366,6 @@ fn analyzeCall(
7352 const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst);7366 const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst);
7353 try ics.callee().inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body);7367 try ics.callee().inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body);
73547368
7355 var has_comptime_args = false;
7356 var arg_i: u32 = 0;7369 var arg_i: u32 = 0;
7357 for (fn_info.param_body) |inst| {7370 for (fn_info.param_body) |inst| {
7358 const opt_noreturn_ref = try analyzeInlineCallArg(7371 const opt_noreturn_ref = try analyzeInlineCallArg(
...@@ -7368,7 +7381,6 @@ fn analyzeCall(...@@ -7368,7 +7381,6 @@ fn analyzeCall(
7368 memoized_arg_values,7381 memoized_arg_values,
7369 func_ty_info,7382 func_ty_info,
7370 func,7383 func,
7371 &has_comptime_args,
7372 );7384 );
7373 if (opt_noreturn_ref) |ref| {7385 if (opt_noreturn_ref) |ref| {
7374 // Analyzing this argument gave a ref of a noreturn type. Terminate argument analysis here.7386 // Analyzing this argument gave a ref of a noreturn type. Terminate argument analysis here.
...@@ -7380,19 +7392,18 @@ fn analyzeCall(...@@ -7380,19 +7392,18 @@ fn analyzeCall(
7380 // can just use `sema` directly.7392 // can just use `sema` directly.
7381 _ = ics.callee();7393 _ = ics.callee();
73827394
7383 if (!has_comptime_args and module_fn.analysis(ip).state == .sema_failure)7395 if (!inlining.has_comptime_args) {
7384 return error.AnalysisFail;7396 if (module_fn.analysis(ip).state == .sema_failure)
7397 return error.AnalysisFail;
73857398
7386 const recursive_msg = "inline call is recursive";7399 var block_it = block;
7387 var head = if (!has_comptime_args) block else null;7400 while (block_it.inlining) |parent_inlining| {
7388 while (head) |some| {7401 if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {
7389 const parent_inlining = some.inlining orelse break;7402 return sema.fail(block, call_src, "inline call is recursive", .{});
7390 if (parent_inlining.func == module_fn_index) {7403 }
7391 return sema.fail(block, call_src, recursive_msg, .{});7404 block_it = parent_inlining.call_block;
7392 }7405 }
7393 head = some.parent;
7394 }7406 }
7395 if (!has_comptime_args) inlining.func = module_fn_index;
73967407
7397 // In case it is a generic function with an expression for the return type that depends7408 // In case it is a generic function with an expression for the return type that depends
7398 // on parameters, we must now do the same for the return type as we just did with7409 // on parameters, we must now do the same for the return type as we just did with
...@@ -7462,12 +7473,6 @@ fn analyzeCall(...@@ -7462,12 +7473,6 @@ fn analyzeCall(
7462 const result = result: {7473 const result = result: {
7463 sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {7474 sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
7464 error.ComptimeReturn => break :result inlining.comptime_result,7475 error.ComptimeReturn => break :result inlining.comptime_result,
7465 error.AnalysisFail => {
7466 const err_msg = sema.err orelse return err;
7467 if (mem.eql(u8, err_msg.msg, recursive_msg)) return err;
7468 try sema.errNote(block, call_src, err_msg, "called from here", .{});
7469 return err;
7470 },
7471 else => |e| return e,7476 else => |e| return e,
7472 };7477 };
7473 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);7478 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
...@@ -7632,13 +7637,12 @@ fn analyzeInlineCallArg(...@@ -7632,13 +7637,12 @@ fn analyzeInlineCallArg(
7632 memoized_arg_values: []InternPool.Index,7637 memoized_arg_values: []InternPool.Index,
7633 func_ty_info: InternPool.Key.FuncType,7638 func_ty_info: InternPool.Key.FuncType,
7634 func_inst: Air.Inst.Ref,7639 func_inst: Air.Inst.Ref,
7635 has_comptime_args: *bool,
7636) !?Air.Inst.Ref {7640) !?Air.Inst.Ref {
7637 const mod = ics.sema.mod;7641 const mod = ics.sema.mod;
7638 const ip = &mod.intern_pool;7642 const ip = &mod.intern_pool;
7639 const zir_tags = ics.callee().code.instructions.items(.tag);7643 const zir_tags = ics.callee().code.instructions.items(.tag);
7640 switch (zir_tags[inst]) {7644 switch (zir_tags[inst]) {
7641 .param_comptime, .param_anytype_comptime => has_comptime_args.* = true,7645 .param_comptime, .param_anytype_comptime => param_block.inlining.?.has_comptime_args = true,
7642 else => {},7646 else => {},
7643 }7647 }
7644 switch (zir_tags[inst]) {7648 switch (zir_tags[inst]) {
...@@ -7698,7 +7702,7 @@ fn analyzeInlineCallArg(...@@ -7698,7 +7702,7 @@ fn analyzeInlineCallArg(
7698 }7702 }
76997703
7700 if (try ics.caller().resolveMaybeUndefVal(casted_arg)) |_| {7704 if (try ics.caller().resolveMaybeUndefVal(casted_arg)) |_| {
7701 has_comptime_args.* = true;7705 param_block.inlining.?.has_comptime_args = true;
7702 }7706 }
77037707
7704 arg_i.* += 1;7708 arg_i.* += 1;
...@@ -7742,7 +7746,7 @@ fn analyzeInlineCallArg(...@@ -7742,7 +7746,7 @@ fn analyzeInlineCallArg(
7742 }7746 }
77437747
7744 if (try ics.caller().resolveMaybeUndefVal(uncasted_arg)) |_| {7748 if (try ics.caller().resolveMaybeUndefVal(uncasted_arg)) |_| {
7745 has_comptime_args.* = true;7749 param_block.inlining.?.has_comptime_args = true;
7746 }7750 }
77477751
7748 arg_i.* += 1;7752 arg_i.* += 1;