| ... | @@ -109,7 +109,7 @@ pub fn astGenFile( | ... | @@ -109,7 +109,7 @@ pub fn astGenFile( |
| 109 | | 109 | |
| 110 | break :lock .shared; | 110 | break :lock .shared; |
| 111 | }, | 111 | }, |
| 112 | .astgen_failure, .success_zir => lock: { | 112 | .astgen_failure, .success => lock: { |
| 113 | const unchanged_metadata = | 113 | const unchanged_metadata = |
| 114 | stat.size == file.stat.size and | 114 | stat.size == file.stat.size and |
| 115 | stat.mtime == file.stat.mtime and | 115 | stat.mtime == file.stat.mtime and |
| ... | @@ -214,8 +214,7 @@ pub fn astGenFile( | ... | @@ -214,8 +214,7 @@ pub fn astGenFile( |
| 214 | .inode = header.stat_inode, | 214 | .inode = header.stat_inode, |
| 215 | .mtime = header.stat_mtime, | 215 | .mtime = header.stat_mtime, |
| 216 | }; | 216 | }; |
| 217 | file.prev_status = file.status; | 217 | file.status = .success; |
| 218 | file.status = .success_zir; | | |
| 219 | log.debug("AstGen cached success: {s}", .{file.sub_file_path}); | 218 | log.debug("AstGen cached success: {s}", .{file.sub_file_path}); |
| 220 | | 219 | |
| 221 | if (file.zir.?.hasCompileErrors()) { | 220 | if (file.zir.?.hasCompileErrors()) { |
| ... | @@ -248,19 +247,11 @@ pub fn astGenFile( | ... | @@ -248,19 +247,11 @@ pub fn astGenFile( |
| 248 | | 247 | |
| 249 | pt.lockAndClearFileCompileError(file); | 248 | pt.lockAndClearFileCompileError(file); |
| 250 | | 249 | |
| 251 | // Previous ZIR is kept for two reasons: | 250 | // If `zir` is not null, and `prev_zir` is null, then `TrackedInst`s are associated with `zir`. |
| 252 | // | 251 | // We need to keep it around! |
| 253 | // 1. In case an update to the file causes a Parse or AstGen failure, we | 252 | // As an optimization, also check `loweringFailed`; if true, but `prev_zir == null`, then this |
| 254 | // need to compare two successful ZIR files in order to proceed with an | 253 | // file has never passed AstGen, so we actually need not cache the old ZIR. |
| 255 | // incremental update. This avoids needlessly tossing out semantic | 254 | if (file.zir != null and file.prev_zir == null and !file.zir.?.loweringFailed()) { |
| 256 | // analysis work when an error is temporarily introduced. | | |
| 257 | // | | |
| 258 | // 2. In order to detect updates, we need to iterate over the intern pool | | |
| 259 | // values while comparing old ZIR to new ZIR. This is better done in a | | |
| 260 | // single-threaded context, so we need to keep both versions around | | |
| 261 | // until that point in the pipeline. Previous ZIR data is freed after | | |
| 262 | // that. | | |
| 263 | if (file.zir != null and !file.zir.?.loweringFailed()) { | | |
| 264 | assert(file.prev_zir == null); | 255 | assert(file.prev_zir == null); |
| 265 | const prev_zir_ptr = try gpa.create(Zir); | 256 | const prev_zir_ptr = try gpa.create(Zir); |
| 266 | file.prev_zir = prev_zir_ptr; | 257 | file.prev_zir = prev_zir_ptr; |
| ... | @@ -289,8 +280,7 @@ pub fn astGenFile( | ... | @@ -289,8 +280,7 @@ pub fn astGenFile( |
| 289 | | 280 | |
| 290 | // Any potential AST errors are converted to ZIR errors here. | 281 | // Any potential AST errors are converted to ZIR errors here. |
| 291 | file.zir = try AstGen.generate(gpa, file.tree.?); | 282 | file.zir = try AstGen.generate(gpa, file.tree.?); |
| 292 | file.prev_status = file.status; | 283 | file.status = .success; |
| 293 | file.status = .success_zir; | | |
| 294 | log.debug("AstGen fresh success: {s}", .{file.sub_file_path}); | 284 | log.debug("AstGen fresh success: {s}", .{file.sub_file_path}); |
| 295 | | 285 | |
| 296 | const safety_buffer = if (Zcu.data_has_safety_tag) | 286 | const safety_buffer = if (Zcu.data_has_safety_tag) |
| ... | @@ -383,9 +373,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -383,9 +373,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 383 | defer cleanupUpdatedFiles(gpa, &updated_files); | 373 | defer cleanupUpdatedFiles(gpa, &updated_files); |
| 384 | for (zcu.import_table.values()) |file_index| { | 374 | for (zcu.import_table.values()) |file_index| { |
| 385 | const file = zcu.fileByIndex(file_index); | 375 | const file = zcu.fileByIndex(file_index); |
| 386 | if (file.prev_status != file.status and file.prev_status != .never_loaded) { | 376 | assert(file.status == .success); |
| 387 | try zcu.markDependeeOutdated(.not_marked_po, .{ .file = file_index }); | | |
| 388 | } | | |
| 389 | const old_zir = file.prev_zir orelse continue; | 377 | const old_zir = file.prev_zir orelse continue; |
| 390 | const new_zir = file.zir.?; | 378 | const new_zir = file.zir.?; |
| 391 | const gop = try updated_files.getOrPut(gpa, file_index); | 379 | const gop = try updated_files.getOrPut(gpa, file_index); |
| ... | @@ -394,9 +382,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -394,9 +382,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 394 | .file = file, | 382 | .file = file, |
| 395 | .inst_map = .{}, | 383 | .inst_map = .{}, |
| 396 | }; | 384 | }; |
| 397 | if (!new_zir.loweringFailed()) { | 385 | try Zcu.mapOldZirToNew(gpa, old_zir.*, new_zir, &gop.value_ptr.inst_map); |
| 398 | try Zcu.mapOldZirToNew(gpa, old_zir.*, new_zir, &gop.value_ptr.inst_map); | | |
| 399 | } | | |
| 400 | } | 386 | } |
| 401 | | 387 | |
| 402 | if (updated_files.count() == 0) | 388 | if (updated_files.count() == 0) |
| ... | @@ -416,13 +402,9 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -416,13 +402,9 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 416 | .index = @intCast(tracked_inst_unwrapped_index), | 402 | .index = @intCast(tracked_inst_unwrapped_index), |
| 417 | }).wrap(ip); | 403 | }).wrap(ip); |
| 418 | const new_inst = updated_file.inst_map.get(old_inst) orelse { | 404 | const new_inst = updated_file.inst_map.get(old_inst) orelse { |
| 419 | // Tracking failed for this instruction. | 405 | // Tracking failed for this instruction due to changes in the ZIR. |
| 420 | // This may be due to changes in the ZIR, or AstGen might have failed due to a very broken file. | 406 | // Invalidate associated `src_hash` deps. |
| 421 | // Either way, invalidate associated `src_hash` deps. | 407 | log.debug("tracking failed for %{d}", .{old_inst}); |
| 422 | log.debug("tracking failed for %{d}{s}", .{ | | |
| 423 | old_inst, | | |
| 424 | if (file.zir.?.loweringFailed()) " due to AstGen failure" else "", | | |
| 425 | }); | | |
| 426 | tracked_inst.inst = .lost; | 408 | tracked_inst.inst = .lost; |
| 427 | try zcu.markDependeeOutdated(.not_marked_po, .{ .src_hash = tracked_inst_index }); | 409 | try zcu.markDependeeOutdated(.not_marked_po, .{ .src_hash = tracked_inst_index }); |
| 428 | continue; | 410 | continue; |
| ... | @@ -527,23 +509,19 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -527,23 +509,19 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 527 | | 509 | |
| 528 | for (updated_files.keys(), updated_files.values()) |file_index, updated_file| { | 510 | for (updated_files.keys(), updated_files.values()) |file_index, updated_file| { |
| 529 | const file = updated_file.file; | 511 | const file = updated_file.file; |
| 530 | if (file.zir.?.loweringFailed()) { | 512 | |
| 531 | // Keep `prev_zir` around: it's the last usable ZIR. | 513 | const prev_zir = file.prev_zir.?; |
| 532 | // Don't update the namespace, as we have no new data to update *to*. | 514 | file.prev_zir = null; |
| 533 | } else { | 515 | prev_zir.deinit(gpa); |
| 534 | const prev_zir = file.prev_zir.?; | 516 | gpa.destroy(prev_zir); |
| 535 | file.prev_zir = null; | 517 | |
| 536 | prev_zir.deinit(gpa); | 518 | // For every file which has changed, re-scan the namespace of the file's root struct type. |
| 537 | gpa.destroy(prev_zir); | 519 | // These types are special-cased because they don't have an enclosing declaration which will |
| 538 | | 520 | // be re-analyzed (causing the struct's namespace to be re-scanned). It's fine to do this |
| 539 | // For every file which has changed, re-scan the namespace of the file's root struct type. | 521 | // now because this work is fast (no actual Sema work is happening, we're just updating the |
| 540 | // These types are special-cased because they don't have an enclosing declaration which will | 522 | // namespace contents). We must do this after updating ZIR refs above, since `scanNamespace` |
| 541 | // be re-analyzed (causing the struct's namespace to be re-scanned). It's fine to do this | 523 | // will track some instructions. |
| 542 | // now because this work is fast (no actual Sema work is happening, we're just updating the | 524 | try pt.updateFileNamespace(file_index); |
| 543 | // namespace contents). We must do this after updating ZIR refs above, since `scanNamespace` | | |
| 544 | // will track some instructions. | | |
| 545 | try pt.updateFileNamespace(file_index); | | |
| 546 | } | | |
| 547 | } | 525 | } |
| 548 | } | 526 | } |
| 549 | | 527 | |
| ... | @@ -745,6 +723,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU | ... | @@ -745,6 +723,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU |
| 745 | kv.value.destroy(gpa); | 723 | kv.value.destroy(gpa); |
| 746 | } | 724 | } |
| 747 | _ = zcu.transitive_failed_analysis.swapRemove(anal_unit); | 725 | _ = zcu.transitive_failed_analysis.swapRemove(anal_unit); |
| | 726 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); |
| 748 | } | 727 | } |
| 749 | } else { | 728 | } else { |
| 750 | // We can trust the current information about this unit. | 729 | // We can trust the current information about this unit. |
| ... | @@ -796,15 +775,8 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu | ... | @@ -796,15 +775,8 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu |
| 796 | | 775 | |
| 797 | const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 776 | const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse return error.AnalysisFail; |
| 798 | const file = zcu.fileByIndex(inst_resolved.file); | 777 | const file = zcu.fileByIndex(inst_resolved.file); |
| 799 | // TODO: stop the compiler ever reaching Sema if there are failed files. That way, this check is | | |
| 800 | // unnecessary, and we can move the below `removeDependenciesForDepender` call up with its friends | | |
| 801 | // in `ensureComptimeUnitUpToDate`. | | |
| 802 | if (file.status != .success_zir) return error.AnalysisFail; | | |
| 803 | const zir = file.zir.?; | 778 | const zir = file.zir.?; |
| 804 | | 779 | |
| 805 | // We are about to re-analyze this unit; drop its depenndencies. | | |
| 806 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); | | |
| 807 | | | |
| 808 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); | 780 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); |
| 809 | defer assert(zcu.analysis_in_progress.swapRemove(anal_unit)); | 781 | defer assert(zcu.analysis_in_progress.swapRemove(anal_unit)); |
| 810 | | 782 | |
| ... | @@ -923,6 +895,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu | ... | @@ -923,6 +895,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu |
| 923 | kv.value.destroy(gpa); | 895 | kv.value.destroy(gpa); |
| 924 | } | 896 | } |
| 925 | _ = zcu.transitive_failed_analysis.swapRemove(anal_unit); | 897 | _ = zcu.transitive_failed_analysis.swapRemove(anal_unit); |
| | 898 | ip.removeDependenciesForDepender(gpa, anal_unit); |
| 926 | } else { | 899 | } else { |
| 927 | // We can trust the current information about this unit. | 900 | // We can trust the current information about this unit. |
| 928 | if (prev_failed) return error.AnalysisFail; | 901 | if (prev_failed) return error.AnalysisFail; |
| ... | @@ -993,15 +966,8 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr | ... | @@ -993,15 +966,8 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 993 | | 966 | |
| 994 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 967 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; |
| 995 | const file = zcu.fileByIndex(inst_resolved.file); | 968 | const file = zcu.fileByIndex(inst_resolved.file); |
| 996 | // TODO: stop the compiler ever reaching Sema if there are failed files. That way, this check is | | |
| 997 | // unnecessary, and we can move the below `removeDependenciesForDepender` call up with its friends | | |
| 998 | // in `ensureComptimeUnitUpToDate`. | | |
| 999 | if (file.status != .success_zir) return error.AnalysisFail; | | |
| 1000 | const zir = file.zir.?; | 969 | const zir = file.zir.?; |
| 1001 | | 970 | |
| 1002 | // We are about to re-analyze this unit; drop its depenndencies. | | |
| 1003 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); | | |
| 1004 | | | |
| 1005 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); | 971 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); |
| 1006 | errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); | 972 | errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); |
| 1007 | | 973 | |
| ... | @@ -1301,6 +1267,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc | ... | @@ -1301,6 +1267,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc |
| 1301 | kv.value.destroy(gpa); | 1267 | kv.value.destroy(gpa); |
| 1302 | } | 1268 | } |
| 1303 | _ = zcu.transitive_failed_analysis.swapRemove(anal_unit); | 1269 | _ = zcu.transitive_failed_analysis.swapRemove(anal_unit); |
| | 1270 | ip.removeDependenciesForDepender(gpa, anal_unit); |
| 1304 | } else { | 1271 | } else { |
| 1305 | // We can trust the current information about this unit. | 1272 | // We can trust the current information about this unit. |
| 1306 | if (prev_failed) return error.AnalysisFail; | 1273 | if (prev_failed) return error.AnalysisFail; |
| ... | @@ -1371,15 +1338,8 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr | ... | @@ -1371,15 +1338,8 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr |
| 1371 | | 1338 | |
| 1372 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 1339 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; |
| 1373 | const file = zcu.fileByIndex(inst_resolved.file); | 1340 | const file = zcu.fileByIndex(inst_resolved.file); |
| 1374 | // TODO: stop the compiler ever reaching Sema if there are failed files. That way, this check is | | |
| 1375 | // unnecessary, and we can move the below `removeDependenciesForDepender` call up with its friends | | |
| 1376 | // in `ensureComptimeUnitUpToDate`. | | |
| 1377 | if (file.status != .success_zir) return error.AnalysisFail; | | |
| 1378 | const zir = file.zir.?; | 1341 | const zir = file.zir.?; |
| 1379 | | 1342 | |
| 1380 | // We are about to re-analyze this unit; drop its depenndencies. | | |
| 1381 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); | | |
| 1382 | | | |
| 1383 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); | 1343 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); |
| 1384 | defer _ = zcu.analysis_in_progress.swapRemove(anal_unit); | 1344 | defer _ = zcu.analysis_in_progress.swapRemove(anal_unit); |
| 1385 | | 1345 | |
| ... | @@ -1828,7 +1788,6 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. | ... | @@ -1828,7 +1788,6 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. |
| 1828 | const zcu = pt.zcu; | 1788 | const zcu = pt.zcu; |
| 1829 | | 1789 | |
| 1830 | const file = zcu.fileByIndex(file_index); | 1790 | const file = zcu.fileByIndex(file_index); |
| 1831 | assert(file.status == .success_zir); | | |
| 1832 | const file_root_type = zcu.fileRootType(file_index); | 1791 | const file_root_type = zcu.fileRootType(file_index); |
| 1833 | if (file_root_type == .none) return; | 1792 | if (file_root_type == .none) return; |
| 1834 | | 1793 | |
| ... | @@ -1865,9 +1824,6 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -1865,9 +1824,6 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1865 | assert(file.getMode() == .zig); | 1824 | assert(file.getMode() == .zig); |
| 1866 | assert(zcu.fileRootType(file_index) == .none); | 1825 | assert(zcu.fileRootType(file_index) == .none); |
| 1867 | | 1826 | |
| 1868 | if (file.status != .success_zir) { | | |
| 1869 | return error.AnalysisFail; | | |
| 1870 | } | | |
| 1871 | assert(file.zir != null); | 1827 | assert(file.zir != null); |
| 1872 | | 1828 | |
| 1873 | const new_namespace_index = try pt.createNamespace(.{ | 1829 | const new_namespace_index = try pt.createNamespace(.{ |
| ... | @@ -1910,7 +1866,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -1910,7 +1866,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1910 | } | 1866 | } |
| 1911 | } | 1867 | } |
| 1912 | | 1868 | |
| 1913 | pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { | 1869 | pub fn importPkg(pt: Zcu.PerThread, mod: *Module) Allocator.Error!Zcu.ImportFileResult { |
| 1914 | const zcu = pt.zcu; | 1870 | const zcu = pt.zcu; |
| 1915 | const gpa = zcu.gpa; | 1871 | const gpa = zcu.gpa; |
| 1916 | | 1872 | |
| ... | @@ -1984,7 +1940,6 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { | ... | @@ -1984,7 +1940,6 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { |
| 1984 | .zir = null, | 1940 | .zir = null, |
| 1985 | .zoir = null, | 1941 | .zoir = null, |
| 1986 | .status = .never_loaded, | 1942 | .status = .never_loaded, |
| 1987 | .prev_status = .never_loaded, | | |
| 1988 | .mod = mod, | 1943 | .mod = mod, |
| 1989 | }; | 1944 | }; |
| 1990 | | 1945 | |
| ... | @@ -1997,13 +1952,19 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { | ... | @@ -1997,13 +1952,19 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { |
| 1997 | }; | 1952 | }; |
| 1998 | } | 1953 | } |
| 1999 | | 1954 | |
| 2000 | /// Called from a worker thread during AstGen. | 1955 | /// Called from a worker thread during AstGen (with the Compilation mutex held). |
| 2001 | /// Also called from Sema during semantic analysis. | 1956 | /// Also called from Sema during semantic analysis. |
| | 1957 | /// Does not attempt to load the file from disk; just returns a corresponding `*Zcu.File`. |
| 2002 | pub fn importFile( | 1958 | pub fn importFile( |
| 2003 | pt: Zcu.PerThread, | 1959 | pt: Zcu.PerThread, |
| 2004 | cur_file: *Zcu.File, | 1960 | cur_file: *Zcu.File, |
| 2005 | import_string: []const u8, | 1961 | import_string: []const u8, |
| 2006 | ) !Zcu.ImportFileResult { | 1962 | ) error{ |
| | 1963 | OutOfMemory, |
| | 1964 | ModuleNotFound, |
| | 1965 | ImportOutsideModulePath, |
| | 1966 | CurrentWorkingDirectoryUnlinked, |
| | 1967 | }!Zcu.ImportFileResult { |
| 2007 | const zcu = pt.zcu; | 1968 | const zcu = pt.zcu; |
| 2008 | const mod = cur_file.mod; | 1969 | const mod = cur_file.mod; |
| 2009 | | 1970 | |
| ... | @@ -2061,7 +2022,10 @@ pub fn importFile( | ... | @@ -2061,7 +2022,10 @@ pub fn importFile( |
| 2061 | defer gpa.free(resolved_root_path); | 2022 | defer gpa.free(resolved_root_path); |
| 2062 | | 2023 | |
| 2063 | const sub_file_path = p: { | 2024 | const sub_file_path = p: { |
| 2064 | const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path); | 2025 | const relative = std.fs.path.relative(gpa, resolved_root_path, resolved_path) catch |err| switch (err) { |
| | 2026 | error.Unexpected => unreachable, |
| | 2027 | else => |e| return e, |
| | 2028 | }; |
| 2065 | errdefer gpa.free(relative); | 2029 | errdefer gpa.free(relative); |
| 2066 | | 2030 | |
| 2067 | if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) { | 2031 | if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) { |
| ... | @@ -2089,13 +2053,15 @@ pub fn importFile( | ... | @@ -2089,13 +2053,15 @@ pub fn importFile( |
| 2089 | gop.value_ptr.* = new_file_index; | 2053 | gop.value_ptr.* = new_file_index; |
| 2090 | new_file.* = .{ | 2054 | new_file.* = .{ |
| 2091 | .sub_file_path = sub_file_path, | 2055 | .sub_file_path = sub_file_path, |
| | 2056 | |
| | 2057 | .status = .never_loaded, |
| 2092 | .stat = undefined, | 2058 | .stat = undefined, |
| | 2059 | |
| 2093 | .source = null, | 2060 | .source = null, |
| 2094 | .tree = null, | 2061 | .tree = null, |
| 2095 | .zir = null, | 2062 | .zir = null, |
| 2096 | .zoir = null, | 2063 | .zoir = null, |
| 2097 | .status = .never_loaded, | 2064 | |
| 2098 | .prev_status = .never_loaded, | | |
| 2099 | .mod = mod, | 2065 | .mod = mod, |
| 2100 | }; | 2066 | }; |
| 2101 | | 2067 | |
| ... | @@ -2835,7 +2801,7 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err | ... | @@ -2835,7 +2801,7 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err |
| 2835 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. | 2801 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. |
| 2836 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { | 2802 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { |
| 2837 | const zir = file.zir orelse return; | 2803 | const zir = file.zir orelse return; |
| 2838 | if (zir.hasCompileErrors()) return; | 2804 | if (!zir.hasCompileErrors()) return; |
| 2839 | | 2805 | |
| 2840 | pt.zcu.comp.mutex.lock(); | 2806 | pt.zcu.comp.mutex.lock(); |
| 2841 | defer pt.zcu.comp.mutex.unlock(); | 2807 | defer pt.zcu.comp.mutex.unlock(); |
| ... | @@ -3196,6 +3162,7 @@ pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Inde | ... | @@ -3196,6 +3162,7 @@ pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Inde |
| 3196 | } | 3162 | } |
| 3197 | } | 3163 | } |
| 3198 | | 3164 | |
| | 3165 | /// Sets `File.status` of `file_index` to `retryable_failure`, and stores an error in `pt.zcu.failed_files`. |
| 3199 | pub fn reportRetryableAstGenError( | 3166 | pub fn reportRetryableAstGenError( |
| 3200 | pt: Zcu.PerThread, | 3167 | pt: Zcu.PerThread, |
| 3201 | src: Zcu.AstGenSrc, | 3168 | src: Zcu.AstGenSrc, |
| ... | @@ -3231,13 +3198,18 @@ pub fn reportRetryableAstGenError( | ... | @@ -3231,13 +3198,18 @@ pub fn reportRetryableAstGenError( |
| 3231 | }); | 3198 | }); |
| 3232 | errdefer err_msg.destroy(gpa); | 3199 | errdefer err_msg.destroy(gpa); |
| 3233 | | 3200 | |
| 3234 | { | 3201 | zcu.comp.mutex.lock(); |
| 3235 | zcu.comp.mutex.lock(); | 3202 | defer zcu.comp.mutex.unlock(); |
| 3236 | defer zcu.comp.mutex.unlock(); | 3203 | const gop = try zcu.failed_files.getOrPut(gpa, file); |
| 3237 | try zcu.failed_files.putNoClobber(gpa, file, err_msg); | 3204 | if (gop.found_existing) { |
| | 3205 | if (gop.value_ptr.*) |old_err_msg| { |
| | 3206 | old_err_msg.destroy(gpa); |
| | 3207 | } |
| 3238 | } | 3208 | } |
| | 3209 | gop.value_ptr.* = err_msg; |
| 3239 | } | 3210 | } |
| 3240 | | 3211 | |
| | 3212 | /// Sets `File.status` of `file_index` to `retryable_failure`, and stores an error in `pt.zcu.failed_files`. |
| 3241 | pub fn reportRetryableFileError( | 3213 | pub fn reportRetryableFileError( |
| 3242 | pt: Zcu.PerThread, | 3214 | pt: Zcu.PerThread, |
| 3243 | file_index: Zcu.File.Index, | 3215 | file_index: Zcu.File.Index, |
| ... | @@ -3771,7 +3743,6 @@ fn recreateStructType( | ... | @@ -3771,7 +3743,6 @@ fn recreateStructType( |
| 3771 | | 3743 | |
| 3772 | const inst_info = key.zir_index.resolveFull(ip).?; | 3744 | const inst_info = key.zir_index.resolveFull(ip).?; |
| 3773 | const file = zcu.fileByIndex(inst_info.file); | 3745 | const file = zcu.fileByIndex(inst_info.file); |
| 3774 | assert(file.status == .success_zir); // otherwise inst tracking failed | | |
| 3775 | const zir = file.zir.?; | 3746 | const zir = file.zir.?; |
| 3776 | | 3747 | |
| 3777 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); | 3748 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); |
| ... | @@ -3844,7 +3815,6 @@ fn recreateUnionType( | ... | @@ -3844,7 +3815,6 @@ fn recreateUnionType( |
| 3844 | | 3815 | |
| 3845 | const inst_info = key.zir_index.resolveFull(ip).?; | 3816 | const inst_info = key.zir_index.resolveFull(ip).?; |
| 3846 | const file = zcu.fileByIndex(inst_info.file); | 3817 | const file = zcu.fileByIndex(inst_info.file); |
| 3847 | assert(file.status == .success_zir); // otherwise inst tracking failed | | |
| 3848 | const zir = file.zir.?; | 3818 | const zir = file.zir.?; |
| 3849 | | 3819 | |
| 3850 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); | 3820 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); |
| ... | @@ -3931,7 +3901,6 @@ fn recreateEnumType( | ... | @@ -3931,7 +3901,6 @@ fn recreateEnumType( |
| 3931 | | 3901 | |
| 3932 | const inst_info = key.zir_index.resolveFull(ip).?; | 3902 | const inst_info = key.zir_index.resolveFull(ip).?; |
| 3933 | const file = zcu.fileByIndex(inst_info.file); | 3903 | const file = zcu.fileByIndex(inst_info.file); |
| 3934 | assert(file.status == .success_zir); // otherwise inst tracking failed | | |
| 3935 | const zir = file.zir.?; | 3904 | const zir = file.zir.?; |
| 3936 | | 3905 | |
| 3937 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); | 3906 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); |
| ... | @@ -4075,7 +4044,6 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace | ... | @@ -4075,7 +4044,6 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace |
| 4075 | | 4044 | |
| 4076 | const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | 4045 | const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; |
| 4077 | const file = zcu.fileByIndex(inst_info.file); | 4046 | const file = zcu.fileByIndex(inst_info.file); |
| 4078 | if (file.status != .success_zir) return error.AnalysisFail; | | |
| 4079 | const zir = file.zir.?; | 4047 | const zir = file.zir.?; |
| 4080 | | 4048 | |
| 4081 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); | 4049 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); |