| ... | ... | @@ -538,7 +538,7 @@ pub fn ensureCauAnalyzed(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) Zcu |
| 538 | 538 | const anal_unit = AnalUnit.wrap(.{ .cau = cau_index }); |
| 539 | 539 | const cau = ip.getCau(cau_index); |
| 540 | 540 | |
| 541 | | log.debug("ensureCauAnalyzed {d}", .{@intFromEnum(cau_index)}); |
| 541 | log.debug("ensureCauAnalyzed {}", .{zcu.fmtAnalUnit(anal_unit)}); |
| 542 | 542 | |
| 543 | 543 | assert(!zcu.analysis_in_progress.contains(anal_unit)); |
| 544 | 544 | |
| ... | ... | @@ -576,13 +576,19 @@ pub fn ensureCauAnalyzed(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) Zcu |
| 576 | 576 | } |
| 577 | 577 | |
| 578 | 578 | const sema_result: SemaCauResult, const analysis_fail = if (pt.ensureCauAnalyzedInner(cau_index, cau_outdated)) |result| |
| 579 | | .{ result, false } |
| 579 | // This `Cau` has gone from failed to success, so even if the value of the owner `Nav` didn't actually |
| 580 | // change, we need to invalidate the dependencies anyway. |
| 581 | .{ .{ |
| 582 | .invalidate_decl_val = result.invalidate_decl_val or prev_failed, |
| 583 | .invalidate_decl_ref = result.invalidate_decl_ref or prev_failed, |
| 584 | }, false } |
| 580 | 585 | else |err| switch (err) { |
| 581 | 586 | error.AnalysisFail => res: { |
| 582 | 587 | if (!zcu.failed_analysis.contains(anal_unit)) { |
| 583 | 588 | // If this `Cau` caused the error, it would have an entry in `failed_analysis`. |
| 584 | 589 | // Since it does not, this must be a transitive failure. |
| 585 | 590 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); |
| 591 | log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)}); |
| 586 | 592 | } |
| 587 | 593 | // We consider this `Cau` to be outdated if: |
| 588 | 594 | // * Previous analysis succeeded; in this case, we need to re-analyze dependants to ensure |
| ... | ... | @@ -707,12 +713,12 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter |
| 707 | 713 | |
| 708 | 714 | // We only care about the uncoerced function. |
| 709 | 715 | const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index); |
| 716 | const anal_unit = AnalUnit.wrap(.{ .func = func_index }); |
| 710 | 717 | |
| 711 | | const func = zcu.funcInfo(maybe_coerced_func_index); |
| 718 | log.debug("ensureFuncBodyAnalyzed {}", .{zcu.fmtAnalUnit(anal_unit)}); |
| 712 | 719 | |
| 713 | | log.debug("ensureFuncBodyAnalyzed {d}", .{@intFromEnum(func_index)}); |
| 720 | const func = zcu.funcInfo(maybe_coerced_func_index); |
| 714 | 721 | |
| 715 | | const anal_unit = AnalUnit.wrap(.{ .func = func_index }); |
| 716 | 722 | const func_outdated = zcu.outdated.swapRemove(anal_unit) or |
| 717 | 723 | zcu.potentially_outdated.swapRemove(anal_unit); |
| 718 | 724 | |
| ... | ... | @@ -740,6 +746,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter |
| 740 | 746 | // If this function caused the error, it would have an entry in `failed_analysis`. |
| 741 | 747 | // Since it does not, this must be a transitive failure. |
| 742 | 748 | try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); |
| 749 | log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)}); |
| 743 | 750 | } |
| 744 | 751 | // We consider the IES to be outdated if the function previously succeeded analysis; in this case, |
| 745 | 752 | // we need to re-analyze dependants to ensure they hit a transitive error here, rather than reporting |
| ... | ... | @@ -751,10 +758,8 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter |
| 751 | 758 | |
| 752 | 759 | if (func_outdated) { |
| 753 | 760 | if (ies_outdated) { |
| 754 | | log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)}); |
| 755 | 761 | try zcu.markDependeeOutdated(.marked_po, .{ .interned = func_index }); |
| 756 | 762 | } else { |
| 757 | | log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)}); |
| 758 | 763 | try zcu.markPoDependeeUpToDate(.{ .interned = func_index }); |
| 759 | 764 | } |
| 760 | 765 | } |
| ... | ... | @@ -779,6 +784,7 @@ fn ensureFuncBodyAnalyzedInner( |
| 779 | 784 | // results in the worst case. |
| 780 | 785 | |
| 781 | 786 | if (func.generic_owner == .none) { |
| 787 | // Among another things, this ensures that the function's `zir_body_inst` is correct. |
| 782 | 788 | try pt.ensureCauAnalyzed(ip.getNav(func.owner_nav).analysis_owner.unwrap().?); |
| 783 | 789 | if (ip.getNav(func.owner_nav).status.resolved.val != func_index) { |
| 784 | 790 | // This function is no longer referenced! There's no point in re-analyzing it. |
| ... | ... | @@ -787,6 +793,7 @@ fn ensureFuncBodyAnalyzedInner( |
| 787 | 793 | } |
| 788 | 794 | } else { |
| 789 | 795 | const go_nav = zcu.funcInfo(func.generic_owner).owner_nav; |
| 796 | // Among another things, this ensures that the function's `zir_body_inst` is correct. |
| 790 | 797 | try pt.ensureCauAnalyzed(ip.getNav(go_nav).analysis_owner.unwrap().?); |
| 791 | 798 | if (ip.getNav(go_nav).status.resolved.val != func.generic_owner) { |
| 792 | 799 | // The generic owner is no longer referenced, so this function is also unreferenced. |
| ... | ... | @@ -824,8 +831,8 @@ fn ensureFuncBodyAnalyzedInner( |
| 824 | 831 | } |
| 825 | 832 | } |
| 826 | 833 | |
| 827 | | log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{ |
| 828 | | @intFromEnum(func_index), |
| 834 | log.debug("analyze and generate fn body {}; reason='{s}'", .{ |
| 835 | zcu.fmtAnalUnit(anal_unit), |
| 829 | 836 | if (func_outdated) "outdated" else "never analyzed", |
| 830 | 837 | }); |
| 831 | 838 | |
| ... | ... | @@ -1164,7 +1171,7 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { |
| 1164 | 1171 | .none, .type => false, |
| 1165 | 1172 | }; |
| 1166 | 1173 | |
| 1167 | | log.debug("semaCau '{d}'", .{@intFromEnum(cau_index)}); |
| 1174 | log.debug("semaCau {}", .{zcu.fmtAnalUnit(anal_unit)}); |
| 1168 | 1175 | |
| 1169 | 1176 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); |
| 1170 | 1177 | errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); |
| ... | ... | @@ -2307,16 +2314,14 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err |
| 2307 | 2314 | return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name)); |
| 2308 | 2315 | } |
| 2309 | 2316 | |
| 2317 | /// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed. |
| 2318 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. |
| 2310 | 2319 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { |
| 2311 | | switch (file.status) { |
| 2312 | | .success_zir, .retryable_failure => {}, |
| 2313 | | .never_loaded, .parse_failure, .astgen_failure => { |
| 2314 | | pt.zcu.comp.mutex.lock(); |
| 2315 | | defer pt.zcu.comp.mutex.unlock(); |
| 2316 | | if (pt.zcu.failed_files.fetchSwapRemove(file)) |kv| { |
| 2317 | | if (kv.value) |msg| msg.destroy(pt.zcu.gpa); // Delete previous error message. |
| 2318 | | } |
| 2319 | | }, |
| 2320 | if (!file.zir_loaded or !file.zir.hasCompileErrors()) return; |
| 2321 | pt.zcu.comp.mutex.lock(); |
| 2322 | defer pt.zcu.comp.mutex.unlock(); |
| 2323 | if (pt.zcu.failed_files.fetchSwapRemove(file)) |kv| { |
| 2324 | if (kv.value) |msg| msg.destroy(pt.zcu.gpa); // Delete previous error message. |
| 2320 | 2325 | } |
| 2321 | 2326 | } |
| 2322 | 2327 | |