| author | |
| committer | |
| log | 9064907b34128d66ffae8d15e075eddab7af0153 |
| tree | 00cd0fb6c0a19ce56074b14947f36ef6f4ff035d |
| parent | 9279ff888bd1b00d4369b4d234e31a161f02a247 |
| parent | 46d7e808dcef3c9f9200d6cc1ed4e3a787ba054d |
| signature |
compiler: reference trace fixes29 files changed, 253 insertions(+), 150 deletions(-)
lib/compiler/build_runner.zig+2-6| ... | ... | @@ -750,7 +750,7 @@ fn runStepNames( |
| 750 | 750 | if (run.prominent_compile_errors and total_compile_errors > 0) { |
| 751 | 751 | for (step_stack.keys()) |s| { |
| 752 | 752 | if (s.result_error_bundle.errorMessageCount() > 0) { |
| 753 | s.result_error_bundle.renderToStdErr(.{ .ttyconf = ttyconf, .include_reference_trace = (b.reference_trace orelse 0) > 0 }); | |
| 753 | s.result_error_bundle.renderToStdErr(.{ .ttyconf = ttyconf }); | |
| 754 | 754 | } |
| 755 | 755 | } |
| 756 | 756 | |
| ... | ... | @@ -1129,11 +1129,7 @@ fn workerMakeOneStep( |
| 1129 | 1129 | defer std.debug.unlockStdErr(); |
| 1130 | 1130 | |
| 1131 | 1131 | const gpa = b.allocator; |
| 1132 | const options: std.zig.ErrorBundle.RenderOptions = .{ | |
| 1133 | .ttyconf = run.ttyconf, | |
| 1134 | .include_reference_trace = (b.reference_trace orelse 0) > 0, | |
| 1135 | }; | |
| 1136 | printErrorMessages(gpa, s, options, run.stderr, run.prominent_compile_errors) catch {}; | |
| 1132 | printErrorMessages(gpa, s, .{ .ttyconf = run.ttyconf }, run.stderr, run.prominent_compile_errors) catch {}; | |
| 1137 | 1133 | } |
| 1138 | 1134 | |
| 1139 | 1135 | handle_result: { |
src/Compilation.zig+65-30| ... | ... | @@ -3328,7 +3328,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3328 | 3328 | if (comp.zcu) |zcu| zcu_errors: { |
| 3329 | 3329 | for (zcu.failed_files.keys(), zcu.failed_files.values()) |file, error_msg| { |
| 3330 | 3330 | if (error_msg) |msg| { |
| 3331 | try addModuleErrorMsg(zcu, &bundle, msg.*); | |
| 3331 | try addModuleErrorMsg(zcu, &bundle, msg.*, false); | |
| 3332 | 3332 | } else { |
| 3333 | 3333 | // Must be ZIR or Zoir errors. Note that this may include AST errors. |
| 3334 | 3334 | _ = try file.getTree(gpa); // Tree must be loaded. |
| ... | ... | @@ -3378,6 +3378,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3378 | 3378 | break :s entries.slice(); |
| 3379 | 3379 | }; |
| 3380 | 3380 | defer sorted_failed_analysis.deinit(gpa); |
| 3381 | var added_any_analysis_error = false; | |
| 3381 | 3382 | for (sorted_failed_analysis.items(.key), sorted_failed_analysis.items(.value)) |anal_unit, error_msg| { |
| 3382 | 3383 | if (comp.incremental) { |
| 3383 | 3384 | const refs = try zcu.resolveReferences(); |
| ... | ... | @@ -3389,7 +3390,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3389 | 3390 | zcu.fmtAnalUnit(anal_unit), |
| 3390 | 3391 | }); |
| 3391 | 3392 | |
| 3392 | try addModuleErrorMsg(zcu, &bundle, error_msg.*); | |
| 3393 | try addModuleErrorMsg(zcu, &bundle, error_msg.*, added_any_analysis_error); | |
| 3394 | added_any_analysis_error = true; | |
| 3395 | ||
| 3393 | 3396 | if (zcu.cimport_errors.get(anal_unit)) |errors| { |
| 3394 | 3397 | for (errors.getMessages()) |err_msg_index| { |
| 3395 | 3398 | const err_msg = errors.getErrorMessage(err_msg_index); |
| ... | ... | @@ -3412,13 +3415,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3412 | 3415 | } |
| 3413 | 3416 | } |
| 3414 | 3417 | for (zcu.failed_codegen.values()) |error_msg| { |
| 3415 | try addModuleErrorMsg(zcu, &bundle, error_msg.*); | |
| 3418 | try addModuleErrorMsg(zcu, &bundle, error_msg.*, false); | |
| 3416 | 3419 | } |
| 3417 | 3420 | for (zcu.failed_types.values()) |error_msg| { |
| 3418 | try addModuleErrorMsg(zcu, &bundle, error_msg.*); | |
| 3421 | try addModuleErrorMsg(zcu, &bundle, error_msg.*, false); | |
| 3419 | 3422 | } |
| 3420 | 3423 | for (zcu.failed_exports.values()) |value| { |
| 3421 | try addModuleErrorMsg(zcu, &bundle, value.*); | |
| 3424 | try addModuleErrorMsg(zcu, &bundle, value.*, false); | |
| 3422 | 3425 | } |
| 3423 | 3426 | |
| 3424 | 3427 | const actual_error_count = zcu.intern_pool.global_error_set.getNamesFromMainThread().len; |
| ... | ... | @@ -3527,7 +3530,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3527 | 3530 | // We don't actually include the error here if `!include_compile_log_sources`. |
| 3528 | 3531 | // The sorting above was still necessary, though, to get `log_text` in the right order. |
| 3529 | 3532 | if (include_compile_log_sources) { |
| 3530 | try addModuleErrorMsg(zcu, &bundle, messages.items[0]); | |
| 3533 | try addModuleErrorMsg(zcu, &bundle, messages.items[0], false); | |
| 3531 | 3534 | } |
| 3532 | 3535 | |
| 3533 | 3536 | break :compile_log_text try log_text.toOwnedSlice(gpa); |
| ... | ... | @@ -3631,10 +3634,14 @@ pub const ErrorNoteHashContext = struct { |
| 3631 | 3634 | } |
| 3632 | 3635 | }; |
| 3633 | 3636 | |
| 3637 | const default_reference_trace_len = 2; | |
| 3634 | 3638 | pub fn addModuleErrorMsg( |
| 3635 | 3639 | zcu: *Zcu, |
| 3636 | 3640 | eb: *ErrorBundle.Wip, |
| 3637 | 3641 | module_err_msg: Zcu.ErrorMsg, |
| 3642 | /// If `-freference-trace` is not specified, we only want to show the one reference trace. | |
| 3643 | /// So, this is whether we have already emitted an error with a reference trace. | |
| 3644 | already_added_error: bool, | |
| 3638 | 3645 | ) !void { |
| 3639 | 3646 | const gpa = eb.gpa; |
| 3640 | 3647 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -3657,45 +3664,44 @@ pub fn addModuleErrorMsg( |
| 3657 | 3664 | var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty; |
| 3658 | 3665 | defer ref_traces.deinit(gpa); |
| 3659 | 3666 | |
| 3660 | if (module_err_msg.reference_trace_root.unwrap()) |rt_root| { | |
| 3667 | rt: { | |
| 3668 | const rt_root = module_err_msg.reference_trace_root.unwrap() orelse break :rt; | |
| 3669 | const max_references = zcu.comp.reference_trace orelse refs: { | |
| 3670 | if (already_added_error) break :rt; | |
| 3671 | break :refs default_reference_trace_len; | |
| 3672 | }; | |
| 3673 | ||
| 3661 | 3674 | const all_references = try zcu.resolveReferences(); |
| 3662 | 3675 | |
| 3663 | 3676 | var seen: std.AutoHashMapUnmanaged(InternPool.AnalUnit, void) = .empty; |
| 3664 | 3677 | defer seen.deinit(gpa); |
| 3665 | 3678 | |
| 3666 | const max_references = zcu.comp.reference_trace orelse Sema.default_reference_trace_len; | |
| 3667 | ||
| 3668 | 3679 | var referenced_by = rt_root; |
| 3669 | 3680 | while (all_references.get(referenced_by)) |maybe_ref| { |
| 3670 | 3681 | const ref = maybe_ref orelse break; |
| 3671 | 3682 | const gop = try seen.getOrPut(gpa, ref.referencer); |
| 3672 | 3683 | if (gop.found_existing) break; |
| 3673 | if (ref_traces.items.len < max_references) skip: { | |
| 3674 | const src = ref.src.upgrade(zcu); | |
| 3675 | const source = try src.file_scope.getSource(gpa); | |
| 3676 | const span = try src.span(gpa); | |
| 3677 | const loc = std.zig.findLineColumn(source.bytes, span.main); | |
| 3678 | const rt_file_path = try src.file_scope.fullPath(gpa); | |
| 3679 | defer gpa.free(rt_file_path); | |
| 3680 | const name = switch (ref.referencer.unwrap()) { | |
| 3684 | if (ref_traces.items.len < max_references) { | |
| 3685 | var last_call_src = ref.src; | |
| 3686 | var opt_inline_frame = ref.inline_frame; | |
| 3687 | while (opt_inline_frame.unwrap()) |inline_frame| { | |
| 3688 | const f = inline_frame.ptr(zcu).*; | |
| 3689 | const func_nav = ip.indexToKey(f.callee).func.owner_nav; | |
| 3690 | const func_name = ip.getNav(func_nav).name.toSlice(ip); | |
| 3691 | try addReferenceTraceFrame(zcu, eb, &ref_traces, func_name, last_call_src, true); | |
| 3692 | last_call_src = f.call_src; | |
| 3693 | opt_inline_frame = f.parent; | |
| 3694 | } | |
| 3695 | const root_name: ?[]const u8 = switch (ref.referencer.unwrap()) { | |
| 3681 | 3696 | .@"comptime" => "comptime", |
| 3682 | 3697 | .nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip), |
| 3683 | 3698 | .type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), |
| 3684 | 3699 | .func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip), |
| 3685 | .memoized_state => break :skip, | |
| 3700 | .memoized_state => null, | |
| 3686 | 3701 | }; |
| 3687 | try ref_traces.append(gpa, .{ | |
| 3688 | .decl_name = try eb.addString(name), | |
| 3689 | .src_loc = try eb.addSourceLocation(.{ | |
| 3690 | .src_path = try eb.addString(rt_file_path), | |
| 3691 | .span_start = span.start, | |
| 3692 | .span_main = span.main, | |
| 3693 | .span_end = span.end, | |
| 3694 | .line = @intCast(loc.line), | |
| 3695 | .column = @intCast(loc.column), | |
| 3696 | .source_line = 0, | |
| 3697 | }), | |
| 3698 | }); | |
| 3702 | if (root_name) |n| { | |
| 3703 | try addReferenceTraceFrame(zcu, eb, &ref_traces, n, last_call_src, false); | |
| 3704 | } | |
| 3699 | 3705 | } |
| 3700 | 3706 | referenced_by = ref.referencer; |
| 3701 | 3707 | } |
| ... | ... | @@ -3775,6 +3781,35 @@ pub fn addModuleErrorMsg( |
| 3775 | 3781 | } |
| 3776 | 3782 | } |
| 3777 | 3783 | |
| 3784 | fn addReferenceTraceFrame( | |
| 3785 | zcu: *Zcu, | |
| 3786 | eb: *ErrorBundle.Wip, | |
| 3787 | ref_traces: *std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace), | |
| 3788 | name: []const u8, | |
| 3789 | lazy_src: Zcu.LazySrcLoc, | |
| 3790 | inlined: bool, | |
| 3791 | ) !void { | |
| 3792 | const gpa = zcu.gpa; | |
| 3793 | const src = lazy_src.upgrade(zcu); | |
| 3794 | const source = try src.file_scope.getSource(gpa); | |
| 3795 | const span = try src.span(gpa); | |
| 3796 | const loc = std.zig.findLineColumn(source.bytes, span.main); | |
| 3797 | const rt_file_path = try src.file_scope.fullPath(gpa); | |
| 3798 | defer gpa.free(rt_file_path); | |
| 3799 | try ref_traces.append(gpa, .{ | |
| 3800 | .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }), | |
| 3801 | .src_loc = try eb.addSourceLocation(.{ | |
| 3802 | .src_path = try eb.addString(rt_file_path), | |
| 3803 | .span_start = span.start, | |
| 3804 | .span_main = span.main, | |
| 3805 | .span_end = span.end, | |
| 3806 | .line = @intCast(loc.line), | |
| 3807 | .column = @intCast(loc.column), | |
| 3808 | .source_line = 0, | |
| 3809 | }), | |
| 3810 | }); | |
| 3811 | } | |
| 3812 | ||
| 3778 | 3813 | pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void { |
| 3779 | 3814 | const gpa = eb.gpa; |
| 3780 | 3815 | const src_path = try file.fullPath(gpa); |
src/Sema.zig+77-51| ... | ... | @@ -191,7 +191,6 @@ const LowerZon = @import("Sema/LowerZon.zig"); |
| 191 | 191 | const arith = @import("Sema/arith.zig"); |
| 192 | 192 | |
| 193 | 193 | pub const default_branch_quota = 1000; |
| 194 | pub const default_reference_trace_len = 2; | |
| 195 | 194 | |
| 196 | 195 | pub const InferredErrorSet = struct { |
| 197 | 196 | /// The function body from which this error set originates. |
| ... | ... | @@ -445,10 +444,31 @@ pub const Block = struct { |
| 445 | 444 | pub const Inlining = struct { |
| 446 | 445 | call_block: *Block, |
| 447 | 446 | call_src: LazySrcLoc, |
| 448 | has_comptime_args: bool, | |
| 449 | 447 | func: InternPool.Index, |
| 448 | ||
| 449 | /// Populated lazily by `refFrame`. | |
| 450 | ref_frame: Zcu.InlineReferenceFrame.Index.Optional = .none, | |
| 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, | |
| 450 | 457 | comptime_result: Air.Inst.Ref, |
| 451 | 458 | merges: Merges, |
| 459 | ||
| 460 | fn refFrame(inlining: *Inlining, zcu: *Zcu) Allocator.Error!Zcu.InlineReferenceFrame.Index { | |
| 461 | if (inlining.ref_frame == .none) { | |
| 462 | inlining.ref_frame = (try zcu.addInlineReferenceFrame(.{ | |
| 463 | .callee = inlining.func, | |
| 464 | .call_src = inlining.call_src, | |
| 465 | .parent = if (inlining.call_block.inlining) |parent_inlining| p: { | |
| 466 | break :p (try parent_inlining.refFrame(zcu)).toOptional(); | |
| 467 | } else .none, | |
| 468 | })).toOptional(); | |
| 469 | } | |
| 470 | return inlining.ref_frame.unwrap().?; | |
| 471 | } | |
| 452 | 472 | }; |
| 453 | 473 | |
| 454 | 474 | pub const Merges = struct { |
| ... | ... | @@ -2580,7 +2600,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg |
| 2580 | 2600 | if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) { |
| 2581 | 2601 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 2582 | 2602 | wip_errors.init(gpa) catch @panic("out of memory"); |
| 2583 | Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*) catch @panic("out of memory"); | |
| 2603 | Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory"); | |
| 2584 | 2604 | std.debug.print("compile error during Sema:\n", .{}); |
| 2585 | 2605 | var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory"); |
| 2586 | 2606 | error_bundle.renderToStdErr(.{ .ttyconf = .no_color }); |
| ... | ... | @@ -2590,20 +2610,17 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg |
| 2590 | 2610 | if (block) |start_block| { |
| 2591 | 2611 | var block_it = start_block; |
| 2592 | 2612 | while (block_it.inlining) |inlining| { |
| 2593 | try sema.errNote( | |
| 2594 | inlining.call_src, | |
| 2595 | err_msg, | |
| 2596 | "called from here", | |
| 2597 | .{}, | |
| 2598 | ); | |
| 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}); | |
| 2599 | 2619 | block_it = inlining.call_block; |
| 2600 | 2620 | } |
| 2601 | 2621 | } |
| 2602 | 2622 | |
| 2603 | const use_ref_trace = if (zcu.comp.reference_trace) |n| n > 0 else zcu.failed_analysis.count() == 0; | |
| 2604 | if (use_ref_trace) { | |
| 2605 | err_msg.reference_trace_root = sema.owner.toOptional(); | |
| 2606 | } | |
| 2623 | err_msg.reference_trace_root = sema.owner.toOptional(); | |
| 2607 | 2624 | |
| 2608 | 2625 | const gop = try zcu.failed_analysis.getOrPut(gpa, sema.owner); |
| 2609 | 2626 | if (gop.found_existing) { |
| ... | ... | @@ -4291,7 +4308,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4291 | 4308 | if (zcu.intern_pool.isFuncBody(val)) { |
| 4292 | 4309 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(val)); |
| 4293 | 4310 | if (try ty.fnHasRuntimeBitsSema(pt)) { |
| 4294 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = val })); | |
| 4311 | try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = val })); | |
| 4295 | 4312 | try zcu.ensureFuncBodyAnalysisQueued(val); |
| 4296 | 4313 | } |
| 4297 | 4314 | } |
| ... | ... | @@ -6619,7 +6636,7 @@ pub fn analyzeExport( |
| 6619 | 6636 | if (options.linkage == .internal) |
| 6620 | 6637 | return; |
| 6621 | 6638 | |
| 6622 | try sema.ensureNavResolved(src, orig_nav_index, .fully); | |
| 6639 | try sema.ensureNavResolved(block, src, orig_nav_index, .fully); | |
| 6623 | 6640 | |
| 6624 | 6641 | const exported_nav_index = switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) { |
| 6625 | 6642 | .variable => |v| v.owner_nav, |
| ... | ... | @@ -6648,7 +6665,7 @@ pub fn analyzeExport( |
| 6648 | 6665 | return sema.fail(block, src, "export target cannot be extern", .{}); |
| 6649 | 6666 | } |
| 6650 | 6667 | |
| 6651 | try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index); | |
| 6668 | try sema.maybeQueueFuncBodyAnalysis(block, src, exported_nav_index); | |
| 6652 | 6669 | |
| 6653 | 6670 | try sema.exports.append(gpa, .{ |
| 6654 | 6671 | .opts = options, |
| ... | ... | @@ -6896,7 +6913,7 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6896 | 6913 | .no_embedded_nulls, |
| 6897 | 6914 | ); |
| 6898 | 6915 | const nav_index = try sema.lookupIdentifier(block, src, decl_name); |
| 6899 | return sema.analyzeNavRef(src, nav_index); | |
| 6916 | return sema.analyzeNavRef(block, src, nav_index); | |
| 6900 | 6917 | } |
| 6901 | 6918 | |
| 6902 | 6919 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -6992,7 +7009,7 @@ fn lookupInNamespace( |
| 6992 | 7009 | } |
| 6993 | 7010 | |
| 6994 | 7011 | for (usingnamespaces.items) |sub_ns_nav| { |
| 6995 | try sema.ensureNavResolved(src, sub_ns_nav, .fully); | |
| 7012 | try sema.ensureNavResolved(block, src, sub_ns_nav, .fully); | |
| 6996 | 7013 | const sub_ns_ty = Type.fromInterned(ip.getNav(sub_ns_nav).status.fully_resolved.val); |
| 6997 | 7014 | const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu)); |
| 6998 | 7015 | try checked_namespaces.put(gpa, sub_ns, {}); |
| ... | ... | @@ -7724,10 +7741,11 @@ fn analyzeCall( |
| 7724 | 7741 | var generic_inlining: Block.Inlining = if (func_ty_info.is_generic) .{ |
| 7725 | 7742 | .call_block = block, |
| 7726 | 7743 | .call_src = call_src, |
| 7727 | .has_comptime_args = false, // unused by error reporting | |
| 7728 | .func = .none, // unused by error reporting | |
| 7729 | .comptime_result = .none, // unused by error reporting | |
| 7730 | .merges = undefined, // unused because we'll never `return` | |
| 7744 | .func = func_val.?.toIntern(), | |
| 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, | |
| 7731 | 7749 | } else undefined; |
| 7732 | 7750 | |
| 7733 | 7751 | // This is the block in which we evaluate generic function components: that is, generic parameter |
| ... | ... | @@ -8003,7 +8021,7 @@ fn analyzeCall( |
| 8003 | 8021 | ref_func: { |
| 8004 | 8022 | const runtime_func_val = try sema.resolveValue(runtime_func) orelse break :ref_func; |
| 8005 | 8023 | if (!ip.isFuncBody(runtime_func_val.toIntern())) break :ref_func; |
| 8006 | try sema.addReferenceEntry(call_src, .wrap(.{ .func = runtime_func_val.toIntern() })); | |
| 8024 | try sema.addReferenceEntry(block, call_src, .wrap(.{ .func = runtime_func_val.toIntern() })); | |
| 8007 | 8025 | try zcu.ensureFuncBodyAnalysisQueued(runtime_func_val.toIntern()); |
| 8008 | 8026 | } |
| 8009 | 8027 | |
| ... | ... | @@ -8205,10 +8223,11 @@ fn analyzeCall( |
| 8205 | 8223 | var inlining: Block.Inlining = .{ |
| 8206 | 8224 | .call_block = block, |
| 8207 | 8225 | .call_src = call_src, |
| 8226 | .func = func_val.?.toIntern(), | |
| 8227 | .is_generic_instantiation = false, | |
| 8208 | 8228 | .has_comptime_args = for (args) |a| { |
| 8209 | 8229 | if (try sema.isComptimeKnown(a)) break true; |
| 8210 | 8230 | } else false, |
| 8211 | .func = func_val.?.toIntern(), | |
| 8212 | 8231 | .comptime_result = undefined, |
| 8213 | 8232 | .merges = .{ |
| 8214 | 8233 | .block_inst = block_inst, |
| ... | ... | @@ -8239,7 +8258,10 @@ fn analyzeCall( |
| 8239 | 8258 | if (!inlining.has_comptime_args) { |
| 8240 | 8259 | var block_it = block; |
| 8241 | 8260 | while (block_it.inlining) |parent_inlining| { |
| 8242 | 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 | { | |
| 8243 | 8265 | return sema.fail(block, call_src, "inline call is recursive", .{}); |
| 8244 | 8266 | } |
| 8245 | 8267 | block_it = parent_inlining.call_block; |
| ... | ... | @@ -17258,7 +17280,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17258 | 17280 | .@"comptime" => |index| return Air.internedToRef(index), |
| 17259 | 17281 | .runtime => |index| index, |
| 17260 | 17282 | .nav_val => |nav| return sema.analyzeNavVal(block, src, nav), |
| 17261 | .nav_ref => |nav| return sema.analyzeNavRef(src, nav), | |
| 17283 | .nav_ref => |nav| return sema.analyzeNavRef(block, src, nav), | |
| 17262 | 17284 | }; |
| 17263 | 17285 | |
| 17264 | 17286 | // The comptime case is handled already above. Runtime case below. |
| ... | ... | @@ -18411,7 +18433,7 @@ fn typeInfoNamespaceDecls( |
| 18411 | 18433 | if (zcu.analysis_in_progress.contains(.wrap(.{ .nav_val = nav }))) { |
| 18412 | 18434 | continue; |
| 18413 | 18435 | } |
| 18414 | try sema.ensureNavResolved(src, nav, .fully); | |
| 18436 | try sema.ensureNavResolved(block, src, nav, .fully); | |
| 18415 | 18437 | const namespace_ty = Type.fromInterned(ip.getNav(nav).status.fully_resolved.val); |
| 18416 | 18438 | try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces); |
| 18417 | 18439 | } |
| ... | ... | @@ -19443,6 +19465,7 @@ fn analyzeRet( |
| 19443 | 19465 | }; |
| 19444 | 19466 | |
| 19445 | 19467 | if (block.inlining) |inlining| { |
| 19468 | assert(!inlining.is_generic_instantiation); // can't `return` in a generic param/ret ty expr | |
| 19446 | 19469 | if (block.isComptime()) { |
| 19447 | 19470 | const ret_val = try sema.resolveConstValue(block, operand_src, operand, null); |
| 19448 | 19471 | inlining.comptime_result = operand; |
| ... | ... | @@ -27936,7 +27959,7 @@ fn namespaceLookupRef( |
| 27936 | 27959 | decl_name: InternPool.NullTerminatedString, |
| 27937 | 27960 | ) CompileError!?Air.Inst.Ref { |
| 27938 | 27961 | const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null; |
| 27939 | return try sema.analyzeNavRef(src, nav); | |
| 27962 | return try sema.analyzeNavRef(block, src, nav); | |
| 27940 | 27963 | } |
| 27941 | 27964 | |
| 27942 | 27965 | fn namespaceLookupVal( |
| ... | ... | @@ -29099,7 +29122,7 @@ fn coerceExtra( |
| 29099 | 29122 | .@"extern" => |e| e.owner_nav, |
| 29100 | 29123 | else => unreachable, |
| 29101 | 29124 | }; |
| 29102 | const inst_as_ptr = try sema.analyzeNavRef(inst_src, fn_nav); | |
| 29125 | const inst_as_ptr = try sema.analyzeNavRef(block, inst_src, fn_nav); | |
| 29103 | 29126 | return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); |
| 29104 | 29127 | } |
| 29105 | 29128 | |
| ... | ... | @@ -30752,7 +30775,7 @@ fn coerceVarArgParam( |
| 30752 | 30775 | .@"fn" => fn_ptr: { |
| 30753 | 30776 | const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); |
| 30754 | 30777 | const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav; |
| 30755 | break :fn_ptr try sema.analyzeNavRef(inst_src, fn_nav); | |
| 30778 | break :fn_ptr try sema.analyzeNavRef(block, inst_src, fn_nav); | |
| 30756 | 30779 | }, |
| 30757 | 30780 | .array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), |
| 30758 | 30781 | .float => float: { |
| ... | ... | @@ -31762,12 +31785,13 @@ fn analyzeNavVal( |
| 31762 | 31785 | src: LazySrcLoc, |
| 31763 | 31786 | nav_index: InternPool.Nav.Index, |
| 31764 | 31787 | ) CompileError!Air.Inst.Ref { |
| 31765 | const ref = try sema.analyzeNavRefInner(src, nav_index, false); | |
| 31788 | const ref = try sema.analyzeNavRefInner(block, src, nav_index, false); | |
| 31766 | 31789 | return sema.analyzeLoad(block, src, ref, src); |
| 31767 | 31790 | } |
| 31768 | 31791 | |
| 31769 | 31792 | fn addReferenceEntry( |
| 31770 | 31793 | sema: *Sema, |
| 31794 | opt_block: ?*Block, | |
| 31771 | 31795 | src: LazySrcLoc, |
| 31772 | 31796 | referenced_unit: AnalUnit, |
| 31773 | 31797 | ) !void { |
| ... | ... | @@ -31775,10 +31799,12 @@ fn addReferenceEntry( |
| 31775 | 31799 | if (!zcu.comp.incremental and zcu.comp.reference_trace == 0) return; |
| 31776 | 31800 | const gop = try sema.references.getOrPut(sema.gpa, referenced_unit); |
| 31777 | 31801 | if (gop.found_existing) return; |
| 31778 | // TODO: we need to figure out how to model inline calls here. | |
| 31779 | // They aren't references in the analysis sense, but ought to show up in the reference trace! | |
| 31780 | // Would representing inline calls in the reference table cause excessive memory usage? | |
| 31781 | try zcu.addUnitReference(sema.owner, referenced_unit, src); | |
| 31802 | try zcu.addUnitReference(sema.owner, referenced_unit, src, inline_frame: { | |
| 31803 | const block = opt_block orelse break :inline_frame .none; | |
| 31804 | const inlining = block.inlining orelse break :inline_frame .none; | |
| 31805 | const frame = try inlining.refFrame(zcu); | |
| 31806 | break :inline_frame frame.toOptional(); | |
| 31807 | }); | |
| 31782 | 31808 | } |
| 31783 | 31809 | |
| 31784 | 31810 | pub fn addTypeReferenceEntry( |
| ... | ... | @@ -31797,7 +31823,7 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M |
| 31797 | 31823 | const pt = sema.pt; |
| 31798 | 31824 | |
| 31799 | 31825 | const unit: AnalUnit = .wrap(.{ .memoized_state = stage }); |
| 31800 | try sema.addReferenceEntry(src, unit); | |
| 31826 | try sema.addReferenceEntry(null, src, unit); | |
| 31801 | 31827 | try sema.declareDependency(.{ .memoized_state = stage }); |
| 31802 | 31828 | |
| 31803 | 31829 | if (pt.zcu.analysis_in_progress.contains(unit)) { |
| ... | ... | @@ -31806,7 +31832,7 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M |
| 31806 | 31832 | try pt.ensureMemoizedStateUpToDate(stage); |
| 31807 | 31833 | } |
| 31808 | 31834 | |
| 31809 | pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void { | |
| 31835 | pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void { | |
| 31810 | 31836 | const pt = sema.pt; |
| 31811 | 31837 | const zcu = pt.zcu; |
| 31812 | 31838 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -31829,7 +31855,7 @@ pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav |
| 31829 | 31855 | .type => .{ .nav_ty = nav_index }, |
| 31830 | 31856 | .fully => .{ .nav_val = nav_index }, |
| 31831 | 31857 | }); |
| 31832 | try sema.addReferenceEntry(src, anal_unit); | |
| 31858 | try sema.addReferenceEntry(block, src, anal_unit); | |
| 31833 | 31859 | |
| 31834 | 31860 | if (zcu.analysis_in_progress.contains(anal_unit)) { |
| 31835 | 31861 | return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{ |
| ... | ... | @@ -31859,25 +31885,25 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { |
| 31859 | 31885 | } })); |
| 31860 | 31886 | } |
| 31861 | 31887 | |
| 31862 | fn analyzeNavRef(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref { | |
| 31863 | return sema.analyzeNavRefInner(src, nav_index, true); | |
| 31888 | fn analyzeNavRef(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref { | |
| 31889 | return sema.analyzeNavRefInner(block, src, nav_index, true); | |
| 31864 | 31890 | } |
| 31865 | 31891 | |
| 31866 | 31892 | /// Analyze a reference to the `Nav` at the given index. Ensures the underlying `Nav` is analyzed. |
| 31867 | 31893 | /// If this pointer will be used directly, `is_ref` must be `true`. |
| 31868 | 31894 | /// If this pointer will be immediately loaded (i.e. a `decl_val` instruction), `is_ref` must be `false`. |
| 31869 | fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.Nav.Index, is_ref: bool) CompileError!Air.Inst.Ref { | |
| 31895 | fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_index: InternPool.Nav.Index, is_ref: bool) CompileError!Air.Inst.Ref { | |
| 31870 | 31896 | const pt = sema.pt; |
| 31871 | 31897 | const zcu = pt.zcu; |
| 31872 | 31898 | const ip = &zcu.intern_pool; |
| 31873 | 31899 | |
| 31874 | try sema.ensureNavResolved(src, orig_nav_index, if (is_ref) .type else .fully); | |
| 31900 | try sema.ensureNavResolved(block, src, orig_nav_index, if (is_ref) .type else .fully); | |
| 31875 | 31901 | |
| 31876 | 31902 | const nav_index = nav: { |
| 31877 | 31903 | if (ip.getNav(orig_nav_index).isExternOrFn(ip)) { |
| 31878 | 31904 | // Getting a pointer to this `Nav` might mean we actually get a pointer to something else! |
| 31879 | 31905 | // We need to resolve the value to know for sure. |
| 31880 | if (is_ref) try sema.ensureNavResolved(src, orig_nav_index, .fully); | |
| 31906 | if (is_ref) try sema.ensureNavResolved(block, src, orig_nav_index, .fully); | |
| 31881 | 31907 | switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) { |
| 31882 | 31908 | .func => |f| break :nav f.owner_nav, |
| 31883 | 31909 | .@"extern" => |e| break :nav e.owner_nav, |
| ... | ... | @@ -31901,7 +31927,7 @@ fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.N |
| 31901 | 31927 | }, |
| 31902 | 31928 | }); |
| 31903 | 31929 | if (is_ref) { |
| 31904 | try sema.maybeQueueFuncBodyAnalysis(src, nav_index); | |
| 31930 | try sema.maybeQueueFuncBodyAnalysis(block, src, nav_index); | |
| 31905 | 31931 | } |
| 31906 | 31932 | return Air.internedToRef((try pt.intern(.{ .ptr = .{ |
| 31907 | 31933 | .ty = ptr_ty.toIntern(), |
| ... | ... | @@ -31910,7 +31936,7 @@ fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.N |
| 31910 | 31936 | } }))); |
| 31911 | 31937 | } |
| 31912 | 31938 | |
| 31913 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void { | |
| 31939 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void { | |
| 31914 | 31940 | const pt = sema.pt; |
| 31915 | 31941 | const zcu = pt.zcu; |
| 31916 | 31942 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -31918,16 +31944,16 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPoo |
| 31918 | 31944 | // To avoid forcing too much resolution, let's first resolve the type, and check if it's a function. |
| 31919 | 31945 | // If it is, we can resolve the *value*, and queue analysis as needed. |
| 31920 | 31946 | |
| 31921 | try sema.ensureNavResolved(src, nav_index, .type); | |
| 31947 | try sema.ensureNavResolved(block, src, nav_index, .type); | |
| 31922 | 31948 | const nav_ty: Type = .fromInterned(ip.getNav(nav_index).typeOf(ip)); |
| 31923 | 31949 | if (nav_ty.zigTypeTag(zcu) != .@"fn") return; |
| 31924 | 31950 | if (!try nav_ty.fnHasRuntimeBitsSema(pt)) return; |
| 31925 | 31951 | |
| 31926 | try sema.ensureNavResolved(src, nav_index, .fully); | |
| 31952 | try sema.ensureNavResolved(block, src, nav_index, .fully); | |
| 31927 | 31953 | const nav_val = zcu.navValue(nav_index); |
| 31928 | 31954 | if (!ip.isFuncBody(nav_val.toIntern())) return; |
| 31929 | 31955 | |
| 31930 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() })); | |
| 31956 | try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = nav_val.toIntern() })); | |
| 31931 | 31957 | try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern()); |
| 31932 | 31958 | } |
| 31933 | 31959 | |
| ... | ... | @@ -31943,8 +31969,8 @@ fn analyzeRef( |
| 31943 | 31969 | |
| 31944 | 31970 | if (try sema.resolveValue(operand)) |val| { |
| 31945 | 31971 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 31946 | .@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav), | |
| 31947 | .func => |f| return sema.analyzeNavRef(src, f.owner_nav), | |
| 31972 | .@"extern" => |e| return sema.analyzeNavRef(block, src, e.owner_nav), | |
| 31973 | .func => |f| return sema.analyzeNavRef(block, src, f.owner_nav), | |
| 31948 | 31974 | else => return uavRef(sema, val.toIntern()), |
| 31949 | 31975 | } |
| 31950 | 31976 | } |
| ... | ... | @@ -35508,7 +35534,7 @@ fn resolveInferredErrorSet( |
| 35508 | 35534 | } |
| 35509 | 35535 | // In this case we are dealing with the actual InferredErrorSet object that |
| 35510 | 35536 | // corresponds to the function, not one created to track an inline/comptime call. |
| 35511 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index })); | |
| 35537 | try sema.addReferenceEntry(block, src, AnalUnit.wrap(.{ .func = func_index })); | |
| 35512 | 35538 | try pt.ensureFuncBodyUpToDate(func_index); |
| 35513 | 35539 | } |
| 35514 | 35540 |
src/Sema/comptime_ptr_access.zig+1-1| ... | ... | @@ -228,7 +228,7 @@ fn loadComptimePtrInner( |
| 228 | 228 | |
| 229 | 229 | const base_val: MutableValue = switch (ptr.base_addr) { |
| 230 | 230 | .nav => |nav| val: { |
| 231 | try sema.ensureNavResolved(src, nav, .fully); | |
| 231 | try sema.ensureNavResolved(block, src, nav, .fully); | |
| 232 | 232 | const val = ip.getNav(nav).status.fully_resolved.val; |
| 233 | 233 | switch (ip.indexToKey(val)) { |
| 234 | 234 | .variable => return .runtime_load, |
src/Zcu.zig+78-2| ... | ... | @@ -215,6 +215,9 @@ all_references: std.ArrayListUnmanaged(Reference) = .empty, |
| 215 | 215 | /// Freelist of indices in `all_references`. |
| 216 | 216 | free_references: std.ArrayListUnmanaged(u32) = .empty, |
| 217 | 217 | |
| 218 | inline_reference_frames: std.ArrayListUnmanaged(InlineReferenceFrame) = .empty, | |
| 219 | free_inline_reference_frames: std.ArrayListUnmanaged(InlineReferenceFrame.Index) = .empty, | |
| 220 | ||
| 218 | 221 | /// Key is the `AnalUnit` *performing* the reference. This representation allows |
| 219 | 222 | /// incremental updates to quickly delete references caused by a specific `AnalUnit`. |
| 220 | 223 | /// Value is index into `all_type_reference` of the first reference triggered by the unit. |
| ... | ... | @@ -583,6 +586,42 @@ pub const Reference = struct { |
| 583 | 586 | next: u32, |
| 584 | 587 | /// The source location of the reference. |
| 585 | 588 | src: LazySrcLoc, |
| 589 | /// If not `.none`, this is the index of the `InlineReferenceFrame` which should appear | |
| 590 | /// between the referencer and `referenced` in the reference trace. These frames represent | |
| 591 | /// inline calls, which do not create actual references (since they happen in the caller's | |
| 592 | /// `AnalUnit`), but do show in the reference trace. | |
| 593 | inline_frame: InlineReferenceFrame.Index.Optional, | |
| 594 | }; | |
| 595 | ||
| 596 | pub const InlineReferenceFrame = struct { | |
| 597 | /// The inline *callee*; that is, the function which was called inline. | |
| 598 | /// The *caller* is either `parent`, or else the unit causing the original `Reference`. | |
| 599 | callee: InternPool.Index, | |
| 600 | /// The source location of the inline call, in the *caller*. | |
| 601 | call_src: LazySrcLoc, | |
| 602 | /// If not `.none`, a frame which should appear directly below this one. | |
| 603 | /// This will be the "parent" inline call; this frame's `callee` is our caller. | |
| 604 | parent: InlineReferenceFrame.Index.Optional, | |
| 605 | ||
| 606 | pub const Index = enum(u32) { | |
| 607 | _, | |
| 608 | pub fn ptr(idx: Index, zcu: *Zcu) *InlineReferenceFrame { | |
| 609 | return &zcu.inline_reference_frames.items[@intFromEnum(idx)]; | |
| 610 | } | |
| 611 | pub fn toOptional(idx: Index) Optional { | |
| 612 | return @enumFromInt(@intFromEnum(idx)); | |
| 613 | } | |
| 614 | pub const Optional = enum(u32) { | |
| 615 | none = std.math.maxInt(u32), | |
| 616 | _, | |
| 617 | pub fn unwrap(opt: Optional) ?Index { | |
| 618 | return switch (opt) { | |
| 619 | .none => null, | |
| 620 | _ => @enumFromInt(@intFromEnum(opt)), | |
| 621 | }; | |
| 622 | } | |
| 623 | }; | |
| 624 | }; | |
| 586 | 625 | }; |
| 587 | 626 | |
| 588 | 627 | pub const TypeReference = struct { |
| ... | ... | @@ -3440,12 +3479,28 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void { |
| 3440 | 3479 | var idx = kv.value; |
| 3441 | 3480 | |
| 3442 | 3481 | while (idx != std.math.maxInt(u32)) { |
| 3482 | const ref = zcu.all_references.items[idx]; | |
| 3443 | 3483 | zcu.free_references.append(gpa, idx) catch { |
| 3444 | 3484 | // This space will be reused eventually, so we need not propagate this error. |
| 3445 | 3485 | // Just leak it for now, and let GC reclaim it later on. |
| 3446 | 3486 | break :unit_refs; |
| 3447 | 3487 | }; |
| 3448 | idx = zcu.all_references.items[idx].next; | |
| 3488 | idx = ref.next; | |
| 3489 | ||
| 3490 | var opt_inline_frame = ref.inline_frame; | |
| 3491 | while (opt_inline_frame.unwrap()) |inline_frame| { | |
| 3492 | // The same inline frame could be used multiple times by one unit. We need to | |
| 3493 | // detect this case to avoid adding it to `free_inline_reference_frames` more | |
| 3494 | // than once. We do that by setting `parent` to itself as a marker. | |
| 3495 | if (inline_frame.ptr(zcu).parent == inline_frame.toOptional()) break; | |
| 3496 | zcu.free_inline_reference_frames.append(gpa, inline_frame) catch { | |
| 3497 | // This space will be reused eventually, so we need not propagate this error. | |
| 3498 | // Just leak it for now, and let GC reclaim it later on. | |
| 3499 | break :unit_refs; | |
| 3500 | }; | |
| 3501 | opt_inline_frame = inline_frame.ptr(zcu).parent; | |
| 3502 | inline_frame.ptr(zcu).parent = inline_frame.toOptional(); // signal to code above | |
| 3503 | } | |
| 3449 | 3504 | } |
| 3450 | 3505 | } |
| 3451 | 3506 | |
| ... | ... | @@ -3480,7 +3535,22 @@ pub fn deleteUnitCompileLogs(zcu: *Zcu, anal_unit: AnalUnit) void { |
| 3480 | 3535 | } |
| 3481 | 3536 | } |
| 3482 | 3537 | |
| 3483 | pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit, ref_src: LazySrcLoc) Allocator.Error!void { | |
| 3538 | pub fn addInlineReferenceFrame(zcu: *Zcu, frame: InlineReferenceFrame) Allocator.Error!Zcu.InlineReferenceFrame.Index { | |
| 3539 | const frame_idx: InlineReferenceFrame.Index = zcu.free_inline_reference_frames.pop() orelse idx: { | |
| 3540 | _ = try zcu.inline_reference_frames.addOne(zcu.gpa); | |
| 3541 | break :idx @enumFromInt(zcu.inline_reference_frames.items.len - 1); | |
| 3542 | }; | |
| 3543 | frame_idx.ptr(zcu).* = frame; | |
| 3544 | return frame_idx; | |
| 3545 | } | |
| 3546 | ||
| 3547 | pub fn addUnitReference( | |
| 3548 | zcu: *Zcu, | |
| 3549 | src_unit: AnalUnit, | |
| 3550 | referenced_unit: AnalUnit, | |
| 3551 | ref_src: LazySrcLoc, | |
| 3552 | inline_frame: InlineReferenceFrame.Index.Optional, | |
| 3553 | ) Allocator.Error!void { | |
| 3484 | 3554 | const gpa = zcu.gpa; |
| 3485 | 3555 | |
| 3486 | 3556 | zcu.clearCachedResolvedReferences(); |
| ... | ... | @@ -3500,6 +3570,7 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit |
| 3500 | 3570 | .referenced = referenced_unit, |
| 3501 | 3571 | .next = if (gop.found_existing) gop.value_ptr.* else std.math.maxInt(u32), |
| 3502 | 3572 | .src = ref_src, |
| 3573 | .inline_frame = inline_frame, | |
| 3503 | 3574 | }; |
| 3504 | 3575 | |
| 3505 | 3576 | gop.value_ptr.* = @intCast(ref_idx); |
| ... | ... | @@ -3828,7 +3899,10 @@ pub fn unionTagFieldIndex(zcu: *const Zcu, loaded_union: InternPool.LoadedUnionT |
| 3828 | 3899 | |
| 3829 | 3900 | pub const ResolvedReference = struct { |
| 3830 | 3901 | referencer: AnalUnit, |
| 3902 | /// If `inline_frame` is not `.none`, this is the *deepest* source location in the chain of | |
| 3903 | /// inline calls. For source locations further up the inline call stack, consult `inline_frame`. | |
| 3831 | 3904 | src: LazySrcLoc, |
| 3905 | inline_frame: InlineReferenceFrame.Index.Optional, | |
| 3832 | 3906 | }; |
| 3833 | 3907 | |
| 3834 | 3908 | /// Returns a mapping from an `AnalUnit` to where it is referenced. |
| ... | ... | @@ -4037,6 +4111,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4037 | 4111 | try unit_queue.put(gpa, ref.referenced, .{ |
| 4038 | 4112 | .referencer = unit, |
| 4039 | 4113 | .src = ref.src, |
| 4114 | .inline_frame = ref.inline_frame, | |
| 4040 | 4115 | }); |
| 4041 | 4116 | } |
| 4042 | 4117 | ref_idx = ref.next; |
| ... | ... | @@ -4055,6 +4130,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4055 | 4130 | try type_queue.put(gpa, ref.referenced, .{ |
| 4056 | 4131 | .referencer = unit, |
| 4057 | 4132 | .src = ref.src, |
| 4133 | .inline_frame = .none, | |
| 4058 | 4134 | }); |
| 4059 | 4135 | } |
| 4060 | 4136 | ref_idx = ref.next; |
test/cases/compile_errors/add_overflow_in_function_evaluation.zig+1-3| ... | ... | @@ -8,8 +8,6 @@ export fn entry() usize { |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | // error |
| 11 | // backend=stage2 | |
| 12 | // target=native | |
| 13 | 11 | // |
| 14 | 12 | // :3:14: error: overflow of integer type 'u16' with value '65540' |
| 15 | // :1:14: note: called from here | |
| 13 | // :1:14: note: called at comptime here |
test/cases/compile_errors/closure_get_depends_on_failed_decl.zig+1-3| ... | ... | @@ -18,9 +18,7 @@ pub export fn entry() void { |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | // error |
| 21 | // backend=stage2 | |
| 22 | // target=native | |
| 23 | 21 | // |
| 24 | 22 | // :11:5: error: expected 0 argument(s), found 1 |
| 25 | 23 | // :1:12: note: function declared here |
| 26 | // :17:19: note: called from here | |
| 24 | // :17:19: note: called inline here |
test/cases/compile_errors/compile_time_division_by_zero.zig+1-1| ... | ... | @@ -10,4 +10,4 @@ export fn entry() usize { |
| 10 | 10 | // error |
| 11 | 11 | // |
| 12 | 12 | // :3:16: error: division by zero here causes illegal behavior |
| 13 | // :1:14: note: called from here | |
| 13 | // :1:14: note: called at comptime here |
test/cases/compile_errors/comptime_try_non_error.zig+1-3| ... | ... | @@ -11,8 +11,6 @@ pub fn bar() u8 { |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | // error |
| 14 | // backend=stage2 | |
| 15 | // target=native | |
| 16 | 14 | // |
| 17 | 15 | // :6:12: error: expected error union type, found 'u8' |
| 18 | // :2:8: note: called from here | |
| 16 | // :2:8: note: called at comptime here |
test/cases/compile_errors/comptime_var_referenced_by_type.zig+1-1| ... | ... | @@ -22,4 +22,4 @@ comptime { |
| 22 | 22 | // |
| 23 | 23 | // :7:16: error: captured value contains reference to comptime var |
| 24 | 24 | // :16:30: note: 'wrapper.ptr' points to comptime var declared here |
| 25 | // :17:29: note: called from here | |
| 25 | // :17:29: note: called at comptime here |
test/cases/compile_errors/constant_inside_comptime_function_has_compile_error.zig+1-2| ... | ... | @@ -15,9 +15,8 @@ export fn entry() void { |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | // error |
| 18 | // target=native | |
| 19 | 18 | // |
| 20 | 19 | // :4:5: error: unreachable code |
| 21 | 20 | // :4:25: note: control flow is diverted here |
| 22 | 21 | // :4:25: error: aoeu |
| 23 | // :1:36: note: called from here | |
| 22 | // :1:36: note: called at comptime here |
test/cases/compile_errors/error_in_comptime_call_in_container_level_initializer.zig+1-3| ... | ... | @@ -15,8 +15,6 @@ pub export fn entry() void { |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | // error |
| 18 | // backend=stage2 | |
| 19 | // target=native | |
| 20 | 18 | // |
| 21 | 19 | // :9:48: error: caught unexpected error 'InvalidVersion' |
| 22 | 20 | // :?:?: note: error returned here |
| ... | ... | @@ -24,4 +22,4 @@ pub export fn entry() void { |
| 24 | 22 | // :?:?: note: error returned here |
| 25 | 23 | // :?:?: note: error returned here |
| 26 | 24 | // :?:?: note: error returned here |
| 27 | // :12:37: note: called from here | |
| 25 | // :12:37: note: called at comptime here |
test/cases/compile_errors/generic_function_instantiation_inherits_parent_branch_quota.zig+2-2| ... | ... | @@ -25,5 +25,5 @@ fn Type(comptime n: usize) type { |
| 25 | 25 | // |
| 26 | 26 | // :21:16: error: evaluation exceeded 1001 backwards branches |
| 27 | 27 | // :21:16: note: use @setEvalBranchQuota() to raise the branch limit from 1001 |
| 28 | // :16:34: note: called from here | |
| 29 | // :8:15: note: called from here | |
| 28 | // :16:34: note: called at comptime here | |
| 29 | // :8:15: note: generic function instantiated here |
test/cases/compile_errors/generic_instantiation_failure_in_generic_function_return_type.zig+1-3| ... | ... | @@ -36,8 +36,6 @@ pub fn is(comptime id: std.builtin.TypeId) TraitFn { |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | // error |
| 39 | // backend=stage2 | |
| 40 | // target=native | |
| 41 | 39 | // |
| 42 | 40 | // :8:48: error: expected type 'type', found 'bool' |
| 43 | // :5:21: note: called from here | |
| 41 | // :5:21: note: generic function instantiated here |
test/cases/compile_errors/missing_main_fn_in_executable.zig+2-3| ... | ... | @@ -1,9 +1,8 @@ |
| 1 | 1 | // error |
| 2 | // backend=stage2 | |
| 3 | 2 | // target=x86_64-linux |
| 4 | 3 | // output_mode=Exe |
| 5 | 4 | // |
| 6 | 5 | // : error: root source file struct 'tmp' has no member named 'main' |
| 7 | 6 | // : note: struct declared here |
| 8 | // : note: called from here | |
| 9 | // : note: called from here | |
| 7 | // : note: called inline here | |
| 8 | // : note: called inline here |
test/cases/compile_errors/missing_struct_field_in_fn_called_at_comptime.zig+1-3| ... | ... | @@ -10,9 +10,7 @@ comptime { |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | 12 | // error |
| 13 | // backend=stage2 | |
| 14 | // target=native | |
| 15 | 13 | // |
| 16 | 14 | // :5:17: error: missing struct field: b |
| 17 | 15 | // :1:11: note: struct declared here |
| 18 | // :9:15: note: called from here | |
| 16 | // :9:15: note: called at comptime here |
test/cases/compile_errors/mul_overflow_in_function_evaluation.zig+1-3| ... | ... | @@ -8,8 +8,6 @@ export fn entry() usize { |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | // error |
| 11 | // backend=stage2 | |
| 12 | // target=native | |
| 13 | 11 | // |
| 14 | 12 | // :3:14: error: overflow of integer type 'u16' with value '1800000' |
| 15 | // :1:14: note: called from here | |
| 13 | // :1:14: note: called at comptime here |
test/cases/compile_errors/negation_overflow_in_function_evaluation.zig+1-3| ... | ... | @@ -8,8 +8,6 @@ export fn entry() usize { |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | // error |
| 11 | // backend=stage2 | |
| 12 | // target=native | |
| 13 | 11 | // |
| 14 | 12 | // :3:12: error: overflow of integer type 'i8' with value '128' |
| 15 | // :1:14: note: called from here | |
| 13 | // :1:14: note: called at comptime here |
test/cases/compile_errors/non-comptime-parameter-used-as-array-size.zig+1-1| ... | ... | @@ -11,4 +11,4 @@ fn makeLlamas(count: usize) [count]u8 {} |
| 11 | 11 | // |
| 12 | 12 | // :8:30: error: unable to resolve comptime value |
| 13 | 13 | // :8:30: note: array length must be comptime-known |
| 14 | // :2:31: note: called from here | |
| 14 | // :2:31: note: generic function instantiated here |
test/cases/compile_errors/private_main_fn.zig+2-3| ... | ... | @@ -1,11 +1,10 @@ |
| 1 | 1 | fn main() void {} |
| 2 | 2 | |
| 3 | 3 | // error |
| 4 | // backend=stage2 | |
| 5 | 4 | // target=x86_64-linux |
| 6 | 5 | // output_mode=Exe |
| 7 | 6 | // |
| 8 | 7 | // : error: 'main' is not marked 'pub' |
| 9 | 8 | // :1:1: note: declared here |
| 10 | // : note: called from here | |
| 11 | // : note: called from here | |
| 9 | // : note: called inline here | |
| 10 | // : note: called inline here |
test/cases/compile_errors/recursive_inline_fn.zig+4-4| ... | ... | @@ -31,8 +31,8 @@ pub export fn entry2() void { |
| 31 | 31 | // error |
| 32 | 32 | // |
| 33 | 33 | // :5:27: error: inline call is recursive |
| 34 | // :12:12: note: called from here | |
| 34 | // :12:12: note: called inline here | |
| 35 | 35 | // :24:10: error: inline call is recursive |
| 36 | // :20:10: note: called from here | |
| 37 | // :16:11: note: called from here | |
| 38 | // :28:10: note: called from here | |
| 36 | // :20:10: note: called inline here | |
| 37 | // :16:11: note: called inline here | |
| 38 | // :28:10: note: called inline here |
test/cases/compile_errors/referring_to_a_struct_that_is_invalid.zig+1-3| ... | ... | @@ -11,8 +11,6 @@ fn assert(ok: bool) void { |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | // error |
| 14 | // backend=stage2 | |
| 15 | // target=native | |
| 16 | 14 | // |
| 17 | 15 | // :10:14: error: reached unreachable code |
| 18 | // :6:20: note: called from here | |
| 16 | // :6:20: note: called at comptime here |
test/cases/compile_errors/ret_coercion_error_in_generic_fn_called_from_non_fn_scope.zig+1-3| ... | ... | @@ -6,9 +6,7 @@ comptime { |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | // error |
| 9 | // backend=stage2 | |
| 10 | // target=native | |
| 11 | 9 | // |
| 12 | 10 | // :2:12: error: expected type 'fn () void', found 'type' |
| 13 | 11 | // :1:10: note: function return type declared here |
| 14 | // :5:12: note: called from here | |
| 12 | // :5:12: note: called at comptime here |
test/cases/compile_errors/runtime_operation_in_comptime_scope.zig+1-1| ... | ... | @@ -30,7 +30,7 @@ var rt: u32 = undefined; |
| 30 | 30 | // :10:12: note: call to function with comptime-only return type 'type' is evaluated at comptime |
| 31 | 31 | // :13:10: note: return type declared here |
| 32 | 32 | // :10:12: note: types are not available at runtime |
| 33 | // :2:8: note: called from here | |
| 33 | // :2:8: note: called inline here | |
| 34 | 34 | // :19:8: error: unable to evaluate comptime expression |
| 35 | 35 | // :19:5: note: operation is runtime due to this operand |
| 36 | 36 | // :6:8: note: called at comptime from here |
test/cases/compile_errors/sema_src_used_after_inline_call.zig+1-3| ... | ... | @@ -18,9 +18,7 @@ export fn entry() void { |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | // error |
| 21 | // backend=stage2 | |
| 22 | // target=native | |
| 23 | 21 | // |
| 24 | 22 | // :13:30: error: expected type 'u32', found 'i32' |
| 25 | 23 | // :13:30: note: unsigned 32-bit int cannot represent all possible signed 32-bit values |
| 26 | // :17:33: note: called from here | |
| 24 | // :17:33: note: called inline here |
test/cases/compile_errors/stack_usage_in_naked_function.zig+1-2| ... | ... | @@ -36,10 +36,9 @@ export fn d() callconv(.naked) noreturn { |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | // error |
| 39 | // backend=stage2 | |
| 40 | 39 | // |
| 41 | 40 | // :2:5: error: local variable in naked function |
| 42 | 41 | // :10:5: error: local variable in naked function |
| 43 | 42 | // :23:5: error: local variable in naked function |
| 44 | 43 | // :30:13: error: local variable in naked function |
| 45 | // :35:12: note: called from here | |
| 44 | // :35:12: note: called inline here |
test/cases/compile_errors/store_to_comptime_var_through_call.zig+1-1| ... | ... | @@ -12,4 +12,4 @@ fn incr(x: *comptime_int) void { |
| 12 | 12 | // |
| 13 | 13 | // :8:9: error: store to comptime variable depends on runtime condition |
| 14 | 14 | // :3:9: note: runtime condition here |
| 15 | // :4:22: note: called from here | |
| 15 | // :4:22: note: called at comptime here |
test/cases/compile_errors/sub_overflow_in_function_evaluation.zig+1-3| ... | ... | @@ -8,8 +8,6 @@ export fn entry() usize { |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | // error |
| 11 | // backend=stage2 | |
| 12 | // target=native | |
| 13 | 11 | // |
| 14 | 12 | // :3:14: error: overflow of integer type 'u16' with value '-10' |
| 15 | // :1:14: note: called from here | |
| 13 | // :1:14: note: called at comptime here |
test/cases/compile_errors/unreachable_executed_at_comptime.zig+1-3| ... | ... | @@ -9,8 +9,6 @@ export fn entry() void { |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | 11 | // error |
| 12 | // backend=stage2 | |
| 13 | // target=native | |
| 14 | 12 | // |
| 15 | 13 | // :4:9: error: reached unreachable code |
| 16 | // :8:21: note: called from here | |
| 14 | // :8:21: note: called at comptime here |