Repository: carbon-language/carbon-lang
File: toolchain/check/import_ref.cpp (C++)

Code before:

  llvm::SmallVector<SemIR::InstId> lazy_virtual_functions;
  lazy_virtual_functions.reserve(virtual_functions.size());
  for (auto vtable_entry_id : virtual_functions) {
    auto local_attached_constant_id = GetLocalConstantId(
        resolver,
        resolver.import_constant_values().GetAttached(vtable_entry_id));
    if (resolver.HasNewWork()) {
      continue;
    }
    // Use LoadedImportRef for imported symbolic constant vtable entries so they
    // can carry attached constants necessary for applying specifics to these
    // constants when they are used.
    lazy_virtual_functions.push_back(
        local_attached_constant_id.is_symbolic()
            ? AddLoadedImportRef(
                  resolver,
                  GetSingletonType(resolver.local_context(),
                                   SemIR::SpecificFunctionType::TypeInstId),
                  vtable_entry_id, local_attached_constant_id)
            : resolver.local_constant_values().GetInstId(
                  local_attached_constant_id));
  }
  if (resolver.HasNewWork()) {
    return ResolveResult::Retry();
  }

  auto new_vtable_id = resolver.local_vtables().Add(
      {{.class_id = class_id,
        .virtual_functions_id =
            resolver.local_inst_blocks().Add(lazy_virtual_functions)}});

  return ResolveAsDeduplicated<SemIR::VtablePtr>(
      resolver, {.type_id = GetPointerType(resolver.local_context(),
                                           SemIR::VtableType::TypeInstId),
                 .vtable_id = new_vtable_id,
                 .specific_id = GetOrAddLocalSpecific(
                     resolver, inst.specific_id, specific_data)});
}

static auto TryResolveTypedInst(ImportRefResolver& resolver,
                                SemIR::FunctionType inst) -> ResolveResult {
  CARBON_CHECK(inst.type_id == SemIR::TypeType::TypeId);
  auto fn_val_id = GetLocalConstantInstId(
      resolver,
      resolver.import_functions().Get(inst.function_id).first_decl_id());
  auto specific_data = GetLocalSpecificData(resolver, inst.specific_id);
  if (resolver.HasNewWork()) {
    return ResolveResult::Retry();
  }
  auto fn_type_id = resolver.local_insts().Get(fn_val_id).type_id();

Review comment (suggestion):
Rather than adding a second `HasNewWork` / `Retry()` here, we generally do all the work that could add new work before a single `HasNewWork` / `Retry()`. (There is a special case for declaration-like entities that need three-pass construction instead of two-pass, but it doesn't apply here.)

Applying that approach here, we'd make all the `GetLocalConstantId` calls before the `HasNewWork` / `Retry`, and then do all the `AddLoadedImportRef`s afterwards.

Code after:
            local_attached_constant_id));
  }

  if (resolver.HasNewWork()) {
    return ResolveResult::Retry();
  }

  for (auto& vtable_entry_id : lazy_virtual_functions) {
    // Use LoadedImportRef for imported symbolic constant vtable entries so they
    // can carry attached constants necessary for applying specifics to these
    // constants when they are used.
    auto local_attached_constant_id =
        resolver.local_constant_values().Get(vtable_entry_id);
    if (local_attached_constant_id.is_symbolic()) {
      vtable_entry_id = AddLoadedImportRef(
          resolver,
          GetSingletonType(resolver.local_context(),
                           SemIR::SpecificFunctionType::TypeInstId),
          vtable_entry_id, local_attached_constant_id);
    }
  }

  auto class_const_inst = resolver.local_insts().Get(
      resolver.local_constant_values().GetInstId(class_const_id));

  auto class_id = SemIR::ClassId::None;
  if (class_const_inst.Is<SemIR::ClassType>()) {
    class_id = class_const_inst.As<SemIR::ClassType>().class_id;
  } else {
    auto generic_class_type =
        resolver.local_types().GetAs<SemIR::GenericClassType>(
            class_const_inst.type_id());
    class_id = generic_class_type.class_id;
  }

  auto new_vtable_id = resolver.local_vtables().Add(
      {{.class_id = class_id,
        .virtual_functions_id =
            resolver.local_inst_blocks().Add(lazy_virtual_functions)}});

  return ResolveAsDeduplicated<SemIR::VtablePtr>(
      resolver, {.type_id = GetPointerType(resolver.local_context(),
                                           SemIR::VtableType::TypeInstId),
                 .vtable_id = new_vtable_id,
                 .specific_id = GetOrAddLocalSpecific(
                     resolver, inst.specific_id, specific_data)});
}

static auto TryResolveTypedInst(ImportRefResolver& resolver,
                                SemIR::FunctionType inst) -> ResolveResult {
  CARBON_CHECK(inst.type_id == SemIR::TypeType::TypeId);