@@ -1022,6 +1022,35 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
1022
1022
}
1023
1023
}
1024
1024
1025
+ // If there isn't a type annotation, then we have also just resolved the type. That means the
1026
+ // the type is up-to-date, so it won't have the chance to mark its own dependency on the value;
1027
+ // we must do that ourselves.
1028
+ type_deps_on_val : {
1029
+ const inst_resolved = nav .analysis .? .zir_index .resolveFull (ip ) orelse break :type_deps_on_val ;
1030
+ const file = zcu .fileByIndex (inst_resolved .file );
1031
+ const zir_decl = file .zir .? .getDeclaration (inst_resolved .inst );
1032
+ if (zir_decl .type_body != null ) break :type_deps_on_val ;
1033
+ // The type does indeed depend on the value. We are responsible for populating all state of
1034
+ // the `nav_ty`, including exports, references, errors, and dependencies.
1035
+ const ty_unit : AnalUnit = .wrap (.{ .nav_ty = nav_id });
1036
+ const ty_was_outdated = zcu .outdated .swapRemove (ty_unit ) or
1037
+ zcu .potentially_outdated .swapRemove (ty_unit );
1038
+ if (ty_was_outdated ) {
1039
+ _ = zcu .outdated_ready .swapRemove (ty_unit );
1040
+ zcu .deleteUnitExports (ty_unit );
1041
+ zcu .deleteUnitReferences (ty_unit );
1042
+ zcu .deleteUnitCompileLogs (ty_unit );
1043
+ if (zcu .failed_analysis .fetchSwapRemove (ty_unit )) | kv | {
1044
+ kv .value .destroy (gpa );
1045
+ }
1046
+ _ = zcu .transitive_failed_analysis .swapRemove (ty_unit );
1047
+ ip .removeDependenciesForDepender (gpa , ty_unit );
1048
+ }
1049
+ try pt .addDependency (ty_unit , .{ .nav_val = nav_id });
1050
+ if (new_failed ) try zcu .transitive_failed_analysis .put (gpa , ty_unit , {});
1051
+ if (ty_was_outdated ) try zcu .markDependeeOutdated (.marked_po , .{ .nav_ty = nav_id });
1052
+ }
1053
+
1025
1054
if (new_failed ) return error .AnalysisFail ;
1026
1055
}
1027
1056
@@ -1266,14 +1295,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1266
1295
// Mark the unit as completed before evaluating the export!
1267
1296
assert (zcu .analysis_in_progress .swapRemove (anal_unit ));
1268
1297
1269
- if (zir_decl .type_body == null ) {
1270
- // In this situation, it's possible that we were triggered by `analyzeNavType` up the stack. In that
1271
- // case, we must also signal that the *type* is now populated to make this export behave correctly.
1272
- // An alternative strategy would be to just put something on the job queue to perform the export, but
1273
- // this is a little more straightforward, if perhaps less elegant.
1274
- _ = zcu .analysis_in_progress .swapRemove (.wrap (.{ .nav_ty = nav_id }));
1275
- }
1276
-
1277
1298
if (zir_decl .linkage == .@"export" ) {
1278
1299
const export_src = block .src (.{ .token_offset = @enumFromInt (@intFromBool (zir_decl .is_pub )) });
1279
1300
const name_slice = zir .nullTerminatedString (zir_decl .name );
@@ -1314,6 +1335,18 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
1314
1335
1315
1336
log .debug ("ensureNavTypeUpToDate {}" , .{zcu .fmtAnalUnit (anal_unit )});
1316
1337
1338
+ const type_resolved_by_value : bool = from_val : {
1339
+ const analysis = nav .analysis orelse break :from_val false ;
1340
+ const inst_resolved = analysis .zir_index .resolveFull (ip ) orelse break :from_val false ;
1341
+ const file = zcu .fileByIndex (inst_resolved .file );
1342
+ const zir_decl = file .zir .? .getDeclaration (inst_resolved .inst );
1343
+ break :from_val zir_decl .type_body == null ;
1344
+ };
1345
+ if (type_resolved_by_value ) {
1346
+ // Logic at the end of `ensureNavValUpToDate` is directly responsible for populating our state.
1347
+ return pt .ensureNavValUpToDate (nav_id );
1348
+ }
1349
+
1317
1350
// Determine whether or not this `Nav`'s type is outdated. This also includes checking if the
1318
1351
// status is `.unresolved`, which indicates that the value is outdated because it has *never*
1319
1352
// been analyzed so far.
@@ -1421,6 +1454,10 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1421
1454
try zcu .analysis_in_progress .put (gpa , anal_unit , {});
1422
1455
defer _ = zcu .analysis_in_progress .swapRemove (anal_unit );
1423
1456
1457
+ const zir_decl = zir .getDeclaration (inst_resolved .inst );
1458
+ assert (old_nav .is_usingnamespace == (zir_decl .kind == .@"usingnamespace" ));
1459
+ const type_body = zir_decl .type_body .? ;
1460
+
1424
1461
var analysis_arena : std.heap.ArenaAllocator = .init (gpa );
1425
1462
defer analysis_arena .deinit ();
1426
1463
@@ -1460,33 +1497,13 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1460
1497
};
1461
1498
defer block .instructions .deinit (gpa );
1462
1499
1463
- const zir_decl = zir .getDeclaration (inst_resolved .inst );
1464
- assert (old_nav .is_usingnamespace == (zir_decl .kind == .@"usingnamespace" ));
1465
-
1466
1500
const ty_src = block .src (.{ .node_offset_var_decl_ty = .zero });
1467
1501
1468
1502
block .comptime_reason = .{ .reason = .{
1469
1503
.src = ty_src ,
1470
1504
.r = .{ .simple = .type },
1471
1505
} };
1472
1506
1473
- const type_body = zir_decl .type_body orelse {
1474
- // The type of this `Nav` is inferred from the value.
1475
- // In other words, this `nav_ty` depends on the corresponding `nav_val`.
1476
- try sema .declareDependency (.{ .nav_val = nav_id });
1477
- try pt .ensureNavValUpToDate (nav_id );
1478
- // Note that the above call, if it did any work, has removed our `analysis_in_progress` entry for us.
1479
- // (Our `defer` will run anyway, but it does nothing in this case.)
1480
-
1481
- // There's not a great way for us to know whether the type actually changed.
1482
- // For instance, perhaps the `nav_val` was already up-to-date, but this `nav_ty` is being
1483
- // analyzed because this declaration had a type annotation on the *previous* update.
1484
- // However, such cases are rare, and it's not unreasonable to re-analyze in them; and in
1485
- // other cases where we get here, it's because the `nav_val` was already re-analyzed and
1486
- // is outdated.
1487
- return .{ .type_changed = true };
1488
- };
1489
-
1490
1507
const resolved_ty : Type = ty : {
1491
1508
const uncoerced_type_ref = try sema .resolveInlineBody (& block , type_body , inst_resolved .inst );
1492
1509
const type_ref = try sema .coerce (& block , .type , uncoerced_type_ref , ty_src );
0 commit comments