| ... | @@ -3524,9 +3524,11 @@ pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPo | ... | @@ -3524,9 +3524,11 @@ pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPo |
| 3524 | return ty.abiAlignment(zcu); | 3524 | return ty.abiAlignment(zcu); |
| 3525 | } | 3525 | } |
| 3526 | | 3526 | |
| 3527 | /// Given a container type requiring resolution, ensures that it is up-to-date. | 3527 | /// `ty` is a container type requiring resolution (struct, union, or enum). |
| 3528 | /// If not, the type is recreated at a new `InternPool.Index`. | 3528 | /// If `ty` is outdated, it is recreated at a new `InternPool.Index`, which is returned. |
| 3529 | /// The new index is returned. This is the same as the old index if the fields were up-to-date. | 3529 | /// If the type cannot be recreated because it has been lost, `error.AnalysisFail` is returned. |
| | 3530 | /// If `ty` is not outdated, that same `InternPool.Index` is returned. |
| | 3531 | /// If `ty` has already been replaced by this function, the new index will not be returned again. |
| 3530 | pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError!InternPool.Index { | 3532 | pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError!InternPool.Index { |
| 3531 | const zcu = pt.zcu; | 3533 | const zcu = pt.zcu; |
| 3532 | const gpa = zcu.gpa; | 3534 | const gpa = zcu.gpa; |
| ... | @@ -3536,13 +3538,30 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError | ... | @@ -3536,13 +3538,30 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError |
| 3536 | const outdated = zcu.outdated.swapRemove(anal_unit) or | 3538 | const outdated = zcu.outdated.swapRemove(anal_unit) or |
| 3537 | zcu.potentially_outdated.swapRemove(anal_unit); | 3539 | zcu.potentially_outdated.swapRemove(anal_unit); |
| 3538 | | 3540 | |
| | 3541 | if (outdated) { |
| | 3542 | _ = zcu.outdated_ready.swapRemove(anal_unit); |
| | 3543 | try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty }); |
| | 3544 | } |
| | 3545 | |
| | 3546 | const ty_key = switch (ip.indexToKey(ty)) { |
| | 3547 | .struct_type, .union_type, .enum_type => |key| key, |
| | 3548 | else => unreachable, |
| | 3549 | }; |
| | 3550 | const declared_ty_key = switch (ty_key) { |
| | 3551 | .reified => unreachable, // never outdated |
| | 3552 | .generated_tag => unreachable, // never outdated |
| | 3553 | .declared => |d| d, |
| | 3554 | }; |
| | 3555 | |
| | 3556 | if (declared_ty_key.zir_index.resolve(ip) == null) { |
| | 3557 | // The instruction has been lost -- this type is dead. |
| | 3558 | return error.AnalysisFail; |
| | 3559 | } |
| | 3560 | |
| 3539 | if (!outdated) return ty; | 3561 | if (!outdated) return ty; |
| 3540 | | 3562 | |
| 3541 | // We will recreate the type at a new `InternPool.Index`. | 3563 | // We will recreate the type at a new `InternPool.Index`. |
| 3542 | | 3564 | |
| 3543 | _ = zcu.outdated_ready.swapRemove(anal_unit); | | |
| 3544 | try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty }); | | |
| 3545 | | | |
| 3546 | // Delete old state which is no longer in use. Technically, this is not necessary: these exports, | 3565 | // Delete old state which is no longer in use. Technically, this is not necessary: these exports, |
| 3547 | // references, etc, will be ignored because the type itself is unreferenced. However, it allows | 3566 | // references, etc, will be ignored because the type itself is unreferenced. However, it allows |
| 3548 | // reusing the memory which is currently being used to track this state. | 3567 | // reusing the memory which is currently being used to track this state. |
| ... | @@ -3555,9 +3574,9 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError | ... | @@ -3555,9 +3574,9 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError |
| 3555 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); | 3574 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); |
| 3556 | | 3575 | |
| 3557 | switch (ip.indexToKey(ty)) { | 3576 | switch (ip.indexToKey(ty)) { |
| 3558 | .struct_type => |key| return pt.recreateStructType(ty, key), | 3577 | .struct_type => return pt.recreateStructType(ty, declared_ty_key), |
| 3559 | .union_type => |key| return pt.recreateUnionType(ty, key), | 3578 | .union_type => return pt.recreateUnionType(ty, declared_ty_key), |
| 3560 | .enum_type => |key| return pt.recreateEnumType(ty, key), | 3579 | .enum_type => return pt.recreateEnumType(ty, declared_ty_key), |
| 3561 | else => unreachable, | 3580 | else => unreachable, |
| 3562 | } | 3581 | } |
| 3563 | } | 3582 | } |
| ... | @@ -3565,21 +3584,15 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError | ... | @@ -3565,21 +3584,15 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError |
| 3565 | fn recreateStructType( | 3584 | fn recreateStructType( |
| 3566 | pt: Zcu.PerThread, | 3585 | pt: Zcu.PerThread, |
| 3567 | old_ty: InternPool.Index, | 3586 | old_ty: InternPool.Index, |
| 3568 | full_key: InternPool.Key.NamespaceType, | 3587 | key: InternPool.Key.NamespaceType.Declared, |
| 3569 | ) Zcu.SemaError!InternPool.Index { | 3588 | ) Allocator.Error!InternPool.Index { |
| 3570 | const zcu = pt.zcu; | 3589 | const zcu = pt.zcu; |
| 3571 | const gpa = zcu.gpa; | 3590 | const gpa = zcu.gpa; |
| 3572 | const ip = &zcu.intern_pool; | 3591 | const ip = &zcu.intern_pool; |
| 3573 | | 3592 | |
| 3574 | const key = switch (full_key) { | 3593 | const inst_info = key.zir_index.resolveFull(ip).?; |
| 3575 | .reified => unreachable, // never outdated | | |
| 3576 | .generated_tag => unreachable, // not a struct | | |
| 3577 | .declared => |d| d, | | |
| 3578 | }; | | |
| 3579 | | | |
| 3580 | const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | | |
| 3581 | const file = zcu.fileByIndex(inst_info.file); | 3594 | const file = zcu.fileByIndex(inst_info.file); |
| 3582 | if (file.status != .success_zir) return error.AnalysisFail; | 3595 | assert(file.status == .success_zir); // otherwise inst tracking failed |
| 3583 | const zir = file.zir; | 3596 | const zir = file.zir; |
| 3584 | | 3597 | |
| 3585 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); | 3598 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); |
| ... | @@ -3600,7 +3613,7 @@ fn recreateStructType( | ... | @@ -3600,7 +3613,7 @@ fn recreateStructType( |
| 3600 | break :blk fields_len; | 3613 | break :blk fields_len; |
| 3601 | } else 0; | 3614 | } else 0; |
| 3602 | | 3615 | |
| 3603 | if (captures_len != key.captures.owned.len) return error.AnalysisFail; | 3616 | assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew` |
| 3604 | | 3617 | |
| 3605 | const struct_obj = ip.loadStructType(old_ty); | 3618 | const struct_obj = ip.loadStructType(old_ty); |
| 3606 | | 3619 | |
| ... | @@ -3644,21 +3657,15 @@ fn recreateStructType( | ... | @@ -3644,21 +3657,15 @@ fn recreateStructType( |
| 3644 | fn recreateUnionType( | 3657 | fn recreateUnionType( |
| 3645 | pt: Zcu.PerThread, | 3658 | pt: Zcu.PerThread, |
| 3646 | old_ty: InternPool.Index, | 3659 | old_ty: InternPool.Index, |
| 3647 | full_key: InternPool.Key.NamespaceType, | 3660 | key: InternPool.Key.NamespaceType.Declared, |
| 3648 | ) Zcu.SemaError!InternPool.Index { | 3661 | ) Allocator.Error!InternPool.Index { |
| 3649 | const zcu = pt.zcu; | 3662 | const zcu = pt.zcu; |
| 3650 | const gpa = zcu.gpa; | 3663 | const gpa = zcu.gpa; |
| 3651 | const ip = &zcu.intern_pool; | 3664 | const ip = &zcu.intern_pool; |
| 3652 | | 3665 | |
| 3653 | const key = switch (full_key) { | 3666 | const inst_info = key.zir_index.resolveFull(ip).?; |
| 3654 | .reified => unreachable, // never outdated | | |
| 3655 | .generated_tag => unreachable, // not a union | | |
| 3656 | .declared => |d| d, | | |
| 3657 | }; | | |
| 3658 | | | |
| 3659 | const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | | |
| 3660 | const file = zcu.fileByIndex(inst_info.file); | 3667 | const file = zcu.fileByIndex(inst_info.file); |
| 3661 | if (file.status != .success_zir) return error.AnalysisFail; | 3668 | assert(file.status == .success_zir); // otherwise inst tracking failed |
| 3662 | const zir = file.zir; | 3669 | const zir = file.zir; |
| 3663 | | 3670 | |
| 3664 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); | 3671 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); |
| ... | @@ -3681,7 +3688,7 @@ fn recreateUnionType( | ... | @@ -3681,7 +3688,7 @@ fn recreateUnionType( |
| 3681 | break :blk fields_len; | 3688 | break :blk fields_len; |
| 3682 | } else 0; | 3689 | } else 0; |
| 3683 | | 3690 | |
| 3684 | if (captures_len != key.captures.owned.len) return error.AnalysisFail; | 3691 | assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew` |
| 3685 | | 3692 | |
| 3686 | const union_obj = ip.loadUnionType(old_ty); | 3693 | const union_obj = ip.loadUnionType(old_ty); |
| 3687 | | 3694 | |
| ... | @@ -3731,23 +3738,19 @@ fn recreateUnionType( | ... | @@ -3731,23 +3738,19 @@ fn recreateUnionType( |
| 3731 | return wip_ty.finish(ip, namespace_index); | 3738 | return wip_ty.finish(ip, namespace_index); |
| 3732 | } | 3739 | } |
| 3733 | | 3740 | |
| | 3741 | // TODO: is it safe for this to return `SemaError`? enum type resolution is a bit weird... |
| 3734 | fn recreateEnumType( | 3742 | fn recreateEnumType( |
| 3735 | pt: Zcu.PerThread, | 3743 | pt: Zcu.PerThread, |
| 3736 | old_ty: InternPool.Index, | 3744 | old_ty: InternPool.Index, |
| 3737 | full_key: InternPool.Key.NamespaceType, | 3745 | key: InternPool.Key.NamespaceType.Declared, |
| 3738 | ) Zcu.SemaError!InternPool.Index { | 3746 | ) Zcu.SemaError!InternPool.Index { |
| 3739 | const zcu = pt.zcu; | 3747 | const zcu = pt.zcu; |
| 3740 | const gpa = zcu.gpa; | 3748 | const gpa = zcu.gpa; |
| 3741 | const ip = &zcu.intern_pool; | 3749 | const ip = &zcu.intern_pool; |
| 3742 | | 3750 | |
| 3743 | const key = switch (full_key) { | 3751 | const inst_info = key.zir_index.resolveFull(ip).?; |
| 3744 | .reified, .generated_tag => unreachable, // never outdated | | |
| 3745 | .declared => |d| d, | | |
| 3746 | }; | | |
| 3747 | | | |
| 3748 | const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail; | | |
| 3749 | const file = zcu.fileByIndex(inst_info.file); | 3752 | const file = zcu.fileByIndex(inst_info.file); |
| 3750 | if (file.status != .success_zir) return error.AnalysisFail; | 3753 | assert(file.status == .success_zir); // otherwise inst tracking failed |
| 3751 | const zir = file.zir; | 3754 | const zir = file.zir; |
| 3752 | | 3755 | |
| 3753 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); | 3756 | assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended); |
| ... | @@ -3787,7 +3790,7 @@ fn recreateEnumType( | ... | @@ -3787,7 +3790,7 @@ fn recreateEnumType( |
| 3787 | break :blk decls_len; | 3790 | break :blk decls_len; |
| 3788 | } else 0; | 3791 | } else 0; |
| 3789 | | 3792 | |
| 3790 | if (captures_len != key.captures.owned.len) return error.AnalysisFail; | 3793 | assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew` |
| 3791 | | 3794 | |
| 3792 | extra_index += captures_len; | 3795 | extra_index += captures_len; |
| 3793 | extra_index += decls_len; | 3796 | extra_index += decls_len; |