Преглед на файлове

Change ImportRef to a triple state: Unloaded, Loaded, Used (#3831)

This doesn't significantly change logic, although I'm trying to add the
location to used state.

The issue I'm trying to address is how to identify a declaration as
"allowed to be redeclared". Consider:

```
library "a" api;
extern fn F();
```
```
library "b" api;
extern fn F();
```
```
library "c" api;
import library "a";
import library "b";
var x: auto = F();
fn F();
```

What currently happens is:

1. On import of "a", `F` becomes ImportRefUnused
2. On import of "b", `F` becomes ImportRefUsed in order to merge.
3. In "c", the call `F()` doesn't change the state.
4. In "c", the declaration `fn F();` needs some breadcrumb to understand
whether "F" has been referenced, as in step (3) here.

What I want to happen is:

1. On import of "a", `F` becomes ImportRefUnloaded
2. On import of "b", `F` becomes ImportRefLoaded in order to merge.
3. In "c", the call `F()` causes `F` to become ImportRefUsed
4. In "c", the declaration `fn F();` detects that `F` is already
ImportRefUsed, and can use the associated `used_id` for a diagnostic
about why redeclaring is invalid.

Note this PR isn't implementing (4). I'm focused on the refactoring to
add a new ImportRef state here.
Jon Ross-Perkins преди 2 години
родител
ревизия
f8c8861e5f
променени са 73 файла, в които са добавени 727 реда и са изтрити 547 реда
  1. 1 0
      toolchain/check/BUILD
  2. 6 8
      toolchain/check/check.cpp
  3. 20 15
      toolchain/check/context.cpp
  4. 2 2
      toolchain/check/context.h
  5. 4 3
      toolchain/check/eval.cpp
  6. 1 1
      toolchain/check/impl.cpp
  7. 6 4
      toolchain/check/import.cpp
  8. 65 31
      toolchain/check/import_ref.cpp
  9. 4 3
      toolchain/check/import_ref.h
  10. 4 4
      toolchain/check/merge.cpp
  11. 2 2
      toolchain/check/testdata/alias/import.carbon
  12. 4 4
      toolchain/check/testdata/alias/import_order.carbon
  13. 10 10
      toolchain/check/testdata/basics/builtin_insts.carbon
  14. 9 9
      toolchain/check/testdata/class/cross_package_import.carbon
  15. 3 3
      toolchain/check/testdata/class/fail_import_misuses.carbon
  16. 1 1
      toolchain/check/testdata/class/fail_todo_import_forward_decl.carbon
  17. 13 13
      toolchain/check/testdata/class/import.carbon
  18. 9 9
      toolchain/check/testdata/class/import_base.carbon
  19. 3 3
      toolchain/check/testdata/class/import_member_cycle.carbon
  20. 4 4
      toolchain/check/testdata/class/import_struct_cyle.carbon
  21. 3 3
      toolchain/check/testdata/const/import.carbon
  22. 7 7
      toolchain/check/testdata/function/builtin/call_from_operator.carbon
  23. 1 1
      toolchain/check/testdata/function/builtin/import.carbon
  24. 117 28
      toolchain/check/testdata/function/declaration/import.carbon
  25. 12 12
      toolchain/check/testdata/function/definition/import.carbon
  26. 19 19
      toolchain/check/testdata/interface/import.carbon
  27. 1 1
      toolchain/check/testdata/let/fail_generic_import.carbon
  28. 1 1
      toolchain/check/testdata/let/generic_import.carbon
  29. 1 1
      toolchain/check/testdata/let/import.carbon
  30. 1 1
      toolchain/check/testdata/namespace/add_to_import.carbon
  31. 1 1
      toolchain/check/testdata/namespace/fail_conflict_after_merge.carbon
  32. 1 1
      toolchain/check/testdata/namespace/fail_conflict_imported_namespace_first.carbon
  33. 1 1
      toolchain/check/testdata/namespace/fail_conflict_imported_namespace_second.carbon
  34. 3 3
      toolchain/check/testdata/namespace/fail_conflict_in_imports_namespace_first.carbon
  35. 3 3
      toolchain/check/testdata/namespace/fail_conflict_in_imports_namespace_second.carbon
  36. 4 4
      toolchain/check/testdata/namespace/imported.carbon
  37. 10 10
      toolchain/check/testdata/namespace/imported_indirect.carbon
  38. 4 4
      toolchain/check/testdata/namespace/merging.carbon
  39. 12 12
      toolchain/check/testdata/operators/overloaded/add.carbon
  40. 12 12
      toolchain/check/testdata/operators/overloaded/bit_and.carbon
  41. 6 6
      toolchain/check/testdata/operators/overloaded/bit_complement.carbon
  42. 12 12
      toolchain/check/testdata/operators/overloaded/bit_or.carbon
  43. 12 12
      toolchain/check/testdata/operators/overloaded/bit_xor.carbon
  44. 6 6
      toolchain/check/testdata/operators/overloaded/dec.carbon
  45. 12 12
      toolchain/check/testdata/operators/overloaded/div.carbon
  46. 29 29
      toolchain/check/testdata/operators/overloaded/eq.carbon
  47. 12 12
      toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon
  48. 20 20
      toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon
  49. 12 12
      toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon
  50. 6 6
      toolchain/check/testdata/operators/overloaded/inc.carbon
  51. 12 12
      toolchain/check/testdata/operators/overloaded/left_shift.carbon
  52. 12 12
      toolchain/check/testdata/operators/overloaded/mod.carbon
  53. 12 12
      toolchain/check/testdata/operators/overloaded/mul.carbon
  54. 6 6
      toolchain/check/testdata/operators/overloaded/negate.carbon
  55. 35 35
      toolchain/check/testdata/operators/overloaded/ordered.carbon
  56. 12 12
      toolchain/check/testdata/operators/overloaded/right_shift.carbon
  57. 12 12
      toolchain/check/testdata/operators/overloaded/sub.carbon
  58. 8 8
      toolchain/check/testdata/packages/cross_package_import.carbon
  59. 2 2
      toolchain/check/testdata/packages/fail_conflict_no_namespaces.carbon
  60. 4 4
      toolchain/check/testdata/packages/fail_import_type_error.carbon
  61. 2 2
      toolchain/check/testdata/packages/loaded_global.carbon
  62. 1 1
      toolchain/check/testdata/packages/unused_lazy_import.carbon
  63. 2 2
      toolchain/check/testdata/pointer/import.carbon
  64. 2 2
      toolchain/check/testdata/struct/import.carbon
  65. 2 2
      toolchain/check/testdata/tuples/import.carbon
  66. 1 1
      toolchain/check/testdata/var/import.carbon
  67. 8 2
      toolchain/lower/handle.cpp
  68. 18 11
      toolchain/sem_ir/file.cpp
  69. 37 13
      toolchain/sem_ir/formatter.cpp
  70. 2 2
      toolchain/sem_ir/id_kind.h
  71. 3 1
      toolchain/sem_ir/ids.h
  72. 2 1
      toolchain/sem_ir/inst_kind.def
  73. 20 11
      toolchain/sem_ir/typed_insts.h

+ 1 - 0
toolchain/check/BUILD

@@ -84,6 +84,7 @@ cc_library(
         "//common:check",
         "//common:vlog",
         "//toolchain/base:index_base",
+        "//toolchain/base:kind_switch",
         "//toolchain/check:scope_stack",
         "//toolchain/diagnostics:diagnostic_emitter",
         "//toolchain/lex:tokenized_buffer",

+ 6 - 8
toolchain/check/check.cpp

@@ -48,24 +48,22 @@ class SemIRDiagnosticConverter : public DiagnosticConverter<SemIRLoc> {
 
     // Notes an import on the diagnostic and updates cursors to point at the
     // imported IR.
-    auto follow_import_ref = [&](SemIR::ImportIRId ir_id,
-                                 SemIR::InstId inst_id) {
-      const auto& import_ir = cursor_ir->import_irs().Get(ir_id);
+    auto follow_import_ref = [&](SemIR::ImportIRInstId import_ir_inst_id) {
+      auto import_ir_inst = cursor_ir->import_ir_insts().Get(import_ir_inst_id);
+      const auto& import_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id);
       auto context_loc = ConvertLocInFile(cursor_ir, import_ir.node_id,
                                           loc.token_only, context_fn);
       CARBON_DIAGNOSTIC(InImport, Note, "In import.");
       context_fn(context_loc, InImport);
       cursor_ir = import_ir.sem_ir;
-      cursor_inst_id = inst_id;
+      cursor_inst_id = import_ir_inst.inst_id;
     };
 
     // If the location is is an import, follows it and returns nullopt.
     // Otherwise, it's a parse node, so return the final location.
     auto handle_loc = [&](SemIR::LocId loc_id) -> std::optional<DiagnosticLoc> {
       if (loc_id.is_import_ir_inst_id()) {
-        auto import_ir_inst =
-            cursor_ir->import_ir_insts().Get(loc_id.import_ir_inst_id());
-        follow_import_ref(import_ir_inst.ir_id, import_ir_inst.inst_id);
+        follow_import_ref(loc_id.import_ir_inst_id());
         return std::nullopt;
       } else {
         // Parse nodes always refer to the current IR.
@@ -98,7 +96,7 @@ class SemIRDiagnosticConverter : public DiagnosticConverter<SemIRLoc> {
       // possible.
       if (auto import_ref = cursor_ir->insts().TryGetAs<SemIR::AnyImportRef>(
               cursor_inst_id)) {
-        follow_import_ref(import_ref->ir_id, import_ref->inst_id);
+        follow_import_ref(import_ref->import_ir_inst_id);
         continue;
       }
 

+ 20 - 15
toolchain/check/context.cpp

@@ -152,10 +152,10 @@ auto Context::ReplaceInstBeforeConstantUse(SemIR::InstId inst_id,
   constant_values().Set(inst_id, const_id);
 }
 
-auto Context::AddImportRef(SemIR::ImportIRId ir_id, SemIR::InstId inst_id)
+auto Context::AddImportRef(SemIR::ImportIRInst import_ir_inst)
     -> SemIR::InstId {
-  auto import_ref_id =
-      AddPlaceholderInstInNoBlock({SemIR::ImportRefUnused{ir_id, inst_id}});
+  auto import_ref_id = AddPlaceholderInstInNoBlock(
+      SemIR::ImportRefUnloaded{import_ir_insts().Add(import_ir_inst)});
 
   // We can't insert this instruction into whatever block we happen to be in,
   // because this function is typically called by name lookup in the middle of
@@ -337,11 +337,12 @@ static auto LookupInImportIRScopes(Context& context, SemIRLoc loc,
       // Name doesn't exist in the import scope.
       continue;
     }
-    auto import_inst_id = context.AddImportRef(import_ir_id, it->second);
+    auto import_inst_id =
+        context.AddImportRef({.ir_id = import_ir_id, .inst_id = it->second});
     if (result_id.is_valid()) {
       MergeImportRef(context, import_inst_id, result_id);
     } else {
-      TryResolveImportRefUnused(context, import_inst_id);
+      LoadImportRef(context, import_inst_id, loc);
       result_id = import_inst_id;
     }
   }
@@ -353,7 +354,7 @@ auto Context::LookupNameInExactScope(SemIRLoc loc, SemIR::NameId name_id,
                                      const SemIR::NameScope& scope)
     -> SemIR::InstId {
   if (auto it = scope.names.find(name_id); it != scope.names.end()) {
-    TryResolveImportRefUnused(*this, it->second);
+    LoadImportRef(*this, it->second, loc);
     return it->second;
   }
   if (!scope.import_ir_scopes.empty()) {
@@ -786,13 +787,16 @@ class TypeCompleter {
     llvm_unreachable("All builtin kinds were handled above");
   }
 
-  auto BuildImportRefUsedValueRepr(SemIR::TypeId type_id,
-                                   SemIR::ImportRefUsed import_ref) const
+  auto BuildAnyImportRefValueRepr(SemIR::TypeId type_id,
+                                  SemIR::AnyImportRef import_ref) const
       -> SemIR::ValueRepr {
-    const auto& import_ir = context_.import_irs().Get(import_ref.ir_id).sem_ir;
-    auto import_inst = import_ir->insts().Get(import_ref.inst_id);
-    CARBON_CHECK(import_inst.kind() != SemIR::InstKind::ImportRefUsed)
-        << "If ImportRefUsed can point at another, this would be recursive.";
+    auto import_ir_inst =
+        context_.import_ir_insts().Get(import_ref.import_ir_inst_id);
+    const auto& import_ir =
+        context_.import_irs().Get(import_ir_inst.ir_id).sem_ir;
+    auto import_inst = import_ir->insts().Get(import_ir_inst.inst_id);
+    CARBON_CHECK(!import_inst.Is<SemIR::AnyImportRef>())
+        << "If ImportRef can point at another, this would be recursive.";
     return BuildValueRepr(type_id, import_inst);
   }
 
@@ -917,7 +921,7 @@ class TypeCompleter {
       case SemIR::FieldDecl::Kind:
       case SemIR::FunctionDecl::Kind:
       case SemIR::ImplDecl::Kind:
-      case SemIR::ImportRefUnused::Kind:
+      case SemIR::ImportRefUnloaded::Kind:
       case SemIR::InitializeFrom::Kind:
       case SemIR::InterfaceDecl::Kind:
       case SemIR::InterfaceWitness::Kind:
@@ -956,9 +960,10 @@ class TypeCompleter {
         return MakePointerValueRepr(type_id, SemIR::ValueRepr::ObjectAggregate);
       }
 
+      case SemIR::ImportRefLoaded::Kind:
       case SemIR::ImportRefUsed::Kind:
-        return BuildImportRefUsedValueRepr(type_id,
-                                           inst.As<SemIR::ImportRefUsed>());
+        return BuildAnyImportRefValueRepr(type_id,
+                                          inst.As<SemIR::AnyImportRef>());
 
       case SemIR::StructType::Kind:
         return BuildStructTypeValueRepr(type_id, inst.As<SemIR::StructType>());

+ 2 - 2
toolchain/check/context.h

@@ -19,6 +19,7 @@
 #include "toolchain/parse/tree.h"
 #include "toolchain/sem_ir/file.h"
 #include "toolchain/sem_ir/ids.h"
+#include "toolchain/sem_ir/import_ir.h"
 #include "toolchain/sem_ir/inst.h"
 
 namespace Carbon::Check {
@@ -83,8 +84,7 @@ class Context {
 
   // Adds an import_ref instruction for the specified instruction in the
   // specified IR. The import_ref is initially marked as unused.
-  auto AddImportRef(SemIR::ImportIRId ir_id, SemIR::InstId inst_id)
-      -> SemIR::InstId;
+  auto AddImportRef(SemIR::ImportIRInst import_ir_inst) -> SemIR::InstId;
 
   // Sets only the parse node of an instruction. This is only used when setting
   // the parse node of an imported namespace. Versus

+ 4 - 3
toolchain/check/eval.cpp

@@ -650,6 +650,7 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
     // TODO: These need special handling.
     case SemIR::BindValue::Kind:
     case SemIR::Deref::Kind:
+    case SemIR::ImportRefLoaded::Kind:
     case SemIR::ImportRefUsed::Kind:
     case SemIR::Temporary::Kind:
     case SemIR::TemporaryStorage::Kind:
@@ -733,9 +734,9 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
     case SemIR::VarStorage::Kind:
       break;
 
-    case SemIR::ImportRefUnused::Kind:
-      CARBON_FATAL() << "ImportRefUnused should transform to ImportRefUsed "
-                        "before TryEvalInst.";
+    case SemIR::ImportRefUnloaded::Kind:
+      CARBON_FATAL()
+          << "ImportRefUnloaded should be loaded before TryEvalInst.";
   }
   return SemIR::ConstantId::NotConstant;
 }

+ 1 - 1
toolchain/check/impl.cpp

@@ -86,7 +86,7 @@ static auto BuildInterfaceWitness(
        .replacement_id = context.types().GetConstantId(impl.self_id)}};
 
   for (auto decl_id : assoc_entities) {
-    TryResolveImportRefUnused(context, decl_id);
+    LoadImportRef(context, decl_id, impl.definition_id);
     auto const_id = context.constant_values().Get(decl_id);
     CARBON_CHECK(const_id.is_constant()) << "Non-constant associated entity";
     auto decl = context.insts().Get(const_id.inst_id());

+ 6 - 4
toolchain/check/import.cpp

@@ -138,9 +138,10 @@ static auto CopySingleNameScopeFromImportIR(
     SemIR::NameId name_id) -> SemIR::NameScopeId {
   // Produce the namespace for the entry.
   auto make_import_id = [&]() {
-    return context.AddInst(SemIR::ImportRefUsed{.type_id = namespace_type_id,
-                                                .ir_id = ir_id,
-                                                .inst_id = import_inst_id});
+    auto import_ir_inst_id = context.import_ir_insts().Add(
+        {.ir_id = ir_id, .inst_id = import_inst_id});
+    return context.AddInst(SemIR::ImportRefLoaded{
+        .type_id = namespace_type_id, .import_ir_inst_id = import_ir_inst_id});
   };
   auto [namespace_scope_id, namespace_const_id, _] =
       AddNamespace(context, namespace_type_id, Parse::NodeId::Invalid, name_id,
@@ -242,7 +243,8 @@ auto ImportLibraryFromCurrentPackage(Context& context,
           import_namespace_inst->name_scope_id, enclosing_scope_id, name_id);
     } else {
       // Leave a placeholder that the inst comes from the other IR.
-      auto target_id = context.AddImportRef(ir_id, import_inst_id);
+      auto target_id =
+          context.AddImportRef({.ir_id = ir_id, .inst_id = import_inst_id});
       auto [it, success] = context.name_scopes()
                                .Get(enclosing_scope_id)
                                .names.insert({name_id, target_id});

+ 65 - 31
toolchain/check/import_ref.cpp

@@ -5,6 +5,7 @@
 #include "toolchain/check/import_ref.h"
 
 #include "common/check.h"
+#include "toolchain/base/kind_switch.h"
 #include "toolchain/check/context.h"
 #include "toolchain/check/eval.h"
 #include "toolchain/parse/node_ids.h"
@@ -328,12 +329,13 @@ class ImportRefResolver {
     }
   }
 
-  // Adds ImportRefUnused entries for members of the imported scope, for name
+  // Adds ImportRefUnloaded entries for members of the imported scope, for name
   // lookup.
   auto AddNameScopeImportRefs(const SemIR::NameScope& import_scope,
                               SemIR::NameScope& new_scope) -> void {
     for (auto [entry_name_id, entry_inst_id] : import_scope.names) {
-      auto ref_id = context_.AddImportRef(import_ir_id_, entry_inst_id);
+      auto ref_id = context_.AddImportRef(
+          {.ir_id = import_ir_id_, .inst_id = entry_inst_id});
       CARBON_CHECK(
           new_scope.names.insert({GetLocalNameId(entry_name_id), ref_id})
               .second);
@@ -353,7 +355,7 @@ class ImportRefResolver {
     new_associated_entities.reserve(associated_entities.size());
     for (auto inst_id : associated_entities) {
       new_associated_entities.push_back(
-          context_.AddImportRef(import_ir_id_, inst_id));
+          context_.AddImportRef({.ir_id = import_ir_id_, .inst_id = inst_id}));
     }
     return context_.inst_blocks().Add(new_associated_entities);
   }
@@ -445,7 +447,8 @@ class ImportRefResolver {
     }
 
     // Add a lazy reference to the target declaration.
-    auto decl_id = context_.AddImportRef(import_ir_id_, inst.decl_id);
+    auto decl_id = context_.AddImportRef(
+        {.ir_id = import_ir_id_, .inst_id = inst.decl_id});
 
     auto inst_id = context_.AddInstInNoBlock(
         {AddImportIRInst(inst.decl_id),
@@ -707,9 +710,11 @@ class ImportRefResolver {
             : SemIR::TypeId::Invalid;
     auto new_return_slot = SemIR::InstId::Invalid;
     if (function.return_slot_id.is_valid()) {
-      context_.AddInstInNoBlock({SemIR::ImportRefUsed{
+      auto import_ir_inst_id = context_.import_ir_insts().Add(
+          {.ir_id = import_ir_id_, .inst_id = function.return_slot_id});
+      context_.AddInstInNoBlock({SemIR::ImportRefLoaded{
           context_.GetTypeIdForTypeConstant(return_slot_const_id),
-          import_ir_id_, function.return_slot_id}});
+          import_ir_inst_id}});
     }
     function_decl.function_id = context_.functions().Add(
         {.name_id = GetLocalNameId(function.name_id),
@@ -919,32 +924,61 @@ class ImportRefResolver {
   llvm::SmallVector<Work> work_stack_;
 };
 
-auto TryResolveImportRefUnused(Context& context, SemIR::InstId inst_id)
+// Returns the LocId corresponding to the input location.
+static auto SemIRLocToLocId(Context& context, SemIRLoc loc) -> SemIR::LocId {
+  if (loc.is_inst_id) {
+    return context.insts().GetLocId(loc.inst_id);
+  } else {
+    return loc.loc_id;
+  }
+}
+
+// Replace the ImportRefUnloaded instruction with an appropriate ImportRef. This
+// doesn't use ReplaceInstBeforeConstantUse because it would trigger
+// TryEvalInst, which we want to avoid with ImportRefs.
+static auto SetInst(Context& context, SemIR::InstId inst_id,
+                    SemIR::TypeId type_id,
+                    SemIR::ImportIRInstId import_ir_inst_id, SemIRLoc loc,
+                    bool set_if_invalid_loc) -> void {
+  if (auto loc_id = SemIRLocToLocId(context, loc); loc_id.is_valid()) {
+    context.sem_ir().insts().Set(
+        inst_id, SemIR::ImportRefUsed{type_id, import_ir_inst_id, loc_id});
+  } else if (set_if_invalid_loc) {
+    context.sem_ir().insts().Set(
+        inst_id, SemIR::ImportRefLoaded{type_id, import_ir_inst_id});
+  }
+}
+
+auto LoadImportRef(Context& context, SemIR::InstId inst_id, SemIRLoc loc)
     -> void {
-  auto inst = context.insts().Get(inst_id);
-  auto import_ref = inst.TryAs<SemIR::ImportRefUnused>();
-  if (!import_ref) {
-    return;
-  }
-
-  const SemIR::File& import_ir =
-      *context.import_irs().Get(import_ref->ir_id).sem_ir;
-  auto import_inst = import_ir.insts().Get(import_ref->inst_id);
-
-  ImportRefResolver resolver(context, import_ref->ir_id);
-  auto type_id = resolver.ResolveType(import_inst.type_id());
-  auto constant_id = resolver.Resolve(import_ref->inst_id);
-
-  // Replace the ImportRefUnused instruction with an ImportRefUsed. This doesn't
-  // use ReplaceInstBeforeConstantUse because it would trigger TryEvalInst, and
-  // we're instead doing constant evaluation here in order to minimize recursion
-  // risks.
-  context.sem_ir().insts().Set(
-      inst_id,
-      SemIR::ImportRefUsed{type_id, import_ref->ir_id, import_ref->inst_id});
-
-  // Store the constant for both the ImportRefUsed and imported instruction.
-  context.constant_values().Set(inst_id, constant_id);
+  CARBON_KIND_SWITCH(context.insts().Get(inst_id)) {
+    case CARBON_KIND(SemIR::ImportRefLoaded inst): {
+      SetInst(context, inst_id, inst.type_id, inst.import_ir_inst_id, loc,
+              /*set_if_invalid_loc=*/false);
+      return;
+    }
+    case CARBON_KIND(SemIR::ImportRefUnloaded inst): {
+      auto import_ir_inst =
+          context.import_ir_insts().Get(inst.import_ir_inst_id);
+
+      const SemIR::File& import_ir =
+          *context.import_irs().Get(import_ir_inst.ir_id).sem_ir;
+      auto import_inst = import_ir.insts().Get(import_ir_inst.inst_id);
+
+      ImportRefResolver resolver(context, import_ir_inst.ir_id);
+      auto type_id = resolver.ResolveType(import_inst.type_id());
+      auto constant_id = resolver.Resolve(import_ir_inst.inst_id);
+
+      SetInst(context, inst_id, type_id, inst.import_ir_inst_id, loc,
+              /*set_if_invalid_loc=*/true);
+
+      // Store the constant for both the ImportRefUsed and imported instruction.
+      context.constant_values().Set(inst_id, constant_id);
+      return;
+    }
+    default:
+      return;
+  }
 }
 
 }  // namespace Carbon::Check

+ 4 - 3
toolchain/check/import_ref.h

@@ -10,9 +10,10 @@
 
 namespace Carbon::Check {
 
-// If the passed in instruction ID is a ImportRefUnused, resolves it for use.
-// Otherwise, errors.
-auto TryResolveImportRefUnused(Context& context, SemIR::InstId inst_id) -> void;
+// If the passed in instruction ID is an ImportRefUnloaded, loads it for use.
+// The result will be an ImportRefUsed.
+auto LoadImportRef(Context& context, SemIR::InstId inst_id, SemIRLoc loc)
+    -> void;
 
 }  // namespace Carbon::Check
 

+ 4 - 4
toolchain/check/merge.cpp

@@ -15,13 +15,13 @@ static auto ResolveMergeableInst(Context& context, SemIR::InstId inst_id)
     -> std::optional<SemIR::Inst> {
   auto inst = context.insts().Get(inst_id);
   switch (inst.kind()) {
-    case SemIR::ImportRefUnused::Kind:
-      // Resolve before merging.
-      TryResolveImportRefUnused(context, inst_id);
+    case SemIR::ImportRefUnloaded::Kind:
+      // Load before merging.
+      LoadImportRef(context, inst_id, SemIR::LocId::Invalid);
       break;
 
     case SemIR::ImportRefUsed::Kind:
-      // Already resolved.
+      // Already loaded.
       break;
 
     case SemIR::Namespace::Kind:

+ 2 - 2
toolchain/check/testdata/alias/import.carbon

@@ -52,8 +52,8 @@ var c: i32 = b;
 // CHECK:STDOUT:     .b = %import_ref.2
 // CHECK:STDOUT:     .c = %c
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.2: ref i32 = import_ref ir1, inst+7, used
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.2: ref i32 = import_ref ir1, inst+7, loc_14
 // CHECK:STDOUT:   %c.var: ref i32 = var c
 // CHECK:STDOUT:   %c: ref i32 = bind_name c, %c.var
 // CHECK:STDOUT: }

+ 4 - 4
toolchain/check/testdata/alias/import_order.carbon

@@ -62,10 +62,10 @@ var i32_val: i32 = a_val;
 // CHECK:STDOUT:     .a_val = %a_val
 // CHECK:STDOUT:     .i32_val = %i32_val
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = i32]
-// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+3, used [template = i32]
-// CHECK:STDOUT:   %import_ref.3: type = import_ref ir1, inst+5, used [template = i32]
-// CHECK:STDOUT:   %import_ref.4: type = import_ref ir1, inst+7, used [template = i32]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_32 [template = i32]
+// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+3, loc_25 [template = i32]
+// CHECK:STDOUT:   %import_ref.3: type = import_ref ir1, inst+5, loc_18 [template = i32]
+// CHECK:STDOUT:   %import_ref.4: type = import_ref ir1, inst+7, loc_11 [template = i32]
 // CHECK:STDOUT:   %d.ref: type = name_ref d, %import_ref.4 [template = i32]
 // CHECK:STDOUT:   %d_val.var: ref i32 = var d_val
 // CHECK:STDOUT:   %d_val: ref i32 = bind_name d_val, %d_val.var

+ 10 - 10
toolchain/check/testdata/basics/builtin_insts.carbon

@@ -19,16 +19,16 @@
 // CHECK:STDOUT:     type0:           {constant: template instNamespaceType, value_rep: {kind: copy, type: type0}}
 // CHECK:STDOUT:   type_blocks:     {}
 // CHECK:STDOUT:   insts:
-// CHECK:STDOUT:     instTypeType:    {kind: ImportRefUsed, arg0: ir0, arg1: instTypeType, type: typeTypeType}
-// CHECK:STDOUT:     instError:       {kind: ImportRefUsed, arg0: ir0, arg1: instError, type: typeError}
-// CHECK:STDOUT:     instBoolType:    {kind: ImportRefUsed, arg0: ir0, arg1: instBoolType, type: typeTypeType}
-// CHECK:STDOUT:     instIntType:     {kind: ImportRefUsed, arg0: ir0, arg1: instIntType, type: typeTypeType}
-// CHECK:STDOUT:     instFloatType:   {kind: ImportRefUsed, arg0: ir0, arg1: instFloatType, type: typeTypeType}
-// CHECK:STDOUT:     instStringType:  {kind: ImportRefUsed, arg0: ir0, arg1: instStringType, type: typeTypeType}
-// CHECK:STDOUT:     instFunctionType: {kind: ImportRefUsed, arg0: ir0, arg1: instFunctionType, type: typeTypeType}
-// CHECK:STDOUT:     instBoundMethodType: {kind: ImportRefUsed, arg0: ir0, arg1: instBoundMethodType, type: typeTypeType}
-// CHECK:STDOUT:     instNamespaceType: {kind: ImportRefUsed, arg0: ir0, arg1: instNamespaceType, type: typeTypeType}
-// CHECK:STDOUT:     instWitnessType: {kind: ImportRefUsed, arg0: ir0, arg1: instWitnessType, type: typeTypeType}
+// CHECK:STDOUT:     instTypeType:    {kind: ImportRefLoaded, arg0: 0, type: typeTypeType}
+// CHECK:STDOUT:     instError:       {kind: ImportRefLoaded, arg0: 1, type: typeError}
+// CHECK:STDOUT:     instBoolType:    {kind: ImportRefLoaded, arg0: 2, type: typeTypeType}
+// CHECK:STDOUT:     instIntType:     {kind: ImportRefLoaded, arg0: 3, type: typeTypeType}
+// CHECK:STDOUT:     instFloatType:   {kind: ImportRefLoaded, arg0: 4, type: typeTypeType}
+// CHECK:STDOUT:     instStringType:  {kind: ImportRefLoaded, arg0: 5, type: typeTypeType}
+// CHECK:STDOUT:     instFunctionType: {kind: ImportRefLoaded, arg0: 6, type: typeTypeType}
+// CHECK:STDOUT:     instBoundMethodType: {kind: ImportRefLoaded, arg0: 7, type: typeTypeType}
+// CHECK:STDOUT:     instNamespaceType: {kind: ImportRefLoaded, arg0: 8, type: typeTypeType}
+// CHECK:STDOUT:     instWitnessType: {kind: ImportRefLoaded, arg0: 9, type: typeTypeType}
 // CHECK:STDOUT:     inst+0:          {kind: Namespace, arg0: name_scope0, arg1: inst<invalid>, type: type0}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     instTypeType:    template instTypeType

+ 9 - 9
toolchain/check/testdata/class/cross_package_import.carbon

@@ -165,9 +165,9 @@ var c: Other.C = {};
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%C]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_14 [template = constants.%C]
 // CHECK:STDOUT:   %C.decl: invalid = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unloaded
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref C = var c
 // CHECK:STDOUT:   %c: ref C = bind_name c, %c.var
@@ -201,7 +201,7 @@ var c: Other.C = {};
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, used [template = constants.%C]
+// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, loc_14 [template = constants.%C]
 // CHECK:STDOUT:   %C.decl: invalid = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref <error> = var c
@@ -235,10 +235,10 @@ var c: Other.C = {};
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%C.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_19 [template = constants.%C.1]
 // CHECK:STDOUT:   %C.decl.1: invalid = class_decl @C.1 [template = constants.%C.1] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.3: type = import_ref ir2, inst+1, used [template = constants.%C.2]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.3: type = import_ref ir2, inst+1, loaded [template = constants.%C.2]
 // CHECK:STDOUT:   %C.decl.2: invalid = class_decl @C.2 [template = constants.%C.2] {}
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C.1]
 // CHECK:STDOUT:   %c.var: ref C = var c
@@ -278,10 +278,10 @@ var c: Other.C = {};
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, %Other [template = %Other]
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%C]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_19 [template = constants.%C]
 // CHECK:STDOUT:   %C.decl: invalid = class_decl @C.2 [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir2, inst+1, used [template = imports.%C]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir2, inst+1, loaded [template = imports.%C]
 // CHECK:STDOUT:   %C.ref: type = name_ref C, %import_ref.1 [template = constants.%C]
 // CHECK:STDOUT:   %c.var: ref C = var c
 // CHECK:STDOUT:   %c: ref C = bind_name c, %c.var

+ 3 - 3
toolchain/check/testdata/class/fail_import_misuses.carbon

@@ -82,9 +82,9 @@ var a: Incomplete;
 // CHECK:STDOUT:     .Incomplete = %import_ref.2
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%Empty]
-// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+4, used [template = constants.%Incomplete]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_10 [template = constants.%Empty]
+// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+4, loc_15 [template = constants.%Incomplete]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+2, unloaded
 // CHECK:STDOUT:   %.decl: type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %Empty.decl: invalid = class_decl @Empty [template = constants.%Empty] {}
 // CHECK:STDOUT:   }

+ 1 - 1
toolchain/check/testdata/class/fail_todo_import_forward_decl.carbon

@@ -56,7 +56,7 @@ class ForwardDecl {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .ForwardDecl = %import_ref
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, used [template = constants.%ForwardDecl]
+// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, loc_10 [template = constants.%ForwardDecl]
 // CHECK:STDOUT:   %.decl: type = class_decl @.1 [template = constants.%.1] {
 // CHECK:STDOUT:     %ForwardDecl.decl: invalid = class_decl @ForwardDecl [template = constants.%ForwardDecl] {}
 // CHECK:STDOUT:   }

+ 13 - 13
toolchain/check/testdata/class/import.carbon

@@ -142,20 +142,20 @@ fn Run() {
 // CHECK:STDOUT:     .Incomplete = %import_ref.4
 // CHECK:STDOUT:     .Run = %Run
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%Empty]
-// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+4, used [template = constants.%Field]
-// CHECK:STDOUT:   %import_ref.3: type = import_ref ir1, inst+11, used [template = constants.%ForwardDeclared.1]
-// CHECK:STDOUT:   %import_ref.4: type = import_ref ir1, inst+25, used [template = constants.%Incomplete]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_16 [template = constants.%Empty]
+// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+4, loc_24 [template = constants.%Field]
+// CHECK:STDOUT:   %import_ref.3: type = import_ref ir1, inst+11, loc_42 [template = constants.%ForwardDeclared.1]
+// CHECK:STDOUT:   %import_ref.4: type = import_ref ir1, inst+25, loc_71 [template = constants.%Incomplete]
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+5, unused
-// CHECK:STDOUT:   %import_ref.7: <unbound element of class Field> = import_ref ir1, inst+7, used [template = imports.%.1]
-// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+12, unused
-// CHECK:STDOUT:   %import_ref.9: <function> = import_ref ir1, inst+24, used [template = imports.%G]
-// CHECK:STDOUT:   %import_ref.10: <function> = import_ref ir1, inst+17, used [template = imports.%F]
-// CHECK:STDOUT:   %import_ref.11 = import_ref ir1, inst+12, unused
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.13 = import_ref ir1, inst+17, unused
+// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+5, unloaded
+// CHECK:STDOUT:   %import_ref.7: <unbound element of class Field> = import_ref ir1, inst+7, loc_36 [template = imports.%.1]
+// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+12, unloaded
+// CHECK:STDOUT:   %import_ref.9: <function> = import_ref ir1, inst+24, loc_56 [template = imports.%G]
+// CHECK:STDOUT:   %import_ref.10: <function> = import_ref ir1, inst+17, loc_50 [template = imports.%F]
+// CHECK:STDOUT:   %import_ref.11 = import_ref ir1, inst+12, unloaded
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.13 = import_ref ir1, inst+17, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Empty {

+ 9 - 9
toolchain/check/testdata/class/import_base.carbon

@@ -116,16 +116,16 @@ fn Run() {
 // CHECK:STDOUT:     .Child = %import_ref.2
 // CHECK:STDOUT:     .Run = %Run
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
-// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+19, used [template = constants.%Child]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unloaded
+// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+19, loc_16 [template = constants.%Child]
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+6, used [template = imports.%F]
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.5: <unbound element of class Base> = import_ref ir1, inst+12, used [template = imports.%.1]
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+10, unused
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+20, unused
-// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+24, unused
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+6, loc_44 [template = imports.%F]
+// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.5: <unbound element of class Base> = import_ref ir1, inst+12, loc_38 [template = imports.%.1]
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+10, unloaded
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+15, unloaded
+// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+20, unloaded
+// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+24, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Child {

+ 3 - 3
toolchain/check/testdata/class/import_member_cycle.carbon

@@ -61,10 +61,10 @@ fn Run() {
 // CHECK:STDOUT:     .Cycle = %import_ref.1
 // CHECK:STDOUT:     .Run = %Run
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%Cycle]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_16 [template = constants.%Cycle]
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+7, unused
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+7, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+2, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Cycle {

+ 4 - 4
toolchain/check/testdata/class/import_struct_cyle.carbon

@@ -79,11 +79,11 @@ fn Run() {
 // CHECK:STDOUT:     .a = %import_ref.2
 // CHECK:STDOUT:     .Run = %Run
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
-// CHECK:STDOUT:   %import_ref.2: ref {.b: Cycle*} = import_ref ir1, inst+11, used
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unloaded
+// CHECK:STDOUT:   %import_ref.2: ref {.b: Cycle*} = import_ref ir1, inst+11, loc_14
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.4: <unbound element of class Cycle> = import_ref ir1, inst+18, used [template = imports.%.1]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.4: <unbound element of class Cycle> = import_ref ir1, inst+18, loc_24 [template = imports.%.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Cycle {

+ 3 - 3
toolchain/check/testdata/const/import.carbon

@@ -76,9 +76,9 @@ var a_ptr: const i32* = a_ptr_ref;
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:     .a_ptr = %a_ptr
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+4, unused
-// CHECK:STDOUT:   %import_ref.2: ref const i32 = import_ref ir1, inst+7, used
-// CHECK:STDOUT:   %import_ref.3: ref const i32* = import_ref ir1, inst+15, used
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+4, unloaded
+// CHECK:STDOUT:   %import_ref.2: ref const i32 = import_ref ir1, inst+7, loc_12
+// CHECK:STDOUT:   %import_ref.3: ref const i32* = import_ref ir1, inst+15, loc_22
 // CHECK:STDOUT:   %.loc6_8: type = const_type i32 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc6_17: type = ptr_type const i32 [template = constants.%.2]
 // CHECK:STDOUT:   %a.var: ref const i32* = var a

+ 7 - 7
toolchain/check/testdata/function/builtin/call_from_operator.carbon

@@ -94,10 +94,10 @@ var arr: [i32; 1 + 2] = (3, 4, 3 + 4);
 // CHECK:STDOUT:     .arr = %arr
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.1]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Add> = import_ref ir1, inst+20, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_9 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Add> = import_ref ir1, inst+20, loc_36 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_10 [template = imports.%Op]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Add.decl: invalid = interface_decl @Add [template = constants.%.1] {}
@@ -105,15 +105,15 @@ var arr: [i32; 1 + 2] = (3, 4, 3 + 4);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1 [template = constants.%.3]
 // CHECK:STDOUT:   %.loc10_20: i32 = int_literal 2 [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, used [template = constants.%.1]
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, loc_36 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Op]
 // CHECK:STDOUT:   %.loc10_18.1: <bound method> = bound_method %.loc10_16, %.1 [template = constants.%.7]
 // CHECK:STDOUT:   %.loc10_18.2: init i32 = call %.loc10_18.1(%.loc10_16, %.loc10_20) [template = constants.%.8]
 // CHECK:STDOUT:   %.loc10_21: type = array_type %.loc10_18.2, i32 [template = constants.%.9]
 // CHECK:STDOUT:   %arr.var: ref [i32; 3] = var arr
 // CHECK:STDOUT:   %arr: ref [i32; 3] = bind_name arr, %arr.var
-// CHECK:STDOUT:   %import_ref.7: type = import_ref ir1, inst+1, used [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.7: type = import_ref ir1, inst+1, loc_47 [template = constants.%.1]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Add {

+ 1 - 1
toolchain/check/testdata/function/builtin/import.carbon

@@ -53,7 +53,7 @@ var arr: [i32; Core.Add(1, 2)] = (1, 2, 3);
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+6, used [template = imports.%Add]
+// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+6, loc_11 [template = imports.%Add]
 // CHECK:STDOUT:   %Add.ref: <function> = name_ref Add, %import_ref [template = imports.%Add]
 // CHECK:STDOUT:   %.loc4_25: i32 = int_literal 1 [template = constants.%.1]
 // CHECK:STDOUT:   %.loc4_28: i32 = int_literal 2 [template = constants.%.2]

+ 117 - 28
toolchain/check/testdata/function/declaration/import.carbon

@@ -97,6 +97,25 @@ var b: i32 = B(1);
 var c: {.c: i32} = C((1,));
 var d: () = D();
 
+// --- unloaded.carbon
+
+library "unloaded" api;
+
+import library "api";
+
+// --- unloaded_extern.carbon
+
+library "unloaded_extern" api;
+
+import library "extern_api";
+
+// --- loaded_merge.carbon
+
+library "loaded_merge" api;
+
+import library "api";
+import library "extern_api";
+
 // CHECK:STDOUT: --- api.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
@@ -198,10 +217,10 @@ var d: () = D();
 // CHECK:STDOUT:     .c = %c
 // CHECK:STDOUT:     .d = %d
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%A]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, used [template = imports.%B]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, used [template = imports.%C]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%D]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_15 [template = imports.%A]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, loc_24 [template = imports.%B]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, loc_39 [template = imports.%C]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_53 [template = imports.%D]
 // CHECK:STDOUT:   %.loc6_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc6_9.2: type = converted %.loc6_9.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref () = var a
@@ -269,10 +288,10 @@ var d: () = D();
 // CHECK:STDOUT:     .c = %c.loc13
 // CHECK:STDOUT:     .d = %d
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%A]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, used [template = imports.%B]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, used [template = imports.%C]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%D]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_11 [template = imports.%A]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, loc_17 [template = imports.%B]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, loc_28 [template = imports.%C]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_47 [template = imports.%D]
 // CHECK:STDOUT:   %A: <function> = fn_decl @A [template] {}
 // CHECK:STDOUT:   %B: <function> = fn_decl @B [template] {
 // CHECK:STDOUT:     %b.loc7_13.1: i32 = param b
@@ -355,10 +374,10 @@ var d: () = D();
 // CHECK:STDOUT:     .c = %c.loc13
 // CHECK:STDOUT:     .d = %d
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%A]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, used [template = imports.%B]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, used [template = imports.%C]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%D]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_11 [template = imports.%A]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, loc_17 [template = imports.%B]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, loc_28 [template = imports.%C]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_47 [template = imports.%D]
 // CHECK:STDOUT:   %A: <function> = fn_decl @A [template] {}
 // CHECK:STDOUT:   %B: <function> = fn_decl @B [template] {
 // CHECK:STDOUT:     %b.loc7_13.1: i32 = param b
@@ -440,14 +459,14 @@ var d: () = D();
 // CHECK:STDOUT:     .c = %c
 // CHECK:STDOUT:     .d = %d
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%A.1]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, used [template = imports.%B.1]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, used [template = imports.%C.1]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%D.1]
-// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir2, inst+1, used [template = imports.%A.2]
-// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir2, inst+5, used [template = imports.%B.2]
-// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir2, inst+17, used [template = imports.%C.2]
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir2, inst+18, used [template = imports.%D.2]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_19 [template = imports.%A.1]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, loc_28 [template = imports.%B.1]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, loc_43 [template = imports.%C.1]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_57 [template = imports.%D.1]
+// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir2, inst+1, loaded [template = imports.%A.2]
+// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir2, inst+5, loaded [template = imports.%B.2]
+// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir2, inst+17, loaded [template = imports.%C.2]
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir2, inst+18, loaded [template = imports.%D.2]
 // CHECK:STDOUT:   %.loc7_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc7_9.2: type = converted %.loc7_9.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:   %a.var: ref () = var a
@@ -522,14 +541,14 @@ var d: () = D();
 // CHECK:STDOUT:     .c = %c
 // CHECK:STDOUT:     .d = %d
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%A.1]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, used [template = imports.%B.1]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, used [template = imports.%C.1]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%D.1]
-// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir2, inst+1, used [template = imports.%A.2]
-// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir2, inst+5, used [template = imports.%B.2]
-// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir2, inst+17, used [template = imports.%C.2]
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir2, inst+18, used [template = imports.%D.2]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_19 [template = imports.%A.1]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, loc_28 [template = imports.%B.1]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, loc_43 [template = imports.%C.1]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_57 [template = imports.%D.1]
+// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir2, inst+1, loaded [template = imports.%A.2]
+// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir2, inst+5, loaded [template = imports.%B.2]
+// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir2, inst+17, loaded [template = imports.%C.2]
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir2, inst+18, loaded [template = imports.%D.2]
 // CHECK:STDOUT:   %.loc7_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc7_9.2: type = converted %.loc7_9.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:   %a.var: ref () = var a
@@ -583,3 +602,73 @@ var d: () = D();
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: --- unloaded.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .A = %import_ref.1
+// CHECK:STDOUT:     .B = %import_ref.2
+// CHECK:STDOUT:     .C = %import_ref.3
+// CHECK:STDOUT:     .D = %import_ref.4
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unloaded
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+5, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+17, unloaded
+// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+18, unloaded
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- unloaded_extern.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .A = %import_ref.1
+// CHECK:STDOUT:     .B = %import_ref.2
+// CHECK:STDOUT:     .C = %import_ref.3
+// CHECK:STDOUT:     .D = %import_ref.4
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unloaded
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+5, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+17, unloaded
+// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+18, unloaded
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: --- loaded_merge.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %.1: type = tuple_type (i32) [template]
+// CHECK:STDOUT:   %.2: type = struct_type {.c: i32} [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {
+// CHECK:STDOUT:   package: <namespace> = namespace [template] {
+// CHECK:STDOUT:     .A = %import_ref.1
+// CHECK:STDOUT:     .B = %import_ref.2
+// CHECK:STDOUT:     .C = %import_ref.3
+// CHECK:STDOUT:     .D = %import_ref.4
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loaded [template = imports.%A.1]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+5, loaded [template = imports.%B.1]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, loaded [template = imports.%C.1]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loaded [template = imports.%D.1]
+// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir2, inst+1, loaded [template = imports.%A.2]
+// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir2, inst+5, loaded [template = imports.%B.2]
+// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir2, inst+17, loaded [template = imports.%C.2]
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir2, inst+18, loaded [template = imports.%D.2]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: extern fn @A.1();
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @A.2();
+// CHECK:STDOUT:
+// CHECK:STDOUT: extern fn @B.1(%b: i32) -> i32;
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @B.2(%b: i32) -> i32;
+// CHECK:STDOUT:
+// CHECK:STDOUT: extern fn @C.1(%c: (i32,)) -> {.c: i32};
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @C.2(%c: (i32,)) -> {.c: i32};
+// CHECK:STDOUT:
+// CHECK:STDOUT: extern fn @D.1();
+// CHECK:STDOUT:
+// CHECK:STDOUT: extern fn @D.2();
+// CHECK:STDOUT:

+ 12 - 12
toolchain/check/testdata/function/definition/import.carbon

@@ -155,10 +155,10 @@ fn D() {}
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:     .c = %c
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%A]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+6, used [template = imports.%B]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+20, used [template = imports.%C]
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_15 [template = imports.%A]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+6, loc_24 [template = imports.%B]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+20, loc_39 [template = imports.%C]
+// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT:   %.loc6_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc6_9.2: type = converted %.loc6_9.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref () = var a
@@ -204,10 +204,10 @@ fn D() {}
 // CHECK:STDOUT:     .C = %import_ref.3
 // CHECK:STDOUT:     .D = %import_ref.4
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%A]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+6, used [template = imports.%B]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+20, unused
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_10 [template = imports.%A]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+6, loc_17 [template = imports.%B]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+20, unloaded
+// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT:   %A: <function> = fn_decl @A [template] {}
 // CHECK:STDOUT:   %B: <function> = fn_decl @B [template] {
 // CHECK:STDOUT:     %b.loc27_6.1: i32 = param b
@@ -232,10 +232,10 @@ fn D() {}
 // CHECK:STDOUT:     .C = %import_ref.3
 // CHECK:STDOUT:     .D = %import_ref.4
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+6, unused
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+20, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+30, used [template = imports.%D]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unloaded
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+6, unloaded
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+20, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+30, loc_11 [template = imports.%D]
 // CHECK:STDOUT:   %D.loc6: <function> = fn_decl @D [template] {}
 // CHECK:STDOUT:   %D.loc16: <function> = fn_decl @D [template] {}
 // CHECK:STDOUT: }

+ 19 - 19
toolchain/check/testdata/interface/import.carbon

@@ -154,33 +154,33 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:     .UseForwardDeclaredF = %UseForwardDeclaredF
 // CHECK:STDOUT:     .f = %f.loc16
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.1]
-// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+4, used [template = constants.%.3]
-// CHECK:STDOUT:   %import_ref.3: type = import_ref ir1, inst+15, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.4: ref {.f: ForwardDeclared} = import_ref ir1, inst+36, used
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+3, unused
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_13 [template = constants.%.1]
+// CHECK:STDOUT:   %import_ref.2: type = import_ref ir1, inst+4, loc_22 [template = constants.%.3]
+// CHECK:STDOUT:   %import_ref.3: type = import_ref ir1, inst+15, loc_31 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.4: ref {.f: ForwardDeclared} = import_ref ir1, inst+36, loc_70
+// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+3, unloaded
 // CHECK:STDOUT:   %UseEmpty: <function> = fn_decl @UseEmpty [template] {
 // CHECK:STDOUT:     %Empty.decl: invalid = interface_decl @Empty [template = constants.%.1] {}
 // CHECK:STDOUT:     %Empty.ref: type = name_ref Empty, %import_ref.1 [template = constants.%.1]
 // CHECK:STDOUT:     %e.loc6_13.1: Empty = param e
 // CHECK:STDOUT:     @UseEmpty.%e: Empty = bind_name e, %e.loc6_13.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+6, unused
-// CHECK:STDOUT:   %import_ref.7: <associated <function> in Basic> = import_ref ir1, inst+13, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.8: <associated type in Basic> = import_ref ir1, inst+9, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+7, unused
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+11, unused
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+6, unloaded
+// CHECK:STDOUT:   %import_ref.7: <associated <function> in Basic> = import_ref ir1, inst+13, loc_48 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.8: <associated type in Basic> = import_ref ir1, inst+9, loc_41 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+7, unloaded
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+11, unloaded
 // CHECK:STDOUT:   %UseBasic: <function> = fn_decl @UseBasic [template] {
 // CHECK:STDOUT:     %Basic.decl: invalid = interface_decl @Basic [template = constants.%.3] {}
 // CHECK:STDOUT:     %Basic.ref.loc7: type = name_ref Basic, %import_ref.2 [template = constants.%.3]
 // CHECK:STDOUT:     %e.loc7_13.1: Basic = param e
 // CHECK:STDOUT:     @UseBasic.%e: Basic = bind_name e, %e.loc7_13.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11 = import_ref ir1, inst+18, unused
-// CHECK:STDOUT:   %import_ref.12: <associated <function> in ForwardDeclared> = import_ref ir1, inst+25, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.13: <associated type in ForwardDeclared> = import_ref ir1, inst+21, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.14 = import_ref ir1, inst+19, unused
-// CHECK:STDOUT:   %import_ref.15 = import_ref ir1, inst+23, unused
+// CHECK:STDOUT:   %import_ref.11 = import_ref ir1, inst+18, unloaded
+// CHECK:STDOUT:   %import_ref.12: <associated <function> in ForwardDeclared> = import_ref ir1, inst+25, loc_62 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.13: <associated type in ForwardDeclared> = import_ref ir1, inst+21, loc_55 [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.14 = import_ref ir1, inst+19, unloaded
+// CHECK:STDOUT:   %import_ref.15 = import_ref ir1, inst+23, unloaded
 // CHECK:STDOUT:   %UseForwardDeclared: <function> = fn_decl @UseForwardDeclared [template] {
 // CHECK:STDOUT:     %ForwardDeclared.decl: invalid = interface_decl @ForwardDeclared [template = constants.%.4] {}
 // CHECK:STDOUT:     %ForwardDeclared.ref.loc8: type = name_ref ForwardDeclared, %import_ref.3 [template = constants.%.4]
@@ -188,19 +188,19 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:     @UseForwardDeclared.%f: ForwardDeclared = bind_name f, %f.loc8_23.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Basic.ref.loc10: type = name_ref Basic, %import_ref.2 [template = constants.%.3]
-// CHECK:STDOUT:   %import_ref.16 = import_ref ir1, inst+7, unused
+// CHECK:STDOUT:   %import_ref.16 = import_ref ir1, inst+7, unloaded
 // CHECK:STDOUT:   %T.ref.loc10: <associated type in Basic> = name_ref T, %import_ref.8 [template = constants.%.6]
 // CHECK:STDOUT:   %UseBasicT: <associated type in Basic> = bind_alias UseBasicT, %import_ref.8 [template = constants.%.6]
 // CHECK:STDOUT:   %Basic.ref.loc11: type = name_ref Basic, %import_ref.2 [template = constants.%.3]
-// CHECK:STDOUT:   %import_ref.17 = import_ref ir1, inst+11, unused
+// CHECK:STDOUT:   %import_ref.17 = import_ref ir1, inst+11, unloaded
 // CHECK:STDOUT:   %F.ref.loc11: <associated <function> in Basic> = name_ref F, %import_ref.7 [template = constants.%.8]
 // CHECK:STDOUT:   %UseBasicF: <associated <function> in Basic> = bind_alias UseBasicF, %import_ref.7 [template = constants.%.8]
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc13: type = name_ref ForwardDeclared, %import_ref.3 [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.18 = import_ref ir1, inst+19, unused
+// CHECK:STDOUT:   %import_ref.18 = import_ref ir1, inst+19, unloaded
 // CHECK:STDOUT:   %T.ref.loc13: <associated type in ForwardDeclared> = name_ref T, %import_ref.13 [template = constants.%.10]
 // CHECK:STDOUT:   %UseForwardDeclaredT: <associated type in ForwardDeclared> = bind_alias UseForwardDeclaredT, %import_ref.13 [template = constants.%.10]
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc14: type = name_ref ForwardDeclared, %import_ref.3 [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.19 = import_ref ir1, inst+23, unused
+// CHECK:STDOUT:   %import_ref.19 = import_ref ir1, inst+23, unloaded
 // CHECK:STDOUT:   %F.ref.loc14: <associated <function> in ForwardDeclared> = name_ref F, %import_ref.12 [template = constants.%.12]
 // CHECK:STDOUT:   %UseForwardDeclaredF: <associated <function> in ForwardDeclared> = bind_alias UseForwardDeclaredF, %import_ref.12 [template = constants.%.12]
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc16: type = name_ref ForwardDeclared, %import_ref.3 [template = constants.%.4]

+ 1 - 1
toolchain/check/testdata/let/fail_generic_import.carbon

@@ -37,7 +37,7 @@ let a: T = 0;
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .T = %import_ref
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, used [symbolic = <unexpected instref inst+2>]
+// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, loc_7 [symbolic = <unexpected instref inst+2>]
 // CHECK:STDOUT:   %T.ref: type = name_ref T, %import_ref [symbolic = <unexpected instref inst+2>]
 // CHECK:STDOUT:   %.loc8: i32 = int_literal 0 [template = constants.%.1]
 // CHECK:STDOUT:   %a: T = bind_name a, <error>

+ 1 - 1
toolchain/check/testdata/let/generic_import.carbon

@@ -36,7 +36,7 @@ var b: T = *a;
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, used [symbolic = <unexpected instref inst+2>]
+// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, loc_7 [symbolic = <unexpected instref inst+2>]
 // CHECK:STDOUT:   %T.ref.loc4: type = name_ref T, %import_ref [symbolic = <unexpected instref inst+2>]
 // CHECK:STDOUT:   %.loc4: type = ptr_type T [symbolic = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref T* = var a

+ 1 - 1
toolchain/check/testdata/let/import.carbon

@@ -34,7 +34,7 @@ let b:! bool = a;
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .a = %import_ref
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: bool = import_ref ir1, inst+1, used [symbolic = <unexpected instref inst+3>]
+// CHECK:STDOUT:   %import_ref: bool = import_ref ir1, inst+1, loc_10 [symbolic = <unexpected instref inst+3>]
 // CHECK:STDOUT:   %a.ref: bool = name_ref a, %import_ref [symbolic = <unexpected instref inst+3>]
 // CHECK:STDOUT:   %b: bool = bind_symbolic_name b, %a.ref [symbolic]
 // CHECK:STDOUT: }

+ 1 - 1
toolchain/check/testdata/namespace/add_to_import.carbon

@@ -38,7 +38,7 @@ var a: i32 = NS.A();
 // CHECK:STDOUT:     .NS = %NS
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %NS: <namespace> = namespace %import_ref, [template] {
 // CHECK:STDOUT:     .A = %A
 // CHECK:STDOUT:   }

+ 1 - 1
toolchain/check/testdata/namespace/fail_conflict_after_merge.carbon

@@ -56,7 +56,7 @@ fn NS();
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .NS = %NS
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %NS: <namespace> = namespace %import_ref, [template] {}
 // CHECK:STDOUT:   %.loc8: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %.loc17: <function> = fn_decl @.1 [template] {}

+ 1 - 1
toolchain/check/testdata/namespace/fail_conflict_imported_namespace_first.carbon

@@ -44,7 +44,7 @@ fn NS.Foo();
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .NS = %NS
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %NS: <namespace> = namespace %import_ref, [template] {
 // CHECK:STDOUT:     .Foo = %Foo
 // CHECK:STDOUT:   }

+ 1 - 1
toolchain/check/testdata/namespace/fail_conflict_imported_namespace_second.carbon

@@ -53,7 +53,7 @@ fn NS.Foo();
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .NS = %import_ref
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+1, used [template = imports.%NS]
+// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+1, loc_10 [template = imports.%NS]
 // CHECK:STDOUT:   %.loc16: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %.loc24: <function> = fn_decl @.1 [template] {}
 // CHECK:STDOUT: }

+ 3 - 3
toolchain/check/testdata/namespace/fail_conflict_in_imports_namespace_first.carbon

@@ -75,13 +75,13 @@ fn NS.Bar() {}
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .NS = %NS
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %NS: <namespace> = namespace %import_ref.1, [template] {
 // CHECK:STDOUT:     .Foo = %import_ref.2
 // CHECK:STDOUT:     .Bar = %Bar
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir2, inst+1, used [template = imports.%NS]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir2, inst+1, loaded [template = imports.%NS]
 // CHECK:STDOUT:   %Bar: <function> = fn_decl @Bar [template] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 3
toolchain/check/testdata/namespace/fail_conflict_in_imports_namespace_second.carbon

@@ -75,13 +75,13 @@ fn NS.Bar() {}
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .NS = %NS
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
-// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir2, inst+1, used
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unloaded
+// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir2, inst+1, loaded
 // CHECK:STDOUT:   %NS: <namespace> = namespace %import_ref.2, [template] {
 // CHECK:STDOUT:     .Foo = %import_ref.3
 // CHECK:STDOUT:     .Bar = %Bar
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir2, inst+2, unused
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir2, inst+2, unloaded
 // CHECK:STDOUT:   %Bar: <function> = fn_decl @Bar [template] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/namespace/imported.carbon

@@ -59,17 +59,17 @@ var package_b: () = package.NS.ChildNS.B();
 // CHECK:STDOUT:     .package_a = %package_a
 // CHECK:STDOUT:     .package_b = %package_b
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %NS: <namespace> = namespace %import_ref.1, [template] {
 // CHECK:STDOUT:     .ChildNS = %ChildNS
 // CHECK:STDOUT:     .A = %import_ref.3
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+2, used
+// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+2, loaded
 // CHECK:STDOUT:   %ChildNS: <namespace> = namespace %import_ref.2, [template] {
 // CHECK:STDOUT:     .B = %import_ref.4
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+3, used [template = imports.%A]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+4, used [template = imports.%B]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+3, loc_13 [template = imports.%A]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+4, loc_27 [template = imports.%B]
 // CHECK:STDOUT:   %.loc4_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc4_9.2: type = converted %.loc4_9.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref () = var a

+ 10 - 10
toolchain/check/testdata/namespace/imported_indirect.carbon

@@ -53,7 +53,7 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .A = %A
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %A: <namespace> = namespace %import_ref, [template] {
 // CHECK:STDOUT:     .B = %B
 // CHECK:STDOUT:   }
@@ -66,11 +66,11 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .A = %A
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+2, used
+// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+2, loaded
 // CHECK:STDOUT:   %A: <namespace> = namespace %import_ref.1, [template] {
 // CHECK:STDOUT:     .B = %B
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+3, used
+// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+3, loaded
 // CHECK:STDOUT:   %B: <namespace> = namespace %import_ref.2, [template] {
 // CHECK:STDOUT:     .C = %C
 // CHECK:STDOUT:   }
@@ -83,15 +83,15 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .A = %A
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+2, used
+// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+2, loaded
 // CHECK:STDOUT:   %A: <namespace> = namespace %import_ref.1, [template] {
 // CHECK:STDOUT:     .B = %B
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+4, used
+// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+4, loaded
 // CHECK:STDOUT:   %B: <namespace> = namespace %import_ref.2, [template] {
 // CHECK:STDOUT:     .C = %C
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.3: <namespace> = import_ref ir1, inst+5, used
+// CHECK:STDOUT:   %import_ref.3: <namespace> = import_ref ir1, inst+5, loaded
 // CHECK:STDOUT:   %C: <namespace> = namespace %import_ref.3, [template] {
 // CHECK:STDOUT:     .D = %D
 // CHECK:STDOUT:   }
@@ -114,19 +114,19 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:     .A = %A
 // CHECK:STDOUT:     .e = %e
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+2, used
+// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+2, loaded
 // CHECK:STDOUT:   %A: <namespace> = namespace %import_ref.1, [template] {
 // CHECK:STDOUT:     .B = %B
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+4, used
+// CHECK:STDOUT:   %import_ref.2: <namespace> = import_ref ir1, inst+4, loaded
 // CHECK:STDOUT:   %B: <namespace> = namespace %import_ref.2, [template] {
 // CHECK:STDOUT:     .C = %C
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.3: <namespace> = import_ref ir1, inst+6, used
+// CHECK:STDOUT:   %import_ref.3: <namespace> = import_ref ir1, inst+6, loaded
 // CHECK:STDOUT:   %C: <namespace> = namespace %import_ref.3, [template] {
 // CHECK:STDOUT:     .D = %import_ref.4
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+7, used [template = imports.%D]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+7, loc_23 [template = imports.%D]
 // CHECK:STDOUT:   %.loc5_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc5_9.2: type = converted %.loc5_9.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:   %e.var: ref () = var e

+ 4 - 4
toolchain/check/testdata/namespace/merging.carbon

@@ -95,16 +95,16 @@ fn Run() {
 // CHECK:STDOUT:     .NS = %NS
 // CHECK:STDOUT:     .Run = %Run
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %NS: <namespace> = namespace %import_ref.1, [template] {
 // CHECK:STDOUT:     .A = %import_ref.2
 // CHECK:STDOUT:     .B1 = %import_ref.3
 // CHECK:STDOUT:     .B2 = %import_ref.4
 // CHECK:STDOUT:     .C = %C
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+2, used [template = imports.%A]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir2, inst+2, used [template = imports.%B1]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir2, inst+5, used [template = imports.%B2]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+2, loc_33 [template = imports.%A]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir2, inst+2, loc_39 [template = imports.%B1]
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir2, inst+5, loc_45 [template = imports.%B2]
 // CHECK:STDOUT:   %.loc7: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C: <function> = fn_decl @C [template] {}
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}

+ 12 - 12
toolchain/check/testdata/operators/overloaded/add.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Add> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Add> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Add.decl: invalid = interface_decl @Add [template = constants.%.2] {}
 // CHECK:STDOUT:     %Add.ref: type = name_ref Add, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in AddAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in AddAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Add {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/bit_and.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitAnd> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitAnd> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %BitAnd.decl: invalid = interface_decl @BitAnd [template = constants.%.2] {}
 // CHECK:STDOUT:     %BitAnd.ref: type = name_ref BitAnd, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in BitAndAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in BitAndAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitAnd {

+ 6 - 6
toolchain/check/testdata/operators/overloaded/bit_complement.carbon

@@ -92,10 +92,10 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitComplement> = import_ref ir1, inst+15, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+13, used [template = imports.%Op]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitComplement> = import_ref ir1, inst+15, loc_50 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+13, loc_19 [template = imports.%Op]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
@@ -109,8 +109,8 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:     %C.ref.loc14_20: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+13, unused
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, loc_50 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+13, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitComplement {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/bit_or.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitOr> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitOr> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %BitOr.decl: invalid = interface_decl @BitOr [template = constants.%.2] {}
 // CHECK:STDOUT:     %BitOr.ref: type = name_ref BitOr, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in BitOrAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in BitOrAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitOr {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/bit_xor.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitXor> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in BitXor> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %BitXor.decl: invalid = interface_decl @BitXor [template = constants.%.2] {}
 // CHECK:STDOUT:     %BitXor.ref: type = name_ref BitXor, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in BitXorAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in BitXorAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitXor {

+ 6 - 6
toolchain/check/testdata/operators/overloaded/dec.carbon

@@ -92,10 +92,10 @@ fn TestOp() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Dec> = import_ref ir1, inst+14, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+12, used [template = imports.%Op]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Dec> = import_ref ir1, inst+14, loc_47 [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+12, loc_19 [template = imports.%Op]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %C.ref: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
@@ -103,8 +103,8 @@ fn TestOp() {
 // CHECK:STDOUT:     %Dec.ref: type = name_ref Dec, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {}
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+12, unused
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, loc_47 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+12, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Dec {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/div.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Div> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Div> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Div.decl: invalid = interface_decl @Div [template = constants.%.2] {}
 // CHECK:STDOUT:     %Div.ref: type = name_ref Div, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in DivAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in DivAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Div {

+ 29 - 29
toolchain/check/testdata/operators/overloaded/eq.carbon

@@ -171,12 +171,12 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Eq> = import_ref ir1, inst+17, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <associated <function> in Eq> = import_ref ir1, inst+31, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir1, inst+15, used [template = imports.%Equal]
-// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir1, inst+30, used [template = imports.%NotEqual]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Eq> = import_ref ir1, inst+17, loc_68 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <associated <function> in Eq> = import_ref ir1, inst+31, loc_88 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir1, inst+15, loc_19 [template = imports.%Equal]
+// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir1, inst+30, loc_19 [template = imports.%NotEqual]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
@@ -192,8 +192,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestEqual.%b: C = bind_name b, %b.loc13_20.1
 // CHECK:STDOUT:     %return.var.loc13: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.7: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+15, unused
+// CHECK:STDOUT:   %import_ref.7: type = import_ref ir1, inst+1, loc_68 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+15, unloaded
 // CHECK:STDOUT:   %TestNotEqual: <function> = fn_decl @TestNotEqual [template] {
 // CHECK:STDOUT:     %C.ref.loc17_20: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc17_17.1: C = param a
@@ -203,8 +203,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestNotEqual.%b: C = bind_name b, %b.loc17_23.1
 // CHECK:STDOUT:     %return.var.loc17: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_88 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Eq {
@@ -310,13 +310,13 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestEqual.%b: D = bind_name b, %b.loc8_20.1
 // CHECK:STDOUT:     %return.var.loc8: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Eq> = import_ref ir1, inst+17, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <associated <function> in Eq> = import_ref ir1, inst+31, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+30, unused
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+15, unused
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_30 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Eq> = import_ref ir1, inst+17, loc_30 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <associated <function> in Eq> = import_ref ir1, inst+31, loc_50 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+15, unloaded
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+30, unloaded
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+15, unloaded
 // CHECK:STDOUT:   %TestNotEqual: <function> = fn_decl @TestNotEqual [template] {
 // CHECK:STDOUT:     %D.ref.loc16_20: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc16_17.1: D = param a
@@ -326,8 +326,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestNotEqual.%b: D = bind_name b, %b.loc16_23.1
 // CHECK:STDOUT:     %return.var.loc16: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.8: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.8: type = import_ref ir1, inst+1, loc_50 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Eq {
@@ -384,12 +384,12 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT:   %D.decl: type = class_decl @D [template = constants.%D] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Eq> = import_ref ir1, inst+17, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <associated <function> in Eq> = import_ref ir1, inst+31, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir1, inst+15, used [template = imports.%Equal]
-// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir1, inst+30, used [template = imports.%NotEqual]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_23 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Eq> = import_ref ir1, inst+17, loc_73 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <associated <function> in Eq> = import_ref ir1, inst+31, loc_93 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir1, inst+15, loc_24 [template = imports.%Equal]
+// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir1, inst+30, loc_24 [template = imports.%NotEqual]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %C.ref.loc9: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
@@ -405,8 +405,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestRhsBad.%b: D = bind_name b, %b.loc14_21.1
 // CHECK:STDOUT:     %return.var.loc14: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.7: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+15, unused
+// CHECK:STDOUT:   %import_ref.7: type = import_ref ir1, inst+1, loc_73 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+15, unloaded
 // CHECK:STDOUT:   %TestLhsBad: <function> = fn_decl @TestLhsBad [template] {
 // CHECK:STDOUT:     %D.ref.loc25: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc25_15.1: D = param a
@@ -416,8 +416,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestLhsBad.%b: C = bind_name b, %b.loc25_21.1
 // CHECK:STDOUT:     %return.var.loc25: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_93 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Eq {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon

@@ -149,20 +149,20 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Inc> = import_ref ir1, inst+14, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+12, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Inc> = import_ref ir1, inst+14, loc_65 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+12, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Inc.decl: invalid = interface_decl @Inc [template = constants.%.2] {}
 // CHECK:STDOUT:     %Inc.ref: type = name_ref Inc, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+16, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in AddAssign> = import_ref ir1, inst+34, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+18, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+32, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+16, loc_38 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in AddAssign> = import_ref ir1, inst+34, loc_82 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+18, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+32, loc_39 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc11: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc11: <namespace> = name_ref Core, %Core [template = %Core]
@@ -174,8 +174,8 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT:     %a.loc15_18.1: C = param a
 // CHECK:STDOUT:     @TestIncNonRef.%a: C = bind_name a, %a.loc15_18.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+12, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_65 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+12, unloaded
 // CHECK:STDOUT:   %TestAddAssignNonRef: <function> = fn_decl @TestAddAssignNonRef [template] {
 // CHECK:STDOUT:     %C.ref.loc26_27: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc26_24.1: C = param a
@@ -184,8 +184,8 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT:     %b.loc26_30.1: C = param b
 // CHECK:STDOUT:     @TestAddAssignNonRef.%b: C = bind_name b, %b.loc26_30.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+16, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+32, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+16, loc_82 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+32, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Inc {

+ 20 - 20
toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon

@@ -223,11 +223,11 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:     %C.ref.loc8_23: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestUnary.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Negate> = import_ref ir1, inst+11, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+9, unused
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+9, unused
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_25 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Negate> = import_ref ir1, inst+11, loc_25 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+9, unloaded
+// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+9, unloaded
 // CHECK:STDOUT:   %TestBinary: <function> = fn_decl @TestBinary [template] {
 // CHECK:STDOUT:     %C.ref.loc16_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc16_15.1: C = param a
@@ -238,26 +238,26 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:     %C.ref.loc16_30: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestBinary.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.6: type = import_ref ir1, inst+13, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.7: <associated <function> in Add> = import_ref ir1, inst+32, used [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+30, unused
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.6: type = import_ref ir1, inst+13, loc_45 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.7: <associated <function> in Add> = import_ref ir1, inst+32, loc_45 [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+15, unloaded
+// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+30, unloaded
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT:   %TestRef: <function> = fn_decl @TestRef [template] {
 // CHECK:STDOUT:     %C.ref.loc24: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %b.loc24_12.1: C = param b
 // CHECK:STDOUT:     @TestRef.%b: C = bind_name b, %b.loc24_12.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+34, used [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.12: <associated <function> in AddAssign> = import_ref ir1, inst+52, used [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.13 = import_ref ir1, inst+36, unused
-// CHECK:STDOUT:   %import_ref.14 = import_ref ir1, inst+50, unused
-// CHECK:STDOUT:   %import_ref.15 = import_ref ir1, inst+50, unused
-// CHECK:STDOUT:   %import_ref.16: type = import_ref ir1, inst+54, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.17: <associated <function> in Inc> = import_ref ir1, inst+67, used [template = constants.%.16]
-// CHECK:STDOUT:   %import_ref.18 = import_ref ir1, inst+56, unused
-// CHECK:STDOUT:   %import_ref.19 = import_ref ir1, inst+65, unused
-// CHECK:STDOUT:   %import_ref.20 = import_ref ir1, inst+65, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+34, loc_66 [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.12: <associated <function> in AddAssign> = import_ref ir1, inst+52, loc_66 [template = constants.%.13]
+// CHECK:STDOUT:   %import_ref.13 = import_ref ir1, inst+36, unloaded
+// CHECK:STDOUT:   %import_ref.14 = import_ref ir1, inst+50, unloaded
+// CHECK:STDOUT:   %import_ref.15 = import_ref ir1, inst+50, unloaded
+// CHECK:STDOUT:   %import_ref.16: type = import_ref ir1, inst+54, loc_69 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.17: <associated <function> in Inc> = import_ref ir1, inst+67, loc_69 [template = constants.%.16]
+// CHECK:STDOUT:   %import_ref.18 = import_ref ir1, inst+56, unloaded
+// CHECK:STDOUT:   %import_ref.19 = import_ref ir1, inst+65, unloaded
+// CHECK:STDOUT:   %import_ref.20 = import_ref ir1, inst+65, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Negate {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon

@@ -160,20 +160,20 @@ fn TestAssign(b: D) {
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
 // CHECK:STDOUT:   %D.decl: type = class_decl @D [template = constants.%D] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Add> = import_ref ir1, inst+20, used [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_23 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Add> = import_ref ir1, inst+20, loc_81 [template = constants.%.11]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_24 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc9: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc9: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Add.decl: invalid = interface_decl @Add [template = constants.%.2] {}
 // CHECK:STDOUT:     %Add.ref: type = name_ref Add, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in AddAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in AddAssign> = import_ref ir1, inst+40, loc_102 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc12: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc12: <namespace> = name_ref Core, %Core [template = %Core]
@@ -190,15 +190,15 @@ fn TestAssign(b: D) {
 // CHECK:STDOUT:     %C.ref.loc16_24: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @Test.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_81 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %D.ref.loc27: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %b.loc27_15.1: D = param b
 // CHECK:STDOUT:     @TestAssign.%b: D = bind_name b, %b.loc27_15.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_102 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Add {

+ 6 - 6
toolchain/check/testdata/operators/overloaded/inc.carbon

@@ -92,10 +92,10 @@ fn TestOp() {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Inc> = import_ref ir1, inst+14, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+12, used [template = imports.%Op]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Inc> = import_ref ir1, inst+14, loc_47 [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+12, loc_19 [template = imports.%Op]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %C.ref: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
@@ -103,8 +103,8 @@ fn TestOp() {
 // CHECK:STDOUT:     %Inc.ref: type = name_ref Inc, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {}
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+12, unused
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, loc_47 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+12, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Inc {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/left_shift.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in LeftShift> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in LeftShift> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %LeftShift.decl: invalid = interface_decl @LeftShift [template = constants.%.2] {}
 // CHECK:STDOUT:     %LeftShift.ref: type = name_ref LeftShift, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in LeftShiftAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in LeftShiftAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @LeftShift {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/mod.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Mod> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Mod> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Mod.decl: invalid = interface_decl @Mod [template = constants.%.2] {}
 // CHECK:STDOUT:     %Mod.ref: type = name_ref Mod, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in ModAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in ModAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Mod {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/mul.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Mul> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Mul> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Mul.decl: invalid = interface_decl @Mul [template = constants.%.2] {}
 // CHECK:STDOUT:     %Mul.ref: type = name_ref Mul, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in MulAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in MulAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Mul {

+ 6 - 6
toolchain/check/testdata/operators/overloaded/negate.carbon

@@ -92,10 +92,10 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Negate> = import_ref ir1, inst+15, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+13, used [template = imports.%Op]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Negate> = import_ref ir1, inst+15, loc_50 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+13, loc_19 [template = imports.%Op]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
@@ -109,8 +109,8 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:     %C.ref.loc14_20: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+13, unused
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+1, loc_50 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+13, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Negate {

+ 35 - 35
toolchain/check/testdata/operators/overloaded/ordered.carbon

@@ -207,16 +207,16 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Ordered> = import_ref ir1, inst+17, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <associated <function> in Ordered> = import_ref ir1, inst+31, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.5: <associated <function> in Ordered> = import_ref ir1, inst+59, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in Ordered> = import_ref ir1, inst+45, used [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir1, inst+15, used [template = imports.%Less]
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+30, used [template = imports.%LessOrEquivalent]
-// CHECK:STDOUT:   %import_ref.9: <function> = import_ref ir1, inst+44, used [template = imports.%Greater]
-// CHECK:STDOUT:   %import_ref.10: <function> = import_ref ir1, inst+58, used [template = imports.%GreaterOrEquivalent]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Ordered> = import_ref ir1, inst+17, loc_98 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <associated <function> in Ordered> = import_ref ir1, inst+31, loc_118 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.5: <associated <function> in Ordered> = import_ref ir1, inst+59, loc_158 [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in Ordered> = import_ref ir1, inst+45, loc_138 [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir1, inst+15, loc_19 [template = imports.%Less]
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+30, loc_19 [template = imports.%LessOrEquivalent]
+// CHECK:STDOUT:   %import_ref.9: <function> = import_ref ir1, inst+44, loc_19 [template = imports.%Greater]
+// CHECK:STDOUT:   %import_ref.10: <function> = import_ref ir1, inst+58, loc_19 [template = imports.%GreaterOrEquivalent]
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref: <namespace> = name_ref Core, %Core [template = %Core]
@@ -232,8 +232,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestLess.%b: C = bind_name b, %b.loc15_19.1
 // CHECK:STDOUT:     %return.var.loc15: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+15, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+1, loc_98 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+15, unloaded
 // CHECK:STDOUT:   %TestLessEqual: <function> = fn_decl @TestLessEqual [template] {
 // CHECK:STDOUT:     %C.ref.loc19_21: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc19_18.1: C = param a
@@ -243,8 +243,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestLessEqual.%b: C = bind_name b, %b.loc19_24.1
 // CHECK:STDOUT:     %return.var.loc19: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.13: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.14 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.13: type = import_ref ir1, inst+1, loc_118 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.14 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT:   %TestGreater: <function> = fn_decl @TestGreater [template] {
 // CHECK:STDOUT:     %C.ref.loc23_19: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc23_16.1: C = param a
@@ -254,8 +254,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestGreater.%b: C = bind_name b, %b.loc23_22.1
 // CHECK:STDOUT:     %return.var.loc23: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.15: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.16 = import_ref ir1, inst+44, unused
+// CHECK:STDOUT:   %import_ref.15: type = import_ref ir1, inst+1, loc_138 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.16 = import_ref ir1, inst+44, unloaded
 // CHECK:STDOUT:   %TestGreaterEqual: <function> = fn_decl @TestGreaterEqual [template] {
 // CHECK:STDOUT:     %C.ref.loc27_24: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc27_21.1: C = param a
@@ -265,8 +265,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestGreaterEqual.%b: C = bind_name b, %b.loc27_27.1
 // CHECK:STDOUT:     %return.var.loc27: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.17: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.18 = import_ref ir1, inst+58, unused
+// CHECK:STDOUT:   %import_ref.17: type = import_ref ir1, inst+1, loc_158 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.18 = import_ref ir1, inst+58, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Ordered {
@@ -430,17 +430,17 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestLess.%b: D = bind_name b, %b.loc8_19.1
 // CHECK:STDOUT:     %return.var.loc8: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Ordered> = import_ref ir1, inst+17, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <associated <function> in Ordered> = import_ref ir1, inst+31, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.5: <associated <function> in Ordered> = import_ref ir1, inst+59, used [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in Ordered> = import_ref ir1, inst+45, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+30, unused
-// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+44, unused
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+58, unused
-// CHECK:STDOUT:   %import_ref.11 = import_ref ir1, inst+15, unused
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_30 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Ordered> = import_ref ir1, inst+17, loc_30 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <associated <function> in Ordered> = import_ref ir1, inst+31, loc_50 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.5: <associated <function> in Ordered> = import_ref ir1, inst+59, loc_90 [template = constants.%.9]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in Ordered> = import_ref ir1, inst+45, loc_70 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+15, unloaded
+// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+30, unloaded
+// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+44, unloaded
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+58, unloaded
+// CHECK:STDOUT:   %import_ref.11 = import_ref ir1, inst+15, unloaded
 // CHECK:STDOUT:   %TestLessEqual: <function> = fn_decl @TestLessEqual [template] {
 // CHECK:STDOUT:     %D.ref.loc16_21: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc16_18.1: D = param a
@@ -450,8 +450,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestLessEqual.%b: D = bind_name b, %b.loc16_24.1
 // CHECK:STDOUT:     %return.var.loc16: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.12: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.13 = import_ref ir1, inst+30, unused
+// CHECK:STDOUT:   %import_ref.12: type = import_ref ir1, inst+1, loc_50 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.13 = import_ref ir1, inst+30, unloaded
 // CHECK:STDOUT:   %TestGreater: <function> = fn_decl @TestGreater [template] {
 // CHECK:STDOUT:     %D.ref.loc24_19: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc24_16.1: D = param a
@@ -461,8 +461,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestGreater.%b: D = bind_name b, %b.loc24_22.1
 // CHECK:STDOUT:     %return.var.loc24: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.14: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.15 = import_ref ir1, inst+44, unused
+// CHECK:STDOUT:   %import_ref.14: type = import_ref ir1, inst+1, loc_70 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.15 = import_ref ir1, inst+44, unloaded
 // CHECK:STDOUT:   %TestGreaterEqual: <function> = fn_decl @TestGreaterEqual [template] {
 // CHECK:STDOUT:     %D.ref.loc32_24: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc32_21.1: D = param a
@@ -472,8 +472,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestGreaterEqual.%b: D = bind_name b, %b.loc32_27.1
 // CHECK:STDOUT:     %return.var.loc32: ref bool = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.16: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.17 = import_ref ir1, inst+58, unused
+// CHECK:STDOUT:   %import_ref.16: type = import_ref ir1, inst+1, loc_90 [template = constants.%.4]
+// CHECK:STDOUT:   %import_ref.17 = import_ref ir1, inst+58, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Ordered {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/right_shift.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in RightShift> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in RightShift> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %RightShift.decl: invalid = interface_decl @RightShift [template = constants.%.2] {}
 // CHECK:STDOUT:     %RightShift.ref: type = name_ref RightShift, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in RightShiftAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in RightShiftAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @RightShift {

+ 12 - 12
toolchain/check/testdata/operators/overloaded/sub.carbon

@@ -146,20 +146,20 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Core: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %C.decl: type = class_decl @C [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Sub> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, loc_18 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.2: <associated <function> in Sub> = import_ref ir1, inst+20, loc_82 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+3, unloaded
+// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+18, loc_19 [template = imports.%Op.1]
 // CHECK:STDOUT:   impl_decl @impl.1 {
 // CHECK:STDOUT:     %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc8: <namespace> = name_ref Core, %Core [template = %Core]
 // CHECK:STDOUT:     %Sub.decl: invalid = interface_decl @Sub [template = constants.%.2] {}
 // CHECK:STDOUT:     %Sub.ref: type = name_ref Sub, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.6: <associated <function> in SubAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
+// CHECK:STDOUT:   %import_ref.5: type = import_ref ir1, inst+22, loc_46 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.6: <associated <function> in SubAssign> = import_ref ir1, inst+40, loc_101 [template = constants.%.14]
+// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+24, unloaded
+// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+38, loc_47 [template = imports.%Op.2]
 // CHECK:STDOUT:   impl_decl @impl.2 {
 // CHECK:STDOUT:     %C.ref.loc13: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %Core.ref.loc13: <namespace> = name_ref Core, %Core [template = %Core]
@@ -176,8 +176,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %C.ref.loc17_26: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     @TestOp.%return: ref C = var <return slot>
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unused
+// CHECK:STDOUT:   %import_ref.9: type = import_ref ir1, inst+1, loc_82 [template = constants.%.2]
+// CHECK:STDOUT:   %import_ref.10 = import_ref ir1, inst+18, unloaded
 // CHECK:STDOUT:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %C.ref.loc21_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %.loc21: type = ptr_type C [template = constants.%.8]
@@ -187,8 +187,8 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:     %b.loc21_22.1: C = param b
 // CHECK:STDOUT:     @TestAssign.%b: C = bind_name b, %b.loc21_22.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unused
+// CHECK:STDOUT:   %import_ref.11: type = import_ref ir1, inst+22, loc_101 [template = constants.%.7]
+// CHECK:STDOUT:   %import_ref.12 = import_ref ir1, inst+38, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Sub {

+ 8 - 8
toolchain/check/testdata/packages/cross_package_import.carbon

@@ -238,8 +238,8 @@ fn Other.G() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%F]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, used [template = imports.%F2]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_22 [template = imports.%F]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, loc_28 [template = imports.%F2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
@@ -270,8 +270,8 @@ fn Other.G() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%F.1]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, used [template = imports.%F.2]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_22 [template = imports.%F.1]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, loaded [template = imports.%F.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
@@ -308,8 +308,8 @@ fn Other.G() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Other: <namespace> = namespace [template] {}
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template] {}
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%F.1]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+3, used [template = imports.%F.2]
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loc_22 [template = imports.%F.1]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+3, loaded [template = imports.%F.2]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
@@ -330,9 +330,9 @@ fn Other.G() {}
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Other = %Other
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, used
+// CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, loaded
 // CHECK:STDOUT:   %Other: <namespace> = namespace %import_ref.1, [template] {}
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, used [template = imports.%F]
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, loc_16 [template = imports.%F]
 // CHECK:STDOUT:   %F: <function> = fn_decl @F [template] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/packages/fail_conflict_no_namespaces.carbon

@@ -62,8 +62,8 @@ import library "var";
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .Foo = %import_ref.1
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%Foo]
-// CHECK:STDOUT:   %import_ref.2: ref i32 = import_ref ir2, inst+2, used
+// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, loaded [template = imports.%Foo]
+// CHECK:STDOUT:   %import_ref.2: ref i32 = import_ref ir2, inst+2, loaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Foo();

+ 4 - 4
toolchain/check/testdata/packages/fail_import_type_error.carbon

@@ -78,10 +78,10 @@ var d: i32 = d_ref;
 // CHECK:STDOUT:     .c = %c
 // CHECK:STDOUT:     .d = %d
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: ref <error> = import_ref ir1, inst+3, used
-// CHECK:STDOUT:   %import_ref.2: ref <error> = import_ref ir1, inst+8, used
-// CHECK:STDOUT:   %import_ref.3: ref <error> = import_ref ir1, inst+12, used
-// CHECK:STDOUT:   %import_ref.4: ref <error> = import_ref ir1, inst+16, used
+// CHECK:STDOUT:   %import_ref.1: ref <error> = import_ref ir1, inst+3, loc_10
+// CHECK:STDOUT:   %import_ref.2: ref <error> = import_ref ir1, inst+8, loc_17
+// CHECK:STDOUT:   %import_ref.3: ref <error> = import_ref ir1, inst+12, loc_24
+// CHECK:STDOUT:   %import_ref.4: ref <error> = import_ref ir1, inst+16, loc_31
 // CHECK:STDOUT:   %a.var: ref i32 = var a
 // CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var
 // CHECK:STDOUT:   %b.var: ref i32 = var b

+ 2 - 2
toolchain/check/testdata/packages/loaded_global.carbon

@@ -57,7 +57,7 @@ var package_b: () = package.B();
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:     .package_a = %package_a
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+1, used [template = imports.%A]
+// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+1, loc_11 [template = imports.%A]
 // CHECK:STDOUT:   %.loc4_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc4_9.2: type = converted %.loc4_9.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref () = var a
@@ -105,7 +105,7 @@ var package_b: () = package.B();
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:     .package_b = %package_b
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+1, used [template = imports.%B]
+// CHECK:STDOUT:   %import_ref: <function> = import_ref ir1, inst+1, loc_17 [template = imports.%B]
 // CHECK:STDOUT:   %.loc6_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc6_9.2: type = converted %.loc6_9.1, constants.%.1 [template = constants.%.1]
 // CHECK:STDOUT:   %b.var: ref () = var b

+ 1 - 1
toolchain/check/testdata/packages/unused_lazy_import.carbon

@@ -31,6 +31,6 @@ package Implicit impl;
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
 // CHECK:STDOUT:     .A = %import_ref
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/pointer/import.carbon

@@ -58,8 +58,8 @@ var a: i32* = a_ref;
 // CHECK:STDOUT:     .a_ref = %import_ref.2
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.2: ref i32* = import_ref ir1, inst+9, used
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unloaded
+// CHECK:STDOUT:   %import_ref.2: ref i32* = import_ref ir1, inst+9, loc_11
 // CHECK:STDOUT:   %.loc4: type = ptr_type i32 [template = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref i32* = var a
 // CHECK:STDOUT:   %a: ref i32* = bind_name a, %a.var

+ 2 - 2
toolchain/check/testdata/struct/import.carbon

@@ -103,8 +103,8 @@ var b: {.a: {.b: i32, .c: (i32,)}, .d: i32} = b_ref;
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: ref {.a: i32} = import_ref ir1, inst+6, used
-// CHECK:STDOUT:   %import_ref.2: ref {.a: {.b: i32, .c: (i32,)}, .d: i32} = import_ref ir1, inst+37, used
+// CHECK:STDOUT:   %import_ref.1: ref {.a: i32} = import_ref ir1, inst+6, loc_15
+// CHECK:STDOUT:   %import_ref.2: ref {.a: {.b: i32, .c: (i32,)}, .d: i32} = import_ref ir1, inst+37, loc_45
 // CHECK:STDOUT:   %.loc4: type = struct_type {.a: i32} [template = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref {.a: i32} = var a
 // CHECK:STDOUT:   %a: ref {.a: i32} = bind_name a, %a.var

+ 2 - 2
toolchain/check/testdata/tuples/import.carbon

@@ -125,8 +125,8 @@ var b: (((i32,), i32), (i32, i32)) = b_ref;
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:     .b = %b
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref.1: ref (i32,) = import_ref ir1, inst+6, used
-// CHECK:STDOUT:   %import_ref.2: ref (((i32,), i32), (i32, i32)) = import_ref ir1, inst+34, used
+// CHECK:STDOUT:   %import_ref.1: ref (i32,) = import_ref ir1, inst+6, loc_13
+// CHECK:STDOUT:   %import_ref.2: ref (((i32,), i32), (i32, i32)) = import_ref ir1, inst+34, loc_35
 // CHECK:STDOUT:   %.loc4_13.1: (type,) = tuple_literal (i32)
 // CHECK:STDOUT:   %.loc4_13.2: type = converted %.loc4_13.1, constants.%.2 [template = constants.%.2]
 // CHECK:STDOUT:   %a.var: ref (i32,) = var a

+ 1 - 1
toolchain/check/testdata/var/import.carbon

@@ -44,7 +44,7 @@ var a: i32 = a_ref;
 // CHECK:STDOUT:     .a_ref = %import_ref
 // CHECK:STDOUT:     .a = %a
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: ref i32 = import_ref ir1, inst+2, used
+// CHECK:STDOUT:   %import_ref: ref i32 = import_ref ir1, inst+2, loc_10
 // CHECK:STDOUT:   %a.var: ref i32 = var a
 // CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var
 // CHECK:STDOUT: }

+ 8 - 2
toolchain/lower/handle.cpp

@@ -306,9 +306,15 @@ auto HandleImplDecl(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
   FatalErrorIfEncountered(inst);
 }
 
-auto HandleImportRefUnused(FunctionContext& /*context*/,
+auto HandleImportRefUnloaded(FunctionContext& /*context*/,
+                             SemIR::InstId /*inst_id*/,
+                             SemIR::ImportRefUnloaded inst) -> void {
+  FatalErrorIfEncountered(inst);
+}
+
+auto HandleImportRefLoaded(FunctionContext& /*context*/,
                            SemIR::InstId /*inst_id*/,
-                           SemIR::ImportRefUnused inst) -> void {
+                           SemIR::ImportRefLoaded inst) -> void {
   FatalErrorIfEncountered(inst);
 }
 

+ 18 - 11
toolchain/sem_ir/file.cpp

@@ -107,8 +107,10 @@ File::File(SharedValueStores& value_stores, std::string filename,
         for (auto [i, inst] : llvm::enumerate(builtins->insts_.array_ref())) {
           // We can reuse the type_id from the builtin IR's inst because they're
           // special-cased values.
-          insts_.AddInNoBlock(ImportRefUsed{
-              inst.type_id(), ImportIRId::Builtins, SemIR::InstId(i)});
+          auto import_ir_inst_id = import_ir_insts_.Add(
+              {.ir_id = ImportIRId::Builtins, .inst_id = SemIR::InstId(i)});
+          insts_.AddInNoBlock(
+              ImportRefLoaded{inst.type_id(), import_ir_inst_id});
         }
       }) {}
 
@@ -199,6 +201,7 @@ static auto GetTypePrecedence(InstKind kind) -> int {
     case Builtin::Kind:
     case ClassType::Kind:
     case FacetTypeAccess::Kind:
+    case ImportRefLoaded::Kind:
     case ImportRefUsed::Kind:
     case InterfaceType::Kind:
     case NameRef::Kind:
@@ -236,7 +239,7 @@ static auto GetTypePrecedence(InstKind kind) -> int {
     case FieldDecl::Kind:
     case FunctionDecl::Kind:
     case ImplDecl::Kind:
-    case ImportRefUnused::Kind:
+    case ImportRefUnloaded::Kind:
     case InitializeFrom::Kind:
     case InterfaceDecl::Kind:
     case InterfaceWitness::Kind:
@@ -374,11 +377,13 @@ static auto StringifyTypeExprImpl(const SemIR::File& outer_sem_ir,
         push_inst_id(inst.As<FacetTypeAccess>().facet_id);
         break;
       }
+      case ImportRefLoaded::Kind:
       case ImportRefUsed::Kind: {
-        auto import_ref = inst.As<ImportRefUsed>();
+        auto import_ir_inst = sem_ir.import_ir_insts().Get(
+            inst.As<AnyImportRef>().import_ir_inst_id);
         steps.push_back(
-            {.sem_ir = *sem_ir.import_irs().Get(import_ref.ir_id).sem_ir,
-             .inst_id = import_ref.inst_id});
+            {.sem_ir = *sem_ir.import_irs().Get(import_ir_inst.ir_id).sem_ir,
+             .inst_id = import_ir_inst.inst_id});
         break;
       }
       case InterfaceType::Kind: {
@@ -485,7 +490,7 @@ static auto StringifyTypeExprImpl(const SemIR::File& outer_sem_ir,
       case FieldDecl::Kind:
       case FunctionDecl::Kind:
       case ImplDecl::Kind:
-      case ImportRefUnused::Kind:
+      case ImportRefUnloaded::Kind:
       case InitializeFrom::Kind:
       case InterfaceDecl::Kind:
       case InterfaceWitness::Kind:
@@ -550,17 +555,19 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
       case FieldDecl::Kind:
       case FunctionDecl::Kind:
       case ImplDecl::Kind:
-      case ImportRefUnused::Kind:
+      case ImportRefUnloaded::Kind:
       case Namespace::Kind:
       case Return::Kind:
       case ReturnExpr::Kind:
       case StructTypeField::Kind:
         return ExprCategory::NotExpr;
 
+      case ImportRefLoaded::Kind:
       case ImportRefUsed::Kind: {
-        auto import_ref = inst.As<ImportRefUsed>();
-        ir = ir->import_irs().Get(import_ref.ir_id).sem_ir;
-        inst_id = import_ref.inst_id;
+        auto import_ir_inst = ir->import_ir_insts().Get(
+            inst.As<AnyImportRef>().import_ir_inst_id);
+        ir = ir->import_irs().Get(import_ir_inst.ir_id).sem_ir;
+        inst_id = import_ir_inst.inst_id;
         continue;
       }
 

+ 37 - 13
toolchain/sem_ir/formatter.cpp

@@ -502,7 +502,8 @@ class InstNamer {
           CollectNamesInBlock(scope_id, inst.decl_block_id);
           break;
         }
-        case ImportRefUnused::Kind:
+        case ImportRefUnloaded::Kind:
+        case ImportRefLoaded::Kind:
         case ImportRefUsed::Kind: {
           add_inst_name("import_ref");
           // When building import refs, we frequently add instructions without
@@ -938,11 +939,11 @@ class Formatter {
     out_ << "\n";
   }
 
-  // Don't print a constant for ImportRefUnused.
-  auto FormatInstruction(InstId inst_id, ImportRefUnused inst) -> void {
+  // Don't print a constant for ImportRefUnloaded.
+  auto FormatInstruction(InstId inst_id, ImportRefUnloaded inst) -> void {
     Indent();
     FormatInstructionLHS(inst_id, inst);
-    out_ << ImportRefUnused::Kind.ir_name();
+    out_ << ImportRefUnloaded::Kind.ir_name();
     FormatInstructionRHS(inst);
     out_ << "\n";
   }
@@ -1003,9 +1004,10 @@ class Formatter {
     }
   }
 
-  // Print ImportRefUnused with type-like semantics even though it lacks a
+  // Print ImportRefUnloaded with type-like semantics even though it lacks a
   // type_id.
-  auto FormatInstructionLHS(InstId inst_id, ImportRefUnused /*inst*/) -> void {
+  auto FormatInstructionLHS(InstId inst_id, ImportRefUnloaded /*inst*/)
+      -> void {
     FormatInstName(inst_id);
     out_ << " = ";
   }
@@ -1158,16 +1160,18 @@ class Formatter {
         .print(out_, sem_ir_.types().IsSignedInt(inst.type_id));
   }
 
-  auto FormatInstructionRHS(ImportRefUnused inst) -> void {
-    // Don't format the inst_id because it refers to a different IR.
-    // TODO: Consider a better way to format the InstID from other IRs.
-    out_ << " " << inst.ir_id << ", " << inst.inst_id << ", unused";
+  auto FormatInstructionRHS(ImportRefUnloaded inst) -> void {
+    FormatArgs(inst.import_ir_inst_id);
+    out_ << ", unloaded";
+  }
+
+  auto FormatInstructionRHS(ImportRefLoaded inst) -> void {
+    FormatArgs(inst.import_ir_inst_id);
+    out_ << ", loaded";
   }
 
   auto FormatInstructionRHS(ImportRefUsed inst) -> void {
-    // Don't format the inst_id because it refers to a different IR.
-    // TODO: Consider a better way to format the InstID from other IRs.
-    out_ << " " << inst.ir_id << ", " << inst.inst_id << ", used";
+    FormatArgs(inst.import_ir_inst_id, inst.used_id);
   }
 
   auto FormatInstructionRHS(SpliceBlock inst) -> void {
@@ -1219,11 +1223,31 @@ class Formatter {
 
   auto FormatArg(ImportIRId id) -> void { out_ << id; }
 
+  auto FormatArg(ImportIRInstId id) -> void {
+    // Don't format the inst_id because it refers to a different IR.
+    // TODO: Consider a better way to format the InstID from other IRs.
+    auto import_ir_inst = sem_ir_.import_ir_insts().Get(id);
+    out_ << import_ir_inst.ir_id << ", " << import_ir_inst.inst_id;
+  }
+
   auto FormatArg(IntId id) -> void {
     // We don't know the signedness to use here. Default to unsigned.
     sem_ir_.ints().Get(id).print(out_, /*isSigned=*/false);
   }
 
+  auto FormatArg(LocId id) -> void {
+    if (id.is_import_ir_inst_id()) {
+      out_ << "{";
+      FormatArg(id.import_ir_inst_id());
+      out_ << "}";
+    } else {
+      // TODO: For a NodeId, this prints the index of the node. Do we want it to
+      // print a line number or something in order to make it less dependent on
+      // parse?
+      out_ << id;
+    }
+  }
+
   auto FormatArg(ElementIndex index) -> void { out_ << index; }
 
   auto FormatArg(NameScopeId id) -> void {

+ 2 - 2
toolchain/sem_ir/id_kind.h

@@ -121,8 +121,8 @@ using IdKind = TypeEnum<
     IntId, RealId, StringLiteralValueId,
     // From sem_ir/id.h.
     InstId, ConstantId, BindNameId, FunctionId, ClassId, InterfaceId, ImplId,
-    ImportIRId, BoolValue, NameId, NameScopeId, InstBlockId, TypeId,
-    TypeBlockId, ElementIndex>;
+    ImportIRId, ImportIRInstId, LocId, BoolValue, NameId, NameScopeId,
+    InstBlockId, TypeId, TypeBlockId, ElementIndex>;
 
 }  // namespace Carbon::SemIR
 

+ 3 - 1
toolchain/sem_ir/ids.h

@@ -496,10 +496,12 @@ struct ImportIRInstId : public IdBase, public Printable<InstId> {
 // - index > Invalid: A Parse::NodeId in the current IR.
 // - index < Invalid: An ImportIRInstId.
 // - index == Invalid: Can be used for either.
-struct LocId : public IdBase, public Printable<FunctionId> {
+struct LocId : public IdBase, public Printable<LocId> {
   // An explicitly invalid function ID.
   static const LocId Invalid;
 
+  using IdBase::IdBase;
+
   // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr LocId(Parse::InvalidNodeId /*invalid*/) : IdBase(InvalidIndex) {}
 

+ 2 - 1
toolchain/sem_ir/inst_kind.def

@@ -50,7 +50,8 @@ CARBON_SEM_IR_INST_KIND(FacetTypeAccess)
 CARBON_SEM_IR_INST_KIND(FieldDecl)
 CARBON_SEM_IR_INST_KIND(FunctionDecl)
 CARBON_SEM_IR_INST_KIND(ImplDecl)
-CARBON_SEM_IR_INST_KIND(ImportRefUnused)
+CARBON_SEM_IR_INST_KIND(ImportRefUnloaded)
+CARBON_SEM_IR_INST_KIND(ImportRefLoaded)
 CARBON_SEM_IR_INST_KIND(ImportRefUsed)
 CARBON_SEM_IR_INST_KIND(InitializeFrom)
 CARBON_SEM_IR_INST_KIND(InterfaceDecl)

+ 20 - 11
toolchain/sem_ir/typed_insts.h

@@ -461,23 +461,31 @@ struct ImplDecl {
 
 // Common representation for all kinds of `ImportRef*` node.
 struct AnyImportRef {
-  static constexpr InstKind Kinds[] = {InstKind::ImportRefUnused,
+  static constexpr InstKind Kinds[] = {InstKind::ImportRefUnloaded,
+                                       InstKind::ImportRefLoaded,
                                        InstKind::ImportRefUsed};
 
   InstKind kind;
-  ImportIRId ir_id;
-  InstId inst_id;
+  ImportIRInstId import_ir_inst_id;
 };
 
-// An imported entity that hasn't yet been referenced. If referenced, it should
-// turn into an ImportRefUsed.
-struct ImportRefUnused {
+// An imported entity that is not yet been loaded.
+struct ImportRefUnloaded {
   // No parse node: any parse node logic must use the referenced IR.
   static constexpr auto Kind =
-      InstKind::ImportRefUnused.Define<Parse::InvalidNodeId>("import_ref");
+      InstKind::ImportRefUnloaded.Define<Parse::InvalidNodeId>("import_ref");
 
-  ImportIRId ir_id;
-  InstId inst_id;
+  ImportIRInstId import_ir_inst_id;
+};
+
+// A imported entity that is loaded, but has not yet had a use associated.
+struct ImportRefLoaded {
+  // No parse node: any parse node logic must use the referenced IR.
+  static constexpr auto Kind =
+      InstKind::ImportRefLoaded.Define<Parse::InvalidNodeId>("import_ref");
+
+  TypeId type_id;
+  ImportIRInstId import_ir_inst_id;
 };
 
 // An imported entity that has a reference, and thus should be emitted.
@@ -487,8 +495,9 @@ struct ImportRefUsed {
       InstKind::ImportRefUsed.Define<Parse::InvalidNodeId>("import_ref");
 
   TypeId type_id;
-  ImportIRId ir_id;
-  InstId inst_id;
+  ImportIRInstId import_ir_inst_id;
+  // A location to reference for queries about the use.
+  LocId used_id;
 };
 
 // Finalizes the initialization of `dest_id` from the initializer expression