Skip to content

Commit 9010249

Browse files
authored
Remove reallocation assumptions from generic code (#6217)
Rather than assume reallocations can occur, we've switched to providing stable references, so simplify related code. Only removing the comment in `BuildGeneric`, no refactoring, because I don't feel a refactoring would be a significant improvement.
1 parent 1a9826b commit 9010249

File tree

2 files changed

+19
-45
lines changed

2 files changed

+19
-45
lines changed

toolchain/check/generic.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,6 @@ auto BuildGeneric(Context& context, SemIR::InstId decl_id) -> SemIR::GenericId {
466466
context.generics().Get(generic_id) = generic;
467467
}
468468

469-
// MakeSelfSpecificId could cause something to be imported, which would
470-
// invalidate the return value of `context.generics().Get(generic_id)`.
471469
auto self_specific_id = MakeSelfSpecificId(context, generic_id);
472470
context.generics().Get(generic_id).self_specific_id = self_specific_id;
473471
return generic_id;
@@ -654,18 +652,15 @@ auto ResolveSpecificDecl(Context& context, SemIR::LocId loc_id,
654652
SemIR::SpecificId specific_id) -> void {
655653
// If this is the first time we've formed this specific, evaluate its decl
656654
// block to form information about the specific.
657-
if (!context.specifics().Get(specific_id).decl_block_id.has_value()) {
655+
auto& specific = context.specifics().Get(specific_id);
656+
if (!specific.decl_block_id.has_value()) {
658657
// Set a placeholder value as the decl block ID so we won't attempt to
659658
// recursively resolve the same specific.
660-
context.specifics().Get(specific_id).decl_block_id =
661-
SemIR::InstBlockId::Empty;
659+
specific.decl_block_id = SemIR::InstBlockId::Empty;
662660

663-
auto decl_block_id =
661+
specific.decl_block_id =
664662
TryEvalBlockForSpecific(context, loc_id, specific_id,
665663
SemIR::GenericInstIndex::Region::Declaration);
666-
// Note that TryEvalBlockForSpecific may reallocate the list of specifics,
667-
// so re-lookup the specific here.
668-
context.specifics().Get(specific_id).decl_block_id = decl_block_id;
669664
}
670665
}
671666

@@ -728,12 +723,8 @@ auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
728723
// The generic is not defined yet.
729724
return false;
730725
}
731-
auto definition_block_id = TryEvalBlockForSpecific(
726+
specific.definition_block_id = TryEvalBlockForSpecific(
732727
context, loc_id, specific_id, SemIR::GenericInstIndex::Definition);
733-
// Note that TryEvalBlockForSpecific may reallocate the list of specifics,
734-
// so re-lookup the specific here.
735-
context.specifics().Get(specific_id).definition_block_id =
736-
definition_block_id;
737728
}
738729
return true;
739730
}

toolchain/check/import_ref.cpp

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3500,36 +3500,29 @@ static auto FinishPendingGeneric(ImportRefResolver& resolver,
35003500
-> void {
35013501
const auto& import_generic =
35023502
resolver.import_generics().Get(pending.import_id);
3503+
auto& local_generic = resolver.local_generics().Get(pending.local_id);
35033504

35043505
// Load the bindings for the generic eagerly; they're used to form the self
35053506
// specific.
35063507
// TODO: Avoid recursion.
3507-
for (auto binding_id : resolver.local_inst_blocks().Get(
3508-
resolver.local_generics().Get(pending.local_id).bindings_id)) {
3508+
for (auto binding_id :
3509+
resolver.local_inst_blocks().Get(local_generic.bindings_id)) {
35093510
LoadImportRef(resolver.local_context(), binding_id);
35103511
}
35113512

3512-
// Don't store the local generic between calls: the generics list can be
3513-
// reallocated by ResolveLocalEvalBlock importing more specifics.
3514-
3515-
auto decl_block_id =
3513+
local_generic.decl_block_id =
35163514
ResolveLocalEvalBlock(resolver, import_generic, pending.local_id,
35173515
SemIR::GenericInstIndex::Region::Declaration);
3518-
resolver.local_generics().Get(pending.local_id).decl_block_id = decl_block_id;
35193516

3520-
auto local_decl_id = resolver.local_generics().Get(pending.local_id).decl_id;
3521-
auto self_specific_id = MakeSelfSpecific(
3522-
resolver.local_context(), SemIR::LocId(local_decl_id), pending.local_id);
3523-
resolver.local_generics().Get(pending.local_id).self_specific_id =
3524-
self_specific_id;
3517+
local_generic.self_specific_id =
3518+
MakeSelfSpecific(resolver.local_context(),
3519+
SemIR::LocId(local_generic.decl_id), pending.local_id);
35253520
resolver.AddPendingSpecific({.import_id = import_generic.self_specific_id,
3526-
.local_id = self_specific_id});
3521+
.local_id = local_generic.self_specific_id});
35273522

3528-
auto definition_block_id =
3523+
local_generic.definition_block_id =
35293524
ResolveLocalEvalBlock(resolver, import_generic, pending.local_id,
35303525
SemIR::GenericInstIndex::Region::Definition);
3531-
resolver.local_generics().Get(pending.local_id).definition_block_id =
3532-
definition_block_id;
35333526
}
35343527

35353528
// Resolves and returns a local inst block of constant instructions
@@ -3551,27 +3544,17 @@ static auto FinishPendingSpecific(ImportRefResolver& resolver,
35513544
-> void {
35523545
const auto& import_specific =
35533546
resolver.import_specifics().Get(pending.import_id);
3547+
auto& local_specific = resolver.local_specifics().Get(pending.local_id);
35543548

3555-
// Don't store the local specific between calls: the specifics list can be
3556-
// reallocated by ResolveLocalInstBlock importing more specifics.
3557-
3558-
if (!resolver.local_specifics()
3559-
.Get(pending.local_id)
3560-
.decl_block_id.has_value()) {
3561-
auto decl_block_id =
3549+
if (!local_specific.decl_block_id.has_value()) {
3550+
local_specific.decl_block_id =
35623551
ResolveLocalInstBlock(resolver, import_specific.decl_block_id);
3563-
resolver.local_specifics().Get(pending.local_id).decl_block_id =
3564-
decl_block_id;
35653552
}
35663553

3567-
if (!resolver.local_specifics()
3568-
.Get(pending.local_id)
3569-
.definition_block_id.has_value() &&
3554+
if (!local_specific.definition_block_id.has_value() &&
35703555
import_specific.definition_block_id.has_value()) {
3571-
auto definition_block_id =
3556+
local_specific.definition_block_id =
35723557
ResolveLocalInstBlock(resolver, import_specific.definition_block_id);
3573-
resolver.local_specifics().Get(pending.local_id).definition_block_id =
3574-
definition_block_id;
35753558
}
35763559
}
35773560

0 commit comments

Comments
 (0)