authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-10 12:48:42+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-09-21 21:08:51+02:00
logb4394412bb0f5d2ff0018fb9e868ccf0f46ab911
treed6168227a598c23fe5d00464eb9e93c907b32c74
parent582b96c361e9bad0a7e44b67af932689bc1afb82
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Zcu: fix analysis of type of decl with inferred type

If the `nav_ty` is resolved by the `nav_val`, then we need to also mark the `nav_ty` as in progress when we begin resolving the `nav_val`.

2 files changed, 25 insertions(+), 9 deletions(-)

src/Sema.zig+1-1
...@@ -34975,7 +34975,7 @@ fn resolveInferredErrorSet(...@@ -34975,7 +34975,7 @@ fn resolveInferredErrorSet(
34975 const resolved_ty = func.resolvedErrorSetUnordered(ip);34975 const resolved_ty = func.resolvedErrorSetUnordered(ip);
34976 if (resolved_ty != .none) return resolved_ty;34976 if (resolved_ty != .none) return resolved_ty;
3497734977
34978 if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .func = func_index }))) {34978 if (zcu.analysis_in_progress.contains(.wrap(.{ .func = func_index }))) {
34979 return sema.fail(block, src, "unable to resolve inferred error set", .{});34979 return sema.fail(block, src, "unable to resolve inferred error set", .{});
34980 }34980 }
3498134981
src/Zcu/PerThread.zig+24-8
...@@ -700,7 +700,7 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage)...@@ -700,7 +700,7 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage)
700700
701 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });701 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
702702
703 try zcu.analysis_in_progress.put(gpa, unit, {});703 try zcu.analysis_in_progress.putNoClobber(gpa, unit, {});
704 defer assert(zcu.analysis_in_progress.swapRemove(unit));704 defer assert(zcu.analysis_in_progress.swapRemove(unit));
705705
706 // Before we begin, collect:706 // Before we begin, collect:
...@@ -864,7 +864,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu...@@ -864,7 +864,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
864 const file = zcu.fileByIndex(inst_resolved.file);864 const file = zcu.fileByIndex(inst_resolved.file);
865 const zir = file.zir.?;865 const zir = file.zir.?;
866866
867 try zcu.analysis_in_progress.put(gpa, anal_unit, {});867 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
868 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));868 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
869869
870 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);870 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
...@@ -958,6 +958,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu...@@ -958,6 +958,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
958958
959 log.debug("ensureNavValUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});959 log.debug("ensureNavValUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
960960
961 assert(!zcu.analysis_in_progress.contains(anal_unit));
962
961 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the963 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the
962 // status is `.unresolved`, which indicates that the value is outdated because it has *never*964 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
963 // been analyzed so far.965 // been analyzed so far.
...@@ -1090,10 +1092,19 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1090,10 +1092,19 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1090 const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;1092 const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
1091 const file = zcu.fileByIndex(inst_resolved.file);1093 const file = zcu.fileByIndex(inst_resolved.file);
1092 const zir = file.zir.?;1094 const zir = file.zir.?;
1095 const zir_decl = zir.getDeclaration(inst_resolved.inst);
10931096
1094 try zcu.analysis_in_progress.put(gpa, anal_unit, {});1097 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
1095 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);1098 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
10961099
1100 // If there's no type body, we are also resolving the type here.
1101 if (zir_decl.type_body == null) {
1102 try zcu.analysis_in_progress.putNoClobber(gpa, .wrap(.{ .nav_ty = nav_id }), {});
1103 }
1104 errdefer if (zir_decl.type_body == null) {
1105 _ = zcu.analysis_in_progress.swapRemove(.wrap(.{ .nav_ty = nav_id }));
1106 };
1107
1097 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);1108 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
1098 defer analysis_arena.deinit();1109 defer analysis_arena.deinit();
10991110
...@@ -1133,8 +1144,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1133,8 +1144,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1133 };1144 };
1134 defer block.instructions.deinit(gpa);1145 defer block.instructions.deinit(gpa);
11351146
1136 const zir_decl = zir.getDeclaration(inst_resolved.inst);
1137
1138 const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero });1147 const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero });
1139 const init_src = block.src(.{ .node_offset_var_decl_init = .zero });1148 const init_src = block.src(.{ .node_offset_var_decl_init = .zero });
1140 const align_src = block.src(.{ .node_offset_var_decl_align = .zero });1149 const align_src = block.src(.{ .node_offset_var_decl_align = .zero });
...@@ -1305,6 +1314,9 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1305,6 +1314,9 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
13051314
1306 // Mark the unit as completed before evaluating the export!1315 // Mark the unit as completed before evaluating the export!
1307 assert(zcu.analysis_in_progress.swapRemove(anal_unit));1316 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1317 if (zir_decl.type_body == null) {
1318 assert(zcu.analysis_in_progress.swapRemove(.wrap(.{ .nav_ty = nav_id })));
1319 }
13081320
1309 if (zir_decl.linkage == .@"export") {1321 if (zir_decl.linkage == .@"export") {
1310 const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) });1322 const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) });
...@@ -1347,6 +1359,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc...@@ -1347,6 +1359,8 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
13471359
1348 log.debug("ensureNavTypeUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});1360 log.debug("ensureNavTypeUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
13491361
1362 assert(!zcu.analysis_in_progress.contains(anal_unit));
1363
1350 const type_resolved_by_value: bool = from_val: {1364 const type_resolved_by_value: bool = from_val: {
1351 const analysis = nav.analysis orelse break :from_val false;1365 const analysis = nav.analysis orelse break :from_val false;
1352 const inst_resolved = analysis.zir_index.resolveFull(ip) orelse break :from_val false;1366 const inst_resolved = analysis.zir_index.resolveFull(ip) orelse break :from_val false;
...@@ -1463,8 +1477,8 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1463,8 +1477,8 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1463 const file = zcu.fileByIndex(inst_resolved.file);1477 const file = zcu.fileByIndex(inst_resolved.file);
1464 const zir = file.zir.?;1478 const zir = file.zir.?;
14651479
1466 try zcu.analysis_in_progress.put(gpa, anal_unit, {});1480 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
1467 defer _ = zcu.analysis_in_progress.swapRemove(anal_unit);1481 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
14681482
1469 const zir_decl = zir.getDeclaration(inst_resolved.inst);1483 const zir_decl = zir.getDeclaration(inst_resolved.inst);
1470 const type_body = zir_decl.type_body.?;1484 const type_body = zir_decl.type_body.?;
...@@ -1587,6 +1601,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z...@@ -1587,6 +1601,8 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
15871601
1588 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});1602 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
15891603
1604 assert(!zcu.analysis_in_progress.contains(anal_unit));
1605
1590 const func = zcu.funcInfo(func_index);1606 const func = zcu.funcInfo(func_index);
15911607
1592 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one1608 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one
...@@ -2781,7 +2797,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2781,7 +2797,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2781 const file = zcu.fileByIndex(inst_info.file);2797 const file = zcu.fileByIndex(inst_info.file);
2782 const zir = file.zir.?;2798 const zir = file.zir.?;
27832799
2784 try zcu.analysis_in_progress.put(gpa, anal_unit, {});2800 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
2785 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);2801 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
27862802
2787 func.setAnalyzed(ip);2803 func.setAnalyzed(ip);