Explorar o código

Lowering support for overloaded operators. (#3798)

Fix a collection of issues that were preventing lowering for overloaded
operators from working.

Instead of creating `import_ref` instructions during name lookup in the
current block, whatever that might be, we now create them in the `file`
block always. This avoids inserting them into blocks that might not be
intended to contain them, such as functions, and avoids the IR generated
for a function depending on which names we happen to have looked up
first.

When importing a class, function, or interface, import its enclosing
scope ID. This is necessary to allow us to distinguish between functions
at interface scope, which shouldn't be lowered, and other functions, and
will also be used in future to provide qualified names for declarations
when printing types. In order to support this:

- Track the constant values of namespaces created during importing so
that we can find them when resolving an import ref. Use those constant
values to convert an enclosing scope ID from the imported IR into a
corresponding ID in the current IR.
- Change how we do two-pass import of classes and namespaces so that we
can do two-pass import even for non-defining declarations, so that we
can import the enclosing scope.

While working on the final point above, I reworked `TryResolveInst` to
return a flag indicating whether another pass is necessary instead of
implicitly encoding this in the `ConstantId`. This permits the handling
of classes to be simplified; now `import_ir_constant_values` is only
accessed in a single place.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Richard Smith %!s(int64=2) %!d(string=hai) anos
pai
achega
d8be774b8b
Modificáronse 35 ficheiros con 947 adicións e 799 borrados
  1. 11 3
      toolchain/check/check.cpp
  2. 18 2
      toolchain/check/context.cpp
  3. 5 0
      toolchain/check/context.h
  4. 18 9
      toolchain/check/import.cpp
  5. 227 186
      toolchain/check/import_ref.cpp
  6. 8 0
      toolchain/check/inst_block_stack.h
  7. 10 13
      toolchain/check/testdata/class/cross_package_import.carbon
  8. 2 3
      toolchain/check/testdata/class/fail_import_misuses.carbon
  9. 32 23
      toolchain/check/testdata/class/import.carbon
  10. 16 18
      toolchain/check/testdata/class/import_base.carbon
  11. 7 8
      toolchain/check/testdata/class/import_member_cycle.carbon
  12. 5 6
      toolchain/check/testdata/class/import_struct_cyle.carbon
  13. 36 39
      toolchain/check/testdata/interface/import.carbon
  14. 21 23
      toolchain/check/testdata/operators/overloaded/add.carbon
  15. 21 23
      toolchain/check/testdata/operators/overloaded/bit_and.carbon
  16. 11 12
      toolchain/check/testdata/operators/overloaded/bit_complement.carbon
  17. 21 23
      toolchain/check/testdata/operators/overloaded/bit_or.carbon
  18. 21 23
      toolchain/check/testdata/operators/overloaded/bit_xor.carbon
  19. 11 12
      toolchain/check/testdata/operators/overloaded/dec.carbon
  20. 21 23
      toolchain/check/testdata/operators/overloaded/div.carbon
  21. 49 52
      toolchain/check/testdata/operators/overloaded/eq.carbon
  22. 21 23
      toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon
  23. 36 40
      toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon
  24. 21 23
      toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon
  25. 11 12
      toolchain/check/testdata/operators/overloaded/inc.carbon
  26. 21 23
      toolchain/check/testdata/operators/overloaded/left_shift.carbon
  27. 21 23
      toolchain/check/testdata/operators/overloaded/mod.carbon
  28. 21 23
      toolchain/check/testdata/operators/overloaded/mul.carbon
  29. 11 12
      toolchain/check/testdata/operators/overloaded/negate.carbon
  30. 56 58
      toolchain/check/testdata/operators/overloaded/ordered.carbon
  31. 21 23
      toolchain/check/testdata/operators/overloaded/right_shift.carbon
  32. 21 23
      toolchain/check/testdata/operators/overloaded/sub.carbon
  33. 12 13
      toolchain/check/testdata/packages/cross_package_import.carbon
  34. 1 2
      toolchain/lower/file_context.cpp
  35. 102 0
      toolchain/lower/testdata/operators/overloaded.carbon

+ 11 - 3
toolchain/check/check.cpp

@@ -159,6 +159,15 @@ struct UnitInfo {
 // Add imports to the root block.
 static auto InitPackageScopeAndImports(Context& context, UnitInfo& unit_info)
     -> void {
+  // First create the constant values map for all imported IRs. We'll populate
+  // these with mappings for namespaces as we go.
+  size_t num_irs = context.import_irs().size();
+  for (auto& [_, package_imports] : unit_info.package_imports_map) {
+    num_irs += package_imports.imports.size();
+  }
+  context.import_ir_constant_values().resize(
+      num_irs, SemIR::ConstantValueStore(SemIR::ConstantId::Invalid));
+
   // Importing makes many namespaces, so only canonicalize the type once.
   auto namespace_type_id =
       context.GetBuiltinType(SemIR::BuiltinKind::NamespaceType);
@@ -217,9 +226,8 @@ static auto InitPackageScopeAndImports(Context& context, UnitInfo& unit_info)
                                     sem_irs, package_imports.has_load_error);
   }
 
-  context.import_ir_constant_values().resize(
-      context.import_irs().size(),
-      SemIR::ConstantValueStore(SemIR::ConstantId::Invalid));
+  CARBON_CHECK(context.import_irs().size() == num_irs)
+      << "Created an unexpected number of IRs";
 }
 
 // Loops over all nodes in the tree. On some errors, this may return early,

+ 18 - 2
toolchain/check/context.cpp

@@ -134,6 +134,23 @@ auto Context::ReplaceInstBeforeConstantUse(
   constant_values().Set(inst_id, const_id);
 }
 
+auto Context::AddImportRef(SemIR::ImportIRId ir_id, SemIR::InstId inst_id)
+    -> SemIR::InstId {
+  auto import_ref_id =
+      AddPlaceholderInstInNoBlock(SemIR::ImportRefUnused{ir_id, inst_id});
+
+  // 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
+  // an otherwise unknown checking step. But we need to add the instruction
+  // somewhere, because it's referenced by other instructions and needs to be
+  // visible in textual IR. Adding it to the file block is arbitrary but is the
+  // best place we have right now.
+  //
+  // TODO: Consider adding a dedicated block for import_refs.
+  inst_block_stack().AddInstIdToFileBlock(import_ref_id);
+  return import_ref_id;
+}
+
 auto Context::DiagnoseDuplicateName(SemIRLocation dup_def,
                                     SemIRLocation prev_def) -> void {
   CARBON_DIAGNOSTIC(NameDeclDuplicate, Error,
@@ -301,8 +318,7 @@ static auto LookupInImportIRScopes(Context& context, SemIRLocation loc,
       // Name doesn't exist in the import scope.
       continue;
     }
-    auto import_inst_id = context.AddPlaceholderInst(
-        {SemIR::ImportRefUnused{import_ir_id, it->second}});
+    auto import_inst_id = context.AddImportRef(import_ir_id, it->second);
     TryResolveImportRefUnused(context, import_inst_id);
     if (result_id.is_valid()) {
       // TODO: Add generalized merge functionality (merge_decls.h?).

+ 5 - 0
toolchain/check/context.h

@@ -96,6 +96,11 @@ class Context {
                                     SemIR::NodeIdAndInst node_id_and_inst)
       -> void;
 
+  // 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;
+
   // Sets only the parse node of an instruction. This is only used when setting
   // the parse node of an imported namespace. Versus
   // ReplaceInstBeforeConstantUse, it is safe to use after the namespace is used

+ 18 - 9
toolchain/check/import.cpp

@@ -79,7 +79,7 @@ static auto AddNamespace(
     Parse::ImportDirectiveId node_id, SemIR::NameId name_id,
     SemIR::NameScopeId enclosing_scope_id, bool diagnose_duplicate_namespace,
     std::optional<llvm::function_ref<SemIR::InstId()>> make_import_id)
-    -> std::pair<SemIR::NameScopeId, bool> {
+    -> std::tuple<SemIR::NameScopeId, SemIR::ConstantId, bool> {
   auto& enclosing_scope = context.name_scopes().Get(enclosing_scope_id);
   auto [it, success] =
       enclosing_scope.names.insert({name_id, SemIR::InstId::Invalid});
@@ -89,7 +89,8 @@ static auto AddNamespace(
       if (diagnose_duplicate_namespace) {
         context.DiagnoseDuplicateName(node_id, it->second);
       }
-      return {namespace_inst->name_scope_id, true};
+      return {namespace_inst->name_scope_id,
+              context.constant_values().Get(it->second), true};
     }
   }
 
@@ -110,7 +111,8 @@ static auto AddNamespace(
   }
 
   it->second = namespace_id;
-  return {namespace_inst.name_scope_id, false};
+  return {namespace_inst.name_scope_id,
+          context.constant_values().Get(namespace_id), false};
 }
 
 // Adds a copied namespace to the cache.
@@ -140,11 +142,14 @@ static auto CopySingleNameScopeFromImportIR(
                                                 .ir_id = ir_id,
                                                 .inst_id = import_inst_id});
   };
-  auto [namespace_scope_id, _] =
+  auto [namespace_scope_id, namespace_const_id, _] =
       AddNamespace(context, namespace_type_id, Parse::NodeId::Invalid, name_id,
                    enclosing_scope_id, /*diagnose_duplicate_namespace=*/false,
                    make_import_id);
 
+  context.import_ir_constant_values()[ir_id.index].Set(import_inst_id,
+                                                       namespace_const_id);
+
   CacheCopiedNamespace(copied_namespaces, import_scope_id, namespace_scope_id);
   return namespace_scope_id;
 }
@@ -205,6 +210,9 @@ auto ImportLibraryFromCurrentPackage(Context& context,
                                      SemIR::TypeId namespace_type_id,
                                      const SemIR::File& import_sem_ir) -> void {
   auto ir_id = context.import_irs().Add(&import_sem_ir);
+  context.import_ir_constant_values()[ir_id.index].Set(
+      SemIR::InstId::PackageNamespace,
+      context.constant_values().Get(SemIR::InstId::PackageNamespace));
 
   for (const auto import_inst_id :
        import_sem_ir.inst_blocks().Get(SemIR::InstBlockId::Exports)) {
@@ -233,8 +241,7 @@ auto ImportLibraryFromCurrentPackage(Context& context,
           namespace_type_id);
     } else {
       // Leave a placeholder that the inst comes from the other IR.
-      auto target_id = context.AddPlaceholderInst(
-          {SemIR::ImportRefUnused{.ir_id = ir_id, .inst_id = import_inst_id}});
+      auto target_id = context.AddImportRef(ir_id, import_inst_id);
       // TODO: When importing from other packages, the scope's names should
       // be changed to allow for ambiguous names. When importing from the
       // current package, as is currently being done, we should issue a
@@ -260,15 +267,17 @@ auto ImportLibrariesFromOtherPackage(Context& context,
 
   auto name_id = SemIR::NameId::ForIdentifier(package_id);
 
-  auto [namespace_scope_id, is_duplicate] = AddNamespace(
+  auto [namespace_scope_id, namespace_const_id, is_duplicate] = AddNamespace(
       context, namespace_type_id, node_id, name_id, SemIR::NameScopeId::Package,
       /*diagnose_duplicate_namespace=*/true, /*make_import_id=*/std::nullopt);
 
   auto& scope = context.name_scopes().Get(namespace_scope_id);
   scope.is_closed_import = !is_duplicate;
   for (const auto* sem_ir : sem_irs) {
-    scope.import_ir_scopes.push_back(
-        {context.import_irs().Add(sem_ir), SemIR::NameScopeId::Package});
+    auto ir_id = context.import_irs().Add(sem_ir);
+    scope.import_ir_scopes.push_back({ir_id, SemIR::NameScopeId::Package});
+    context.import_ir_constant_values()[ir_id.index].Set(
+        SemIR::InstId::PackageNamespace, namespace_const_id);
   }
   if (has_load_error) {
     scope.has_error = has_load_error;

+ 227 - 186
toolchain/check/import_ref.cpp

@@ -22,29 +22,30 @@ namespace Carbon::Check {
 // Calling Resolve on an instruction operates in an iterative manner, tracking
 // Work items on work_stack_. At a high level, the loop is:
 //
-// 1. If Work has received a constant, it's considered resolved.
-//    - If made_forward_decl, resolve unconditionally.
+// 1. If a constant value is already known for the work item, and we're
+//    processing it for the first time, it's considered resolved.
 //    - The constant check avoids performance costs of deduplication on add.
+//    - If `retry` is set, we process it again, because it didn't complete last
+//      time, even though we have a constant value already.
 // 2. Resolve the instruction: (TryResolveInst/TryResolveTypedInst)
-//    - For most cases:
-//      A. For types which _can_ be forward declared, when not
-//         made_forward_decl:
-//        i. Start by making a forward declared type to address circular
-//           references.
-//        ii. If the imported type is not defined, return the constant.
-//        iii. Otherwise, set made_forward_decl and continue resolving.
-//          - Creating a forward declaration of the type will have set the
-//            constant, which influences step (1); setting made_forward_decl
-//            gets us a second resolve pass when needed.
-//      B. Gather all input constants.
-//        - Gathering constants directly adds unresolved values to work_stack_.
-//      C. If any need to be resolved (HasNewWork), return Invalid; this
-//         instruction needs two calls to complete.
-//      D. Build any necessary IR structures, and return the output constant.
-//    - For trivial cases with zero or one input constants, this may return
-//      a constant (if one, potentially Invalid) directly.
-// 3. If resolving returned a non-Invalid constant, pop the work; otherwise, it
-//    needs to remain (and may no longer be at the top of the stack).
+//    - For instructions that can be forward declared, if we don't already have
+//      a constant value from a previous attempt at resolution, start by making
+//      a forward declared constant value to address circular references.
+//    - Gather all input constants.
+//      - Gathering constants directly adds unresolved values to work_stack_.
+//    - If any need to be resolved (HasNewWork), return Retry(): this
+//      instruction needs two calls to complete.
+//      - If the constant value is already known because we have made a forward
+//        declaration, pass it to Retry(). It will be passed to future attempts
+//        to resolve this instruction so the earlier work can be found, and will
+//        be made available for other instructions to use.
+//      - The second attempt to resolve this instruction must produce the same
+//        constant, because the value may have already been used by resolved
+//        instructions.
+//    - Build any necessary IR structures, and return the output constant.
+// 3. If resolve didn't return Retry(), pop the work. Otherwise, it needs to
+//    remain, and may no longer be at the top of the stack; set `retry` on it so
+//    we'll make sure to run it again later.
 //
 // TryResolveInst/TryResolveTypedInst can complete in one call for a given
 // instruction, but should always complete within two calls. However, due to the
@@ -61,27 +62,37 @@ class ImportRefResolver {
             context_.import_ir_constant_values()[import_ir_id.index]) {}
 
   // Iteratively resolves an imported instruction's inner references until a
-  // constant ID referencing the current IR is produced. When an outer
-  // instruction has unresolved inner references, it will add them to the stack
-  // for inner evaluation and reattempt outer evaluation after.
+  // constant ID referencing the current IR is produced. See the class comment
+  // for more details.
   auto Resolve(SemIR::InstId inst_id) -> SemIR::ConstantId {
     work_stack_.push_back({inst_id});
     while (!work_stack_.empty()) {
       auto work = work_stack_.back();
       CARBON_CHECK(work.inst_id.is_valid());
 
-      // Double-check that the constant still doesn't have a calculated value.
-      // This should typically be checked before adding it, but a given
-      // instruction may be added multiple times before its constant is
-      // evaluated.
-      if (!work.made_forward_decl &&
-          import_ir_constant_values_.Get(work.inst_id).is_valid()) {
+      // Step 1: check for a constant value.
+      auto existing_const_id = import_ir_constant_values_.Get(work.inst_id);
+      if (existing_const_id.is_valid() && !work.retry) {
         work_stack_.pop_back();
-      } else if (auto new_const_id =
-                     TryResolveInst(work.inst_id, work.made_forward_decl);
-                 new_const_id.is_valid()) {
-        import_ir_constant_values_.Set(work.inst_id, new_const_id);
+        continue;
+      }
+
+      // Step 2: resolve the instruction.
+      auto initial_work = work_stack_.size();
+      auto [new_const_id, finished] =
+          TryResolveInst(work.inst_id, existing_const_id);
+      CARBON_CHECK(finished == !HasNewWork(initial_work));
+
+      CARBON_CHECK(!existing_const_id.is_valid() ||
+                   existing_const_id == new_const_id)
+          << "Constant value changed in second pass.";
+      import_ir_constant_values_.Set(work.inst_id, new_const_id);
+
+      // Step 3: pop or retry.
+      if (finished) {
         work_stack_.pop_back();
+      } else {
+        work_stack_[initial_work - 1].retry = true;
       }
     }
     auto constant_id = import_ir_constant_values_.Get(inst_id);
@@ -112,15 +123,28 @@ class ImportRefResolver {
     // The instruction to work on.
     SemIR::InstId inst_id;
 
-    // True if a first pass made a forward declaration.
-    bool made_forward_decl = false;
+    // True if another pass was requested last time this was run.
+    bool retry = false;
   };
 
-  // For imported entities, we use an invalid enclosing scope. This will be okay
-  // if the scope isn't used later, but we may need to change logic for this if
-  // the behavior changes.
-  static constexpr SemIR::NameScopeId NoEnclosingScopeForImports =
-      SemIR::NameScopeId::Invalid;
+  // The result of attempting to resolve an imported instruction to a constant.
+  struct ResolveResult {
+    // Try resolving this function again. If `const_id` is specified, it will be
+    // passed to the next resolution attempt.
+    static auto Retry(SemIR::ConstantId const_id = SemIR::ConstantId::Invalid)
+        -> ResolveResult {
+      return {.const_id = const_id, .finished = false};
+    }
+
+    // The new constant value, if known.
+    SemIR::ConstantId const_id;
+    // Whether resolution has finished. If false, `TryResolveInst` will be
+    // called again. Note that this is not strictly necessary, and we can get
+    // the same information by checking whether new work was added to the stack.
+    // However, we use this for consistency checks between resolve actions and
+    // the work stack.
+    bool finished = true;
+  };
 
   // Returns true if new unresolved constants were found.
   //
@@ -258,13 +282,48 @@ class ImportRefResolver {
     return import_name_id;
   }
 
+  // Translates a NameScopeId from the import IR to a local NameScopeId. Adds
+  // unresolved constants to the work stack.
+  auto GetLocalNameScopeId(SemIR::NameScopeId name_scope_id)
+      -> SemIR::NameScopeId {
+    auto inst_id = import_ir_.name_scopes().GetInstIdIfValid(name_scope_id);
+    if (!inst_id.is_valid()) {
+      // Map scopes that aren't associated with an instruction to invalid
+      // scopes. For now, such scopes aren't used, and we don't have a good way
+      // to rmmap them.
+      return SemIR::NameScopeId::Invalid;
+    }
+    auto const_id = GetLocalConstantId(inst_id);
+    if (!const_id.is_valid()) {
+      return SemIR::NameScopeId::Invalid;
+    }
+    switch (auto name_scope_inst = context_.insts().Get(const_id.inst_id());
+            name_scope_inst.kind()) {
+      case SemIR::Namespace::Kind:
+        return name_scope_inst.As<SemIR::Namespace>().name_scope_id;
+      case SemIR::ClassType::Kind:
+        return context_.classes()
+            .Get(name_scope_inst.As<SemIR::ClassType>().class_id)
+            .scope_id;
+      case SemIR::InterfaceType::Kind:
+        return context_.interfaces()
+            .Get(name_scope_inst.As<SemIR::InterfaceType>().interface_id)
+            .scope_id;
+      default:
+        if (const_id == SemIR::ConstantId::Error) {
+          return SemIR::NameScopeId::Invalid;
+        }
+        CARBON_FATAL() << "Unexpected instruction kind for name scope: "
+                       << name_scope_inst;
+    }
+  }
+
   // Adds ImportRefUnused 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_.AddPlaceholderInst(
-          SemIR::ImportRefUnused{import_ir_id_, entry_inst_id});
+      auto ref_id = context_.AddImportRef(import_ir_id_, entry_inst_id);
       CARBON_CHECK(
           new_scope.names.insert({GetLocalNameId(entry_name_id), ref_id})
               .second);
@@ -283,8 +342,8 @@ class ImportRefResolver {
     llvm::SmallVector<SemIR::InstId> new_associated_entities;
     new_associated_entities.reserve(associated_entities.size());
     for (auto inst_id : associated_entities) {
-      new_associated_entities.push_back(context_.AddPlaceholderInst(
-          SemIR::ImportRefUnused{import_ir_id_, inst_id}));
+      new_associated_entities.push_back(
+          context_.AddImportRef(import_ir_id_, inst_id));
     }
     return context_.inst_blocks().Add(new_associated_entities);
   }
@@ -293,24 +352,20 @@ class ImportRefResolver {
   // more has been added to the stack. A similar API is followed for all
   // following TryResolveTypedInst helper functions.
   //
+  // `const_id` is Invalid unless we've tried to resolve this instruction
+  // before, in which case it's the previous result.
+  //
   // TODO: Error is returned when support is missing, but that should go away.
-  auto TryResolveInst(SemIR::InstId inst_id, bool made_forward_decl)
-      -> SemIR::ConstantId {
+  auto TryResolveInst(SemIR::InstId inst_id, SemIR::ConstantId const_id)
+      -> ResolveResult {
     if (inst_id.is_builtin()) {
-      CARBON_CHECK(!made_forward_decl);
+      CARBON_CHECK(!const_id.is_valid());
       // Constants for builtins can be directly copied.
-      return context_.constant_values().Get(inst_id);
+      return {context_.constant_values().Get(inst_id)};
     }
 
     auto inst = import_ir_.insts().Get(inst_id);
 
-    CARBON_CHECK(!made_forward_decl ||
-                 inst.kind() == SemIR::InstKind::ClassDecl ||
-                 inst.kind() == SemIR::InstKind::InterfaceDecl)
-        << "Only types that can be involved in cycles should need "
-           "made_forward_decl state: "
-        << inst.kind();
-
     switch (inst.kind()) {
       case SemIR::InstKind::AssociatedEntity:
         return TryResolveTypedInst(inst.As<SemIR::AssociatedEntity>());
@@ -325,8 +380,7 @@ class ImportRefResolver {
         return TryResolveTypedInst(inst.As<SemIR::BindAlias>());
 
       case SemIR::InstKind::ClassDecl:
-        return TryResolveTypedInst(inst.As<SemIR::ClassDecl>(), inst_id,
-                                   made_forward_decl);
+        return TryResolveTypedInst(inst.As<SemIR::ClassDecl>(), const_id);
 
       case SemIR::InstKind::ClassType:
         return TryResolveTypedInst(inst.As<SemIR::ClassType>());
@@ -341,8 +395,7 @@ class ImportRefResolver {
         return TryResolveTypedInst(inst.As<SemIR::FunctionDecl>());
 
       case SemIR::InstKind::InterfaceDecl:
-        return TryResolveTypedInst(inst.As<SemIR::InterfaceDecl>(), inst_id,
-                                   made_forward_decl);
+        return TryResolveTypedInst(inst.As<SemIR::InterfaceDecl>(), const_id);
 
       case SemIR::InstKind::InterfaceType:
         return TryResolveTypedInst(inst.As<SemIR::InterfaceType>());
@@ -361,7 +414,7 @@ class ImportRefResolver {
 
       case SemIR::InstKind::BindName:
         // TODO: This always returns `ConstantId::NotConstant`.
-        return TryEvalInst(context_, inst_id, inst);
+        return {TryEvalInst(context_, inst_id, inst)};
 
       case SemIR::InstKind::BindSymbolicName:
         return TryResolveTypedInst(inst.As<SemIR::BindSymbolicName>());
@@ -370,31 +423,29 @@ class ImportRefResolver {
         context_.TODO(
             Parse::NodeId(Parse::NodeId::Invalid),
             llvm::formatv("TryResolveInst on {0}", inst.kind()).str());
-        return SemIR::ConstantId::Error;
+        return {SemIR::ConstantId::Error};
     }
   }
 
-  auto TryResolveTypedInst(SemIR::AssociatedEntity inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::AssociatedEntity inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     auto type_const_id = GetLocalConstantId(inst.type_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     // Add a lazy reference to the target declaration.
-    auto decl_id = context_.AddPlaceholderInst(
-        SemIR::ImportRefUnused{import_ir_id_, inst.decl_id});
+    auto decl_id = context_.AddImportRef(import_ir_id_, inst.decl_id);
 
     auto inst_id = context_.AddInstInNoBlock(
         {Parse::NodeId::Invalid,
          SemIR::AssociatedEntity{
              context_.GetTypeIdForTypeConstant(type_const_id), inst.index,
              decl_id}});
-    return context_.constant_values().Get(inst_id);
+    return {context_.constant_values().Get(inst_id)};
   }
 
-  auto TryResolveTypedInst(SemIR::AssociatedEntityType inst)
-      -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::AssociatedEntityType inst) -> ResolveResult {
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
 
     auto initial_work = work_stack_.size();
@@ -402,7 +453,7 @@ class ImportRefResolver {
     auto interface_const_id = GetLocalConstantId(
         import_ir_.interfaces().Get(inst.interface_id).decl_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     auto inst_id = context_.AddInstInNoBlock(SemIR::AssociatedEntityType{
@@ -411,15 +462,15 @@ class ImportRefResolver {
             .GetAs<SemIR::InterfaceType>(interface_const_id.inst_id())
             .interface_id,
         context_.GetTypeIdForTypeConstant(entity_type_const_id)});
-    return context_.constant_values().Get(inst_id);
+    return {context_.constant_values().Get(inst_id)};
   }
 
-  auto TryResolveTypedInst(SemIR::BaseDecl inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::BaseDecl inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     auto type_const_id = GetLocalConstantId(inst.type_id);
     auto base_type_const_id = GetLocalConstantId(inst.base_type_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     // Import the instruction in order to update contained base_type_id.
@@ -428,23 +479,23 @@ class ImportRefResolver {
          SemIR::BaseDecl{context_.GetTypeIdForTypeConstant(type_const_id),
                          context_.GetTypeIdForTypeConstant(base_type_const_id),
                          inst.index}});
-    return context_.constant_values().Get(inst_id);
+    return {context_.constant_values().Get(inst_id)};
   }
 
-  auto TryResolveTypedInst(SemIR::BindAlias inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::BindAlias inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     auto value_id = GetLocalConstantId(inst.value_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
-    return value_id;
+    return {value_id};
   }
 
-  auto TryResolveTypedInst(SemIR::BindSymbolicName inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::BindSymbolicName inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     auto type_id = GetLocalConstantId(inst.type_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     auto name_id =
@@ -456,14 +507,13 @@ class ImportRefResolver {
         {Parse::NodeId::Invalid,
          SemIR::BindSymbolicName{context_.GetTypeIdForTypeConstant(type_id),
                                  bind_name_id, SemIR::InstId::Invalid}});
-    return context_.constant_values().Get(new_bind_id);
+    return {context_.constant_values().Get(new_bind_id)};
   }
 
   // Makes an incomplete class. This is necessary even with classes with a
   // complete declaration, because things such as `Self` may refer back to the
   // type.
-  auto MakeIncompleteClass(SemIR::InstId inst_id,
-                           const SemIR::Class& import_class)
+  auto MakeIncompleteClass(const SemIR::Class& import_class)
       -> SemIR::ConstantId {
     auto class_decl =
         SemIR::ClassDecl{SemIR::TypeId::Invalid, SemIR::ClassId::Invalid,
@@ -474,7 +524,8 @@ class ImportRefResolver {
     // incomplete type so that any references have something to point at.
     class_decl.class_id = context_.classes().Add({
         .name_id = GetLocalNameId(import_class.name_id),
-        .enclosing_scope_id = NoEnclosingScopeForImports,
+        // Set in the second pass once we've imported it.
+        .enclosing_scope_id = SemIR::NameScopeId::Invalid,
         // `.self_type_id` depends on the ClassType, so is set below.
         .self_type_id = SemIR::TypeId::Invalid,
         .decl_id = class_decl_id,
@@ -489,22 +540,14 @@ class ImportRefResolver {
     // Build the `Self` type using the resulting type constant.
     auto& class_info = context_.classes().Get(class_decl.class_id);
     class_info.self_type_id = context_.GetTypeIdForTypeConstant(self_const_id);
-
-    // Set a constant corresponding to the incomplete class.
-    import_ir_constant_values_.Set(inst_id, self_const_id);
     return self_const_id;
   }
 
   // Fills out the class definition for an incomplete class.
   auto AddClassDefinition(const SemIR::Class& import_class,
-                          SemIR::ConstantId class_const_id,
+                          SemIR::Class& new_class,
                           SemIR::ConstantId object_repr_const_id,
                           SemIR::ConstantId base_const_id) -> void {
-    auto& new_class = context_.classes().Get(
-        context_.insts()
-            .GetAs<SemIR::ClassType>(class_const_id.inst_id())
-            .class_id);
-
     new_class.object_repr_id =
         context_.GetTypeIdForTypeConstant(object_repr_const_id);
 
@@ -535,89 +578,86 @@ class ImportRefResolver {
                  import_scope.extended_scopes.size());
   }
 
-  auto TryResolveTypedInst(SemIR::ClassDecl inst, SemIR::InstId inst_id,
-                           bool made_forward_decl) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::ClassDecl inst,
+                           SemIR::ConstantId class_const_id) -> ResolveResult {
     const auto& import_class = import_ir_.classes().Get(inst.class_id);
 
-    SemIR::ConstantId class_const_id = SemIR::ConstantId::Invalid;
-    // On the first pass, there's no incomplete type; start by adding one for
-    // any recursive references.
-    if (!made_forward_decl) {
-      class_const_id = MakeIncompleteClass(inst_id, import_class);
-      // If there's only a forward declaration, we're done.
-      if (!import_class.is_defined()) {
-        return class_const_id;
-      }
-      // This may not be needed because all constants might be ready, but we do
-      // it here so that we don't need to track which work item corresponds to
-      // this instruction.
-      work_stack_.back().made_forward_decl = true;
+    // On the first pass, create a forward declaration of the class for any
+    // recursive references.
+    if (!class_const_id.is_valid()) {
+      class_const_id = MakeIncompleteClass(import_class);
     }
 
-    CARBON_CHECK(import_class.is_defined())
-        << "Only reachable when there's a definition.";
-
     // Load constants for the definition.
     auto initial_work = work_stack_.size();
 
-    auto object_repr_const_id = GetLocalConstantId(import_class.object_repr_id);
+    auto enclosing_scope_id =
+        GetLocalNameScopeId(import_class.enclosing_scope_id);
+    auto object_repr_const_id =
+        import_class.object_repr_id.is_valid()
+            ? GetLocalConstantId(import_class.object_repr_id)
+            : SemIR::ConstantId::Invalid;
     auto base_const_id = import_class.base_id.is_valid()
                              ? GetLocalConstantId(import_class.base_id)
                              : SemIR::ConstantId::Invalid;
 
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry(class_const_id);
     }
 
-    // On the first pass, we build the incomplete type's constant above. If we
-    // get here on a subsequent pass we need to fetch the one we built in the
-    // first pass.
-    if (made_forward_decl) {
-      CARBON_CHECK(!class_const_id.is_valid())
-          << "Shouldn't have a const yet when resuming";
-      class_const_id = import_ir_constant_values_.Get(inst_id);
+    auto& new_class = context_.classes().Get(
+        context_.insts()
+            .GetAs<SemIR::ClassType>(class_const_id.inst_id())
+            .class_id);
+    new_class.enclosing_scope_id = enclosing_scope_id;
+
+    if (import_class.is_defined()) {
+      AddClassDefinition(import_class, new_class, object_repr_const_id,
+                         base_const_id);
     }
-    AddClassDefinition(import_class, class_const_id, object_repr_const_id,
-                       base_const_id);
 
-    return class_const_id;
+    return {class_const_id};
   }
 
-  auto TryResolveTypedInst(SemIR::ClassType inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::ClassType inst) -> ResolveResult {
+    auto initial_work = work_stack_.size();
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
-    // ClassType uses a straight reference to the constant ID generated as part
-    // of pulling in the ClassDecl, so there's no need to phase logic.
-    return GetLocalConstantId(import_ir_.classes().Get(inst.class_id).decl_id);
+    auto class_const_id =
+        GetLocalConstantId(import_ir_.classes().Get(inst.class_id).decl_id);
+    if (HasNewWork(initial_work)) {
+      return ResolveResult::Retry();
+    }
+    return {class_const_id};
   }
 
-  auto TryResolveTypedInst(SemIR::ConstType inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::ConstType inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
     auto inner_const_id = GetLocalConstantId(inst.inner_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
     auto inner_type_id = context_.GetTypeIdForTypeConstant(inner_const_id);
     // TODO: Should ConstType have a wrapper for this similar to the others?
-    return TryEvalInst(
-        context_, SemIR::InstId::Invalid,
-        SemIR::ConstType{SemIR::TypeId::TypeType, inner_type_id});
+    return {
+        TryEvalInst(context_, SemIR::InstId::Invalid,
+                    SemIR::ConstType{SemIR::TypeId::TypeType, inner_type_id})};
   }
 
-  auto TryResolveTypedInst(SemIR::FieldDecl inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::FieldDecl inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     auto const_id = GetLocalConstantId(inst.type_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
     auto inst_id = context_.AddInstInNoBlock(
         {Parse::NodeId::Invalid,
          SemIR::FieldDecl{context_.GetTypeIdForTypeConstant(const_id),
                           GetLocalNameId(inst.name_id), inst.index}});
-    return context_.constant_values().Get(inst_id);
+    return {context_.constant_values().Get(inst_id)};
   }
 
-  auto TryResolveTypedInst(SemIR::FunctionDecl inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::FunctionDecl inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     auto type_const_id = GetLocalConstantId(inst.type_id);
 
@@ -630,13 +670,14 @@ class ImportRefResolver {
     if (function.return_slot_id.is_valid()) {
       return_slot_const_id = GetLocalConstantId(function.return_slot_id);
     }
+    auto enclosing_scope_id = GetLocalNameScopeId(function.enclosing_scope_id);
     llvm::SmallVector<SemIR::ConstantId> implicit_param_const_ids =
         GetLocalParamConstantIds(function.implicit_param_refs_id);
     llvm::SmallVector<SemIR::ConstantId> param_const_ids =
         GetLocalParamConstantIds(function.param_refs_id);
 
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     // Add the function declaration.
@@ -658,7 +699,7 @@ class ImportRefResolver {
     }
     function_decl.function_id = context_.functions().Add(
         {.name_id = GetLocalNameId(function.name_id),
-         .enclosing_scope_id = NoEnclosingScopeForImports,
+         .enclosing_scope_id = enclosing_scope_id,
          .decl_id = function_decl_id,
          .implicit_param_refs_id = GetLocalParamRefsId(
              function.implicit_param_refs_id, implicit_param_const_ids),
@@ -669,13 +710,12 @@ class ImportRefResolver {
     // Write the function ID into the FunctionDecl.
     context_.ReplaceInstBeforeConstantUse(
         function_decl_id, {Parse::NodeId::Invalid, function_decl});
-    return context_.constant_values().Get(function_decl_id);
+    return {context_.constant_values().Get(function_decl_id)};
   }
 
   // Make a declaration of an interface. This is done as a separate step from
   // importing the interface definition in order to resolve cycles.
-  auto MakeInterfaceDecl(SemIR::InstId inst_id,
-                         const SemIR::Interface& import_interface)
+  auto MakeInterfaceDecl(const SemIR::Interface& import_interface)
       -> SemIR::ConstantId {
     auto interface_decl = SemIR::InterfaceDecl{SemIR::TypeId::Invalid,
                                                SemIR::InterfaceId::Invalid,
@@ -686,7 +726,8 @@ class ImportRefResolver {
     // Start with an incomplete interface.
     SemIR::Interface new_interface = {
         .name_id = GetLocalNameId(import_interface.name_id),
-        .enclosing_scope_id = NoEnclosingScopeForImports,
+        // Set in the second pass once we've imported it.
+        .enclosing_scope_id = SemIR::NameScopeId::Invalid,
         .decl_id = interface_decl_id,
     };
 
@@ -696,20 +737,14 @@ class ImportRefResolver {
         interface_decl_id, {Parse::NodeId::Invalid, interface_decl});
 
     // Set the constant value for the imported interface.
-    auto interface_const_id = context_.constant_values().Get(interface_decl_id);
-    import_ir_constant_values_.Set(inst_id, interface_const_id);
-    return interface_const_id;
+    return context_.constant_values().Get(interface_decl_id);
   }
 
   // Imports the definition for an interface that has been imported as a forward
   // declaration.
   auto AddInterfaceDefinition(const SemIR::Interface& import_interface,
-                              SemIR::ConstantId interface_const_id,
+                              SemIR::Interface& new_interface,
                               SemIR::ConstantId self_param_id) -> void {
-    auto& new_interface = context_.interfaces().Get(
-        context_.insts()
-            .GetAs<SemIR::InterfaceType>(interface_const_id.inst_id())
-            .interface_id);
     new_interface.scope_id = context_.name_scopes().Add(
         new_interface.decl_id, SemIR::NameId::Invalid,
         new_interface.enclosing_scope_id);
@@ -729,58 +764,64 @@ class ImportRefResolver {
         << "Interfaces don't currently have extended scopes to support.";
   }
 
-  auto TryResolveTypedInst(SemIR::InterfaceDecl inst, SemIR::InstId inst_id,
-                           bool made_forward_decl) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::InterfaceDecl inst,
+                           SemIR::ConstantId interface_const_id)
+      -> ResolveResult {
     const auto& import_interface =
         import_ir_.interfaces().Get(inst.interface_id);
 
     // On the first pass, create a forward declaration of the interface.
-    if (!made_forward_decl) {
-      auto interface_const_id = MakeInterfaceDecl(inst_id, import_interface);
-      if (!import_interface.is_defined()) {
-        return interface_const_id;
-      }
-      // Track that we need another pass. We always will, because the type of
-      // the `Self` binding refers to the interface.
-      work_stack_.back().made_forward_decl = true;
+    if (!interface_const_id.is_valid()) {
+      interface_const_id = MakeInterfaceDecl(import_interface);
     }
 
     auto initial_work = work_stack_.size();
+
+    auto enclosing_scope_id =
+        GetLocalNameScopeId(import_interface.enclosing_scope_id);
     auto self_param_id = GetLocalConstantId(import_interface.self_param_id);
+
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry(interface_const_id);
     }
 
-    // Add the interface definition.
-    CARBON_CHECK(import_interface.is_defined())
-        << "Should not need second pass for undefined interface.";
-    auto interface_const_id = import_ir_constant_values_.Get(inst_id);
-    AddInterfaceDefinition(import_interface, interface_const_id, self_param_id);
-    return interface_const_id;
+    auto& new_interface = context_.interfaces().Get(
+        context_.insts()
+            .GetAs<SemIR::InterfaceType>(interface_const_id.inst_id())
+            .interface_id);
+    new_interface.enclosing_scope_id = enclosing_scope_id;
+
+    if (import_interface.is_defined()) {
+      AddInterfaceDefinition(import_interface, new_interface, self_param_id);
+    }
+    return {interface_const_id};
   }
 
-  auto TryResolveTypedInst(SemIR::InterfaceType inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::InterfaceType inst) -> ResolveResult {
+    auto initial_work = work_stack_.size();
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
-    // InterfaceType uses a straight reference to the constant ID generated as
-    // part of pulling in the InterfaceDecl, so there's no need to phase logic.
-    return GetLocalConstantId(
+    auto interface_const_id = GetLocalConstantId(
         import_ir_.interfaces().Get(inst.interface_id).decl_id);
+    if (HasNewWork(initial_work)) {
+      return ResolveResult::Retry();
+    }
+    return {interface_const_id};
   }
 
-  auto TryResolveTypedInst(SemIR::PointerType inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::PointerType inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
     auto pointee_const_id = GetLocalConstantId(inst.pointee_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     auto pointee_type_id = context_.GetTypeIdForTypeConstant(pointee_const_id);
-    return context_.types().GetConstantId(
-        context_.GetPointerType(pointee_type_id));
+    return {context_.types().GetConstantId(
+        context_.GetPointerType(pointee_type_id))};
   }
 
-  auto TryResolveTypedInst(SemIR::StructType inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::StructType inst) -> ResolveResult {
     // Collect all constants first, locating unresolved ones in a single pass.
     auto initial_work = work_stack_.size();
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
@@ -792,7 +833,7 @@ class ImportRefResolver {
       field_const_ids.push_back(GetLocalConstantId(field.field_type_id));
     }
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     // Prepare a vector of fields for GetStructType.
@@ -811,11 +852,11 @@ class ImportRefResolver {
                                   .field_type_id = field_type_id}}));
     }
 
-    return context_.types().GetConstantId(
-        context_.GetStructType(context_.inst_blocks().Add(fields)));
+    return {context_.types().GetConstantId(
+        context_.GetStructType(context_.inst_blocks().Add(fields)))};
   }
 
-  auto TryResolveTypedInst(SemIR::TupleType inst) -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::TupleType inst) -> ResolveResult {
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
 
     // Collect all constants first, locating unresolved ones in a single pass.
@@ -827,7 +868,7 @@ class ImportRefResolver {
       elem_const_ids.push_back(GetLocalConstantId(elem_type_id));
     }
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
     // Prepare a vector of the tuple types for GetTupleType.
@@ -837,22 +878,22 @@ class ImportRefResolver {
       elem_type_ids.push_back(context_.GetTypeIdForTypeConstant(elem_const_id));
     }
 
-    return context_.types().GetConstantId(context_.GetTupleType(elem_type_ids));
+    return {
+        context_.types().GetConstantId(context_.GetTupleType(elem_type_ids))};
   }
 
-  auto TryResolveTypedInst(SemIR::UnboundElementType inst)
-      -> SemIR::ConstantId {
+  auto TryResolveTypedInst(SemIR::UnboundElementType inst) -> ResolveResult {
     auto initial_work = work_stack_.size();
     CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
     auto class_const_id = GetLocalConstantId(inst.class_type_id);
     auto elem_const_id = GetLocalConstantId(inst.element_type_id);
     if (HasNewWork(initial_work)) {
-      return SemIR::ConstantId::Invalid;
+      return ResolveResult::Retry();
     }
 
-    return context_.types().GetConstantId(context_.GetUnboundElementType(
+    return {context_.types().GetConstantId(context_.GetUnboundElementType(
         context_.GetTypeIdForTypeConstant(class_const_id),
-        context_.GetTypeIdForTypeConstant(elem_const_id)));
+        context_.GetTypeIdForTypeConstant(elem_const_id)))};
   }
 
   Context& context_;

+ 8 - 0
toolchain/check/inst_block_stack.h

@@ -64,6 +64,14 @@ class InstBlockStack {
     stack_[size_ - 1].content.push_back(inst_id);
   }
 
+  // Adds the given instruction ID to the block at the bottom of the stack.
+  //
+  // TODO: We shouldn't need to do this.
+  auto AddInstIdToFileBlock(SemIR::InstId inst_id) -> void {
+    CARBON_CHECK(!empty()) << "no current block";
+    stack_[0].content.push_back(inst_id);
+  }
+
   // Returns whether the current block is statically reachable.
   auto is_current_block_reachable() -> bool {
     return size_ != 0 &&

+ 10 - 13
toolchain/check/testdata/class/cross_package_import.carbon

@@ -152,18 +152,17 @@ 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.1: type = import_ref ir1, inst+1, used [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:   %import_ref.2 = import_ref ir1, inst+2, unused
+// 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
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT:   .Self = file.%import_ref.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
@@ -225,7 +224,8 @@ var c: Other.C = {};
 // 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:   %C.decl.1: invalid = class_decl @C.1 [template = constants.%C.1] {}
-// CHECK:STDOUT:   %import_ref.2: type = import_ref ir2, inst+1, used [template = constants.%C.2]
+// 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:   %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
@@ -233,10 +233,8 @@ var c: Other.C = {};
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C.1 {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT:   .Self = file.%import_ref.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C.2;
@@ -269,17 +267,16 @@ var c: Other.C = {};
 // 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:   %C.decl: invalid = class_decl @C.2 [template = constants.%C] {}
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, used [template = imports.%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:   %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
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C.2 {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT:   .Self = file.%import_ref.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @C.1();

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

@@ -75,6 +75,7 @@ var a: Incomplete;
 // 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:   %.decl: type = class_decl @.1 [template = constants.%.2] {
 // CHECK:STDOUT:     %Empty.decl: invalid = class_decl @Empty [template = constants.%Empty] {}
 // CHECK:STDOUT:   }
@@ -85,10 +86,8 @@ var a: Incomplete;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Empty {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT:   .Self = file.%import_ref.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @.1 {

+ 32 - 23
toolchain/check/testdata/class/import.carbon

@@ -126,8 +126,9 @@ fn Run() {
 // CHECK:STDOUT:   %.8: Field = struct_value (%.7) [template]
 // CHECK:STDOUT:   %.9: type = unbound_element_type Field, i32 [template]
 // CHECK:STDOUT:   %.10: i32 = int_literal 2 [template]
-// CHECK:STDOUT:   %ForwardDeclared: type = class_type @ForwardDeclared [template]
+// CHECK:STDOUT:   %ForwardDeclared.1: type = class_type @ForwardDeclared.1 [template]
 // CHECK:STDOUT:   %.11: ForwardDeclared = struct_value () [template]
+// CHECK:STDOUT:   %ForwardDeclared.2: type = class_type @ForwardDeclared.2 [template]
 // CHECK:STDOUT:   %.12: type = ptr_type ForwardDeclared [template]
 // CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete [template]
 // CHECK:STDOUT:   %.13: type = ptr_type Incomplete [template]
@@ -143,36 +144,43 @@ fn 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]
+// 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:   %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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Empty {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT:   .Self = file.%import_ref.5
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Field {
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+5, unused
-// CHECK:STDOUT:   %import_ref.2: <unbound element of class Field> = import_ref ir1, inst+7, used [template = imports.%.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref.1
-// CHECK:STDOUT:   .x = %import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.6
+// CHECK:STDOUT:   .x = file.%import_ref.7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @ForwardDeclared {
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+12, unused
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+24, used [template = imports.%G]
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, used [template = imports.%F]
+// CHECK:STDOUT: class @ForwardDeclared.1 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = file.%import_ref.8
+// CHECK:STDOUT:   .G = file.%import_ref.9
+// CHECK:STDOUT:   .F = file.%import_ref.10
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: class @ForwardDeclared.2 {
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref.1
-// CHECK:STDOUT:   .G = %import_ref.2
-// CHECK:STDOUT:   .F = %import_ref.3
+// CHECK:STDOUT:   .Self = file.%import_ref.11
+// CHECK:STDOUT:   .G = file.%import_ref.12
+// CHECK:STDOUT:   .F = file.%import_ref.13
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Incomplete;
@@ -199,12 +207,12 @@ fn Run() {
 // CHECK:STDOUT:   %.loc9_25.5: init Field = converted %.loc9_25.1, %.loc9_25.4 [template = constants.%.8]
 // CHECK:STDOUT:   assign %b.var, %.loc9_25.5
 // CHECK:STDOUT:   %b.ref: ref Field = name_ref b, %b
-// CHECK:STDOUT:   %x.ref: <unbound element of class Field> = name_ref x, @Field.%import_ref.2 [template = imports.%.1]
+// CHECK:STDOUT:   %x.ref: <unbound element of class Field> = name_ref x, file.%import_ref.7 [template = imports.%.1]
 // CHECK:STDOUT:   %.loc10_4: ref i32 = class_element_access %b.ref, element0
 // CHECK:STDOUT:   %.loc10_9: i32 = int_literal 2 [template = constants.%.10]
 // CHECK:STDOUT:   assign %.loc10_4, %.loc10_9
-// CHECK:STDOUT:   %ForwardDeclared.decl: invalid = class_decl @ForwardDeclared [template = constants.%ForwardDeclared] {}
-// CHECK:STDOUT:   %ForwardDeclared.ref.loc12: type = name_ref ForwardDeclared, file.%import_ref.3 [template = constants.%ForwardDeclared]
+// CHECK:STDOUT:   %ForwardDeclared.decl.1: invalid = class_decl @ForwardDeclared.1 [template = constants.%ForwardDeclared.1] {}
+// CHECK:STDOUT:   %ForwardDeclared.ref.loc12: type = name_ref ForwardDeclared, file.%import_ref.3 [template = constants.%ForwardDeclared.1]
 // CHECK:STDOUT:   %c.var: ref ForwardDeclared = var c
 // CHECK:STDOUT:   %c: ref ForwardDeclared = bind_name c, %c.var
 // CHECK:STDOUT:   %.loc12_29.1: {} = struct_literal ()
@@ -212,16 +220,17 @@ fn Run() {
 // CHECK:STDOUT:   %.loc12_29.3: init ForwardDeclared = converted %.loc12_29.1, %.loc12_29.2 [template = constants.%.11]
 // CHECK:STDOUT:   assign %c.var, %.loc12_29.3
 // CHECK:STDOUT:   %c.ref.loc13: ref ForwardDeclared = name_ref c, %c
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @ForwardDeclared.%import_ref.3 [template = imports.%F]
+// CHECK:STDOUT:   %ForwardDeclared.decl.2: invalid = class_decl @ForwardDeclared.2 [template = constants.%ForwardDeclared.2] {}
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%import_ref.10 [template = imports.%F]
 // CHECK:STDOUT:   %.loc13_4: <bound method> = bound_method %c.ref.loc13, %F.ref
 // CHECK:STDOUT:   %.loc13_3: ForwardDeclared = bind_value %c.ref.loc13
 // CHECK:STDOUT:   %.loc13_6: init () = call %.loc13_4(%.loc13_3)
 // CHECK:STDOUT:   %c.ref.loc14: ref ForwardDeclared = name_ref c, %c
-// CHECK:STDOUT:   %G.ref: <function> = name_ref G, @ForwardDeclared.%import_ref.2 [template = imports.%G]
+// CHECK:STDOUT:   %G.ref: <function> = name_ref G, file.%import_ref.9 [template = imports.%G]
 // CHECK:STDOUT:   %.loc14_4: <bound method> = bound_method %c.ref.loc14, %G.ref
 // CHECK:STDOUT:   %.loc14_3: ForwardDeclared* = addr_of %c.ref.loc14
 // CHECK:STDOUT:   %.loc14_6: init () = call %.loc14_4(%.loc14_3)
-// CHECK:STDOUT:   %ForwardDeclared.ref.loc16: type = name_ref ForwardDeclared, file.%import_ref.3 [template = constants.%ForwardDeclared]
+// CHECK:STDOUT:   %ForwardDeclared.ref.loc16: type = name_ref ForwardDeclared, file.%import_ref.3 [template = constants.%ForwardDeclared.1]
 // CHECK:STDOUT:   %.loc16_25: type = ptr_type ForwardDeclared [template = constants.%.12]
 // CHECK:STDOUT:   %d.var: ref ForwardDeclared* = var d
 // CHECK:STDOUT:   %d: ref ForwardDeclared* = bind_name d, %d.var

+ 16 - 18
toolchain/check/testdata/class/import_base.carbon

@@ -119,31 +119,29 @@ fn Run() {
 // 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:   %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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Child {
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+20, unused
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref.1
-// CHECK:STDOUT:   .base = %import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.8
+// CHECK:STDOUT:   .base = file.%import_ref.9
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+6, used [template = imports.%F]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.3: <unbound element of class Base> = import_ref ir1, inst+12, used [template = imports.%.1]
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+10, unused
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .F = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   .x = %import_ref.3
-// CHECK:STDOUT:   .Unused = %import_ref.4
-// CHECK:STDOUT:   .unused = %import_ref.5
+// CHECK:STDOUT:   .F = file.%import_ref.3
+// CHECK:STDOUT:   .Self = file.%import_ref.4
+// CHECK:STDOUT:   .x = file.%import_ref.5
+// CHECK:STDOUT:   .Unused = file.%import_ref.6
+// CHECK:STDOUT:   .unused = file.%import_ref.7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
@@ -168,14 +166,14 @@ fn Run() {
 // CHECK:STDOUT:   %.loc7_48.4: init Child = converted %.loc7_48.1, %.loc7_48.3 [template = constants.%.11]
 // CHECK:STDOUT:   assign %a.var, %.loc7_48.4
 // CHECK:STDOUT:   %a.ref.loc8: ref Child = name_ref a, %a
-// CHECK:STDOUT:   %x.ref: <unbound element of class Base> = name_ref x, @Base.%import_ref.3 [template = imports.%.1]
+// CHECK:STDOUT:   %x.ref: <unbound element of class Base> = name_ref x, file.%import_ref.5 [template = imports.%.1]
 // CHECK:STDOUT:   %.loc8_4.1: ref Base = class_element_access %a.ref.loc8, element0
 // CHECK:STDOUT:   %.loc8_3: ref Base = converted %a.ref.loc8, %.loc8_4.1
 // CHECK:STDOUT:   %.loc8_4.2: ref i32 = class_element_access %.loc8_3, element0
 // CHECK:STDOUT:   %.loc8_9: i32 = int_literal 2 [template = constants.%.13]
 // CHECK:STDOUT:   assign %.loc8_4.2, %.loc8_9
 // CHECK:STDOUT:   %a.ref.loc9: ref Child = name_ref a, %a
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%import_ref.1 [template = imports.%F]
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%import_ref.3 [template = imports.%F]
 // CHECK:STDOUT:   %.loc9_4: <bound method> = bound_method %a.ref.loc9, %F.ref
 // CHECK:STDOUT:   %.loc9_6.1: ref Base = class_element_access %a.ref.loc9, element0
 // CHECK:STDOUT:   %.loc9_3.1: ref Base = converted %a.ref.loc9, %.loc9_6.1

+ 7 - 8
toolchain/check/testdata/class/import_member_cycle.carbon

@@ -58,26 +58,25 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [template] {
-// CHECK:STDOUT:     .Cycle = %import_ref
+// CHECK:STDOUT:     .Cycle = %import_ref.1
 // CHECK:STDOUT:     .Run = %Run
 // CHECK:STDOUT:   }
-// CHECK:STDOUT:   %import_ref: type = import_ref ir1, inst+1, used [template = constants.%Cycle]
+// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Cycle {
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+7, unused
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .a = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
+// CHECK:STDOUT:   .a = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Cycle.decl: invalid = class_decl @Cycle [template = constants.%Cycle] {}
-// CHECK:STDOUT:   %Cycle.ref: type = name_ref Cycle, file.%import_ref [template = constants.%Cycle]
+// CHECK:STDOUT:   %Cycle.ref: type = name_ref Cycle, file.%import_ref.1 [template = constants.%Cycle]
 // CHECK:STDOUT:   %.loc7: type = ptr_type Cycle [template = constants.%.1]
 // CHECK:STDOUT:   %a.var: ref Cycle* = var a
 // CHECK:STDOUT:   %a: ref Cycle* = bind_name a, %a.var

+ 5 - 6
toolchain/check/testdata/class/import_struct_cyle.carbon

@@ -82,15 +82,14 @@ fn Run() {
 // 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:   %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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Cycle {
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unused
-// CHECK:STDOUT:   %import_ref.2: <unbound element of class Cycle> = import_ref ir1, inst+18, used [template = imports.%.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref.1
-// CHECK:STDOUT:   .c = %import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   .c = file.%import_ref.4
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
@@ -102,7 +101,7 @@ fn Run() {
 // CHECK:STDOUT:   %.loc7_12.1: ref Cycle* = struct_access %a.ref.loc7_11, element0
 // CHECK:STDOUT:   %.loc7_12.2: Cycle* = bind_value %.loc7_12.1
 // CHECK:STDOUT:   %.loc7_10: ref Cycle = deref %.loc7_12.2
-// CHECK:STDOUT:   %c.ref: <unbound element of class Cycle> = name_ref c, @Cycle.%import_ref.2 [template = imports.%.1]
+// CHECK:STDOUT:   %c.ref: <unbound element of class Cycle> = name_ref c, file.%import_ref.4 [template = imports.%.1]
 // CHECK:STDOUT:   %.loc7_15: ref {.b: Cycle*} = class_element_access %.loc7_10, element0
 // CHECK:STDOUT:   %.loc7_17.1: ref Cycle* = struct_access %.loc7_15, element0
 // CHECK:STDOUT:   %.loc7_17.2: Cycle* = bind_value %.loc7_17.1

+ 36 - 39
toolchain/check/testdata/interface/import.carbon

@@ -127,13 +127,13 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT:   %.3: type = interface_type @Basic [template]
 // CHECK:STDOUT:   %.4: type = interface_type @ForwardDeclared [template]
 // CHECK:STDOUT:   %.5: type = assoc_entity_type @Basic, type [template]
-// CHECK:STDOUT:   %.6: <associated type in Basic> = assoc_entity element0, file.%import_ref.5 [template]
+// CHECK:STDOUT:   %.6: <associated type in Basic> = assoc_entity element0, file.%import_ref.16 [template]
 // CHECK:STDOUT:   %.7: type = assoc_entity_type @Basic, <function> [template]
-// CHECK:STDOUT:   %.8: <associated <function> in Basic> = assoc_entity element1, file.%import_ref.6 [template]
+// CHECK:STDOUT:   %.8: <associated <function> in Basic> = assoc_entity element1, file.%import_ref.17 [template]
 // CHECK:STDOUT:   %.9: type = assoc_entity_type @ForwardDeclared, type [template]
-// CHECK:STDOUT:   %.10: <associated type in ForwardDeclared> = assoc_entity element0, file.%import_ref.7 [template]
+// CHECK:STDOUT:   %.10: <associated type in ForwardDeclared> = assoc_entity element0, file.%import_ref.18 [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @ForwardDeclared, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in ForwardDeclared> = assoc_entity element1, file.%import_ref.8 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in ForwardDeclared> = assoc_entity element1, file.%import_ref.19 [template]
 // CHECK:STDOUT:   %.13: type = ptr_type ForwardDeclared [template]
 // CHECK:STDOUT:   %.14: type = struct_type {.f: ForwardDeclared} [template]
 // CHECK:STDOUT:   %.15: type = struct_type {.f: ()} [template]
@@ -158,18 +158,29 @@ var f: ForwardDeclared* = &f_ref.f;
 // 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:   %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:   %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:   %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]
@@ -177,21 +188,21 @@ 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.5 = import_ref ir1, inst+7, unused
-// CHECK:STDOUT:   %T.ref.loc10: <associated type in Basic> = name_ref T, @Basic.%import_ref.3 [template = constants.%.6]
-// CHECK:STDOUT:   %UseBasicT: <associated type in Basic> = bind_alias UseBasicT, @Basic.%import_ref.3 [template = constants.%.6]
+// CHECK:STDOUT:   %import_ref.16 = import_ref ir1, inst+7, unused
+// 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.6 = import_ref ir1, inst+11, unused
-// CHECK:STDOUT:   %F.ref.loc11: <associated <function> in Basic> = name_ref F, @Basic.%import_ref.2 [template = constants.%.8]
-// CHECK:STDOUT:   %UseBasicF: <associated <function> in Basic> = bind_alias UseBasicF, @Basic.%import_ref.2 [template = constants.%.8]
+// CHECK:STDOUT:   %import_ref.17 = import_ref ir1, inst+11, unused
+// 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.7 = import_ref ir1, inst+19, unused
-// CHECK:STDOUT:   %T.ref.loc13: <associated type in ForwardDeclared> = name_ref T, @ForwardDeclared.%import_ref.3 [template = constants.%.10]
-// CHECK:STDOUT:   %UseForwardDeclaredT: <associated type in ForwardDeclared> = bind_alias UseForwardDeclaredT, @ForwardDeclared.%import_ref.3 [template = constants.%.10]
+// CHECK:STDOUT:   %import_ref.18 = import_ref ir1, inst+19, unused
+// 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.8 = import_ref ir1, inst+23, unused
-// CHECK:STDOUT:   %F.ref.loc14: <associated <function> in ForwardDeclared> = name_ref F, @ForwardDeclared.%import_ref.2 [template = constants.%.12]
-// CHECK:STDOUT:   %UseForwardDeclaredF: <associated <function> in ForwardDeclared> = bind_alias UseForwardDeclaredF, @ForwardDeclared.%import_ref.2 [template = constants.%.12]
+// CHECK:STDOUT:   %import_ref.19 = import_ref ir1, inst+23, unused
+// 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]
 // CHECK:STDOUT:   %.loc16: type = ptr_type ForwardDeclared [template = constants.%.13]
 // CHECK:STDOUT:   %f.var: ref ForwardDeclared* = var f
@@ -199,39 +210,25 @@ var f: ForwardDeclared* = &f_ref.f;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Empty {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT:   .Self = file.%import_ref.5
 // CHECK:STDOUT:   witness = ()
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Basic {
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+6, unused
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in Basic> = import_ref ir1, inst+13, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.3: <associated type in Basic> = import_ref ir1, inst+9, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+7, unused
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+11, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref.1
-// CHECK:STDOUT:   .F = %import_ref.2
-// CHECK:STDOUT:   .T = %import_ref.3
-// CHECK:STDOUT:   witness = (%import_ref.4, %import_ref.5)
+// CHECK:STDOUT:   .Self = file.%import_ref.6
+// CHECK:STDOUT:   .F = file.%import_ref.7
+// CHECK:STDOUT:   .T = file.%import_ref.8
+// CHECK:STDOUT:   witness = (file.%import_ref.9, file.%import_ref.10)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @ForwardDeclared {
-// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+18, unused
-// CHECK:STDOUT:   %import_ref.2: <associated <function> in ForwardDeclared> = import_ref ir1, inst+25, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.3: <associated type in ForwardDeclared> = import_ref ir1, inst+21, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+19, unused
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+23, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Self = %import_ref.1
-// CHECK:STDOUT:   .F = %import_ref.2
-// CHECK:STDOUT:   .T = %import_ref.3
-// CHECK:STDOUT:   witness = (%import_ref.4, %import_ref.5)
+// CHECK:STDOUT:   .Self = file.%import_ref.11
+// CHECK:STDOUT:   .F = file.%import_ref.12
+// CHECK:STDOUT:   .T = file.%import_ref.13
+// CHECK:STDOUT:   witness = (file.%import_ref.14, file.%import_ref.15)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @UseEmpty(%e: Empty) {

+ 21 - 23
toolchain/check/testdata/operators/overloaded/add.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @Add, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in Add> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in Add> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @AddAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in AddAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in AddAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %AddAssign.decl: invalid = interface_decl @AddAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %AddAssign.ref: type = name_ref AddAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %AddAssign.ref: type = name_ref AddAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Add {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Add> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @AddAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in AddAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as Add {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 21 - 23
toolchain/check/testdata/operators/overloaded/bit_and.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @BitAnd, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in BitAnd> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in BitAnd> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @BitAndAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in BitAndAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in BitAndAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %BitAndAssign.decl: invalid = interface_decl @BitAndAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %BitAndAssign.ref: type = name_ref BitAndAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %BitAndAssign.ref: type = name_ref BitAndAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitAnd {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in BitAnd> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitAndAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in BitAndAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as BitAnd {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 11 - 12
toolchain/check/testdata/operators/overloaded/bit_complement.carbon

@@ -81,7 +81,7 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:   %.5: C = struct_value () [template]
 // CHECK:STDOUT:   %.6: <witness> = interface_witness (@impl.%Op) [template]
 // CHECK:STDOUT:   %.7: type = assoc_entity_type @BitComplement, <function> [template]
-// CHECK:STDOUT:   %.8: <associated <function> in BitComplement> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.8: <associated <function> in BitComplement> = assoc_entity element0, file.%import_ref.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -92,12 +92,15 @@ 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:   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]
-// CHECK:STDOUT:     %import_ref: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // CHECK:STDOUT:     %BitComplement.decl: invalid = interface_decl @BitComplement [template = constants.%.2] {}
-// CHECK:STDOUT:     %BitComplement.ref: type = name_ref BitComplement, %import_ref [template = constants.%.2]
+// CHECK:STDOUT:     %BitComplement.ref: type = name_ref BitComplement, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc14_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -106,17 +109,15 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitComplement {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in BitComplement> = import_ref ir1, inst+15, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+13, used [template = imports.%Op]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: C as BitComplement {
@@ -152,8 +153,6 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT: fn @TestOp(%a: C) -> %return: C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+13, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Op]
 // CHECK:STDOUT:   %.loc15_10.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc14: ref C = splice_block %return {}

+ 21 - 23
toolchain/check/testdata/operators/overloaded/bit_or.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @BitOr, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in BitOr> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in BitOr> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @BitOrAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in BitOrAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in BitOrAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %BitOrAssign.decl: invalid = interface_decl @BitOrAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %BitOrAssign.ref: type = name_ref BitOrAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %BitOrAssign.ref: type = name_ref BitOrAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitOr {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in BitOr> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitOrAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in BitOrAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as BitOr {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 21 - 23
toolchain/check/testdata/operators/overloaded/bit_xor.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @BitXor, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in BitXor> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in BitXor> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @BitXorAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in BitXorAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in BitXorAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %BitXorAssign.decl: invalid = interface_decl @BitXorAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %BitXorAssign.ref: type = name_ref BitXorAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %BitXorAssign.ref: type = name_ref BitXorAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitXor {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in BitXor> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @BitXorAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in BitXorAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as BitXor {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 11 - 12
toolchain/check/testdata/operators/overloaded/dec.carbon

@@ -81,7 +81,7 @@ fn TestOp() {
 // CHECK:STDOUT:   %.7: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.8: C = struct_value () [template]
 // CHECK:STDOUT:   %.9: type = assoc_entity_type @Dec, <function> [template]
-// CHECK:STDOUT:   %.10: <associated <function> in Dec> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.10: <associated <function> in Dec> = assoc_entity element0, file.%import_ref.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -92,25 +92,26 @@ 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:   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]
-// CHECK:STDOUT:     %import_ref: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // CHECK:STDOUT:     %Dec.decl: invalid = interface_decl @Dec [template = constants.%.2] {}
-// CHECK:STDOUT:     %Dec.ref: type = name_ref Dec, %import_ref [template = constants.%.2]
+// 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Dec {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Dec> = import_ref ir1, inst+14, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+12, used [template = imports.%Op]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: C as Dec {
@@ -147,8 +148,6 @@ fn TestOp() {
 // CHECK:STDOUT:   %.loc13_15.3: init C = converted %.loc13_15.1, %.loc13_15.2 [template = constants.%.8]
 // CHECK:STDOUT:   assign %c.var, %.loc13_15.3
 // CHECK:STDOUT:   %c.ref: ref C = name_ref c, %c
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+12, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Op]
 // CHECK:STDOUT:   %.loc14_3.1: <bound method> = bound_method %c.ref, %.1
 // CHECK:STDOUT:   %.loc14_5: C* = addr_of %c.ref

+ 21 - 23
toolchain/check/testdata/operators/overloaded/div.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @Div, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in Div> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in Div> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @DivAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in DivAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in DivAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %DivAssign.decl: invalid = interface_decl @DivAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %DivAssign.ref: type = name_ref DivAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %DivAssign.ref: type = name_ref DivAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Div {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Div> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @DivAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in DivAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as Div {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 49 - 52
toolchain/check/testdata/operators/overloaded/eq.carbon

@@ -155,8 +155,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %.4: type = tuple_type () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.6: type = assoc_entity_type @Eq, <function> [template]
-// CHECK:STDOUT:   %.7: <associated <function> in Eq> = assoc_entity element0, @TestEqual.%import_ref.2 [template]
-// CHECK:STDOUT:   %.8: <associated <function> in Eq> = assoc_entity element1, @TestNotEqual.%import_ref.2 [template]
+// CHECK:STDOUT:   %.7: <associated <function> in Eq> = assoc_entity element0, file.%import_ref.8 [template]
+// CHECK:STDOUT:   %.8: <associated <function> in Eq> = assoc_entity element1, file.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -168,12 +168,17 @@ 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:   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]
-// CHECK:STDOUT:     %import_ref: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // CHECK:STDOUT:     %Eq.decl: invalid = interface_decl @Eq [template = constants.%.2] {}
-// CHECK:STDOUT:     %Eq.ref: type = name_ref Eq, %import_ref [template = constants.%.2]
+// CHECK:STDOUT:     %Eq.ref: type = name_ref Eq, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestEqual: <function> = fn_decl @TestEqual [template] {
 // CHECK:STDOUT:     %C.ref.loc13_17: type = name_ref C, %C.decl [template = constants.%C]
@@ -184,6 +189,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:   %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
@@ -193,20 +200,16 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Eq {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Eq> = import_ref ir1, inst+17, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <associated <function> in Eq> = import_ref ir1, inst+31, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+15, used [template = imports.%Equal]
-// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir1, inst+30, used [template = imports.%NotEqual]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Equal = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   .NotEqual = %import_ref.3
-// CHECK:STDOUT:   witness = (%import_ref.4, %import_ref.5)
+// CHECK:STDOUT:   .Equal = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   .NotEqual = file.%import_ref.4
+// CHECK:STDOUT:   witness = (file.%import_ref.5, file.%import_ref.6)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: C as Eq {
@@ -253,8 +256,6 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+15, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Equal]
 // CHECK:STDOUT:   %.loc14_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc14_12.2: init bool = call %.loc14_12.1(%a.ref, %b.ref)
@@ -267,8 +268,6 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+30, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element1 [template = @impl.%NotEqual]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc18_12.2: init bool = call %.loc18_12.1(%a.ref, %b.ref)
@@ -286,8 +285,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = interface_type @Eq [template]
 // CHECK:STDOUT:   %.5: type = assoc_entity_type @Eq, <function> [template]
-// CHECK:STDOUT:   %.6: <associated <function> in Eq> = assoc_entity element0, @TestEqual.%import_ref.2 [template]
-// CHECK:STDOUT:   %.7: <associated <function> in Eq> = assoc_entity element1, @TestNotEqual.%import_ref.2 [template]
+// CHECK:STDOUT:   %.6: <associated <function> in Eq> = assoc_entity element0, file.%import_ref.7 [template]
+// CHECK:STDOUT:   %.7: <associated <function> in Eq> = assoc_entity element1, file.%import_ref.9 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -308,6 +307,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:   %TestNotEqual: <function> = fn_decl @TestNotEqual [template] {
 // CHECK:STDOUT:     %D.ref.loc15_20: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc15_17.1: D = param a
@@ -317,20 +323,16 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestNotEqual.%b: D = bind_name b, %b.loc15_23.1
 // CHECK:STDOUT:     %return.var.loc15: 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Eq {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Eq> = import_ref ir1, inst+17, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <associated <function> in Eq> = import_ref ir1, inst+31, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+30, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Equal = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   .NotEqual = %import_ref.3
-// CHECK:STDOUT:   witness = (%import_ref.4, %import_ref.5)
+// CHECK:STDOUT:   .Equal = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   .NotEqual = file.%import_ref.4
+// CHECK:STDOUT:   witness = (file.%import_ref.5, file.%import_ref.6)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @D {
@@ -342,9 +344,7 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: D = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
 // CHECK:STDOUT:   %Eq.decl: invalid = interface_decl @Eq [template = constants.%.4] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+15, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -352,8 +352,6 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: D = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+30, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -368,8 +366,8 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:   %.4: type = tuple_type () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.6: type = assoc_entity_type @Eq, <function> [template]
-// CHECK:STDOUT:   %.7: <associated <function> in Eq> = assoc_entity element0, @TestRhsBad.%import_ref.2 [template]
-// CHECK:STDOUT:   %.8: <associated <function> in Eq> = assoc_entity element1, @TestLhsBad.%import_ref.2 [template]
+// CHECK:STDOUT:   %.7: <associated <function> in Eq> = assoc_entity element0, file.%import_ref.8 [template]
+// CHECK:STDOUT:   %.8: <associated <function> in Eq> = assoc_entity element1, file.%import_ref.10 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -383,12 +381,17 @@ 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:   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]
-// CHECK:STDOUT:     %import_ref: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // CHECK:STDOUT:     %Eq.decl: invalid = interface_decl @Eq [template = constants.%.2] {}
-// CHECK:STDOUT:     %Eq.ref: type = name_ref Eq, %import_ref [template = constants.%.2]
+// CHECK:STDOUT:     %Eq.ref: type = name_ref Eq, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestRhsBad: <function> = fn_decl @TestRhsBad [template] {
 // CHECK:STDOUT:     %C.ref.loc14: type = name_ref C, %C.decl [template = constants.%C]
@@ -399,6 +402,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:   %TestLhsBad: <function> = fn_decl @TestLhsBad [template] {
 // CHECK:STDOUT:     %D.ref.loc24: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc24_15.1: D = param a
@@ -408,20 +413,16 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT:     @TestLhsBad.%b: C = bind_name b, %b.loc24_21.1
 // CHECK:STDOUT:     %return.var.loc24: 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Eq {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Eq> = import_ref ir1, inst+17, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <associated <function> in Eq> = import_ref ir1, inst+31, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.4: <function> = import_ref ir1, inst+15, used [template = imports.%Equal]
-// CHECK:STDOUT:   %import_ref.5: <function> = import_ref ir1, inst+30, used [template = imports.%NotEqual]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Equal = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   .NotEqual = %import_ref.3
-// CHECK:STDOUT:   witness = (%import_ref.4, %import_ref.5)
+// CHECK:STDOUT:   .Equal = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   .NotEqual = file.%import_ref.4
+// CHECK:STDOUT:   witness = (file.%import_ref.5, file.%import_ref.6)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: C as Eq {
@@ -473,8 +474,6 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+15, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Equal]
 // CHECK:STDOUT:   %.loc21_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc21_12.2: init bool = call %.loc21_12.1(<invalid>)
@@ -487,8 +486,6 @@ fn TestLhsBad(a: D, b: C) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: D = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+30, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 21 - 23
toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon

@@ -134,9 +134,9 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT:   %.9: type = tuple_type () [template]
 // CHECK:STDOUT:   %.10: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @Inc, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in Inc> = assoc_entity element0, @TestIncNonRef.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in Inc> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @AddAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in AddAssign> = assoc_entity element0, @TestAddAssignNonRef.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in AddAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -148,25 +148,33 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+16, used [template = constants.%.6]
 // CHECK:STDOUT:     %AddAssign.decl: invalid = interface_decl @AddAssign [template = constants.%.6] {}
-// CHECK:STDOUT:     %AddAssign.ref: type = name_ref AddAssign, %import_ref.2 [template = constants.%.6]
+// CHECK:STDOUT:     %AddAssign.ref: type = name_ref AddAssign, %import_ref.5 [template = constants.%.6]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestIncNonRef: <function> = fn_decl @TestIncNonRef [template] {
 // CHECK:STDOUT:     %C.ref.loc15: type = name_ref C, %C.decl [template = constants.%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:   %TestAddAssignNonRef: <function> = fn_decl @TestAddAssignNonRef [template] {
 // CHECK:STDOUT:     %C.ref.loc25_27: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc25_24.1: C = param a
@@ -175,28 +183,22 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT:     %b.loc25_30.1: C = param b
 // CHECK:STDOUT:     @TestAddAssignNonRef.%b: C = bind_name b, %b.loc25_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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Inc {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Inc> = import_ref ir1, inst+14, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+12, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @AddAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in AddAssign> = import_ref ir1, inst+34, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+32, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as Inc {
@@ -248,8 +250,6 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT: fn @TestIncNonRef(%a: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+12, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc22_3.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc22_3.2: init () = call %.loc22_3.1(<invalid>)
@@ -260,8 +260,6 @@ fn TestAddAssignNonRef(a: C, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+16, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+32, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc32_5.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc32_5.2: init () = call %.loc32_5.1(<invalid>)

+ 36 - 40
toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon

@@ -190,17 +190,17 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = interface_type @Negate [template]
 // CHECK:STDOUT:   %.5: type = assoc_entity_type @Negate, <function> [template]
-// CHECK:STDOUT:   %.6: <associated <function> in Negate> = assoc_entity element0, @TestUnary.%import_ref.2 [template]
+// CHECK:STDOUT:   %.6: <associated <function> in Negate> = assoc_entity element0, file.%import_ref.5 [template]
 // CHECK:STDOUT:   %.7: type = interface_type @Add [template]
 // CHECK:STDOUT:   %.8: type = assoc_entity_type @Add, <function> [template]
-// CHECK:STDOUT:   %.9: <associated <function> in Add> = assoc_entity element0, @TestBinary.%import_ref.2 [template]
+// CHECK:STDOUT:   %.9: <associated <function> in Add> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.10: C = struct_value () [template]
 // CHECK:STDOUT:   %.11: type = interface_type @AddAssign [template]
 // CHECK:STDOUT:   %.12: type = assoc_entity_type @AddAssign, <function> [template]
-// CHECK:STDOUT:   %.13: <associated <function> in AddAssign> = assoc_entity element0, @TestRef.%import_ref.2 [template]
+// CHECK:STDOUT:   %.13: <associated <function> in AddAssign> = assoc_entity element0, file.%import_ref.15 [template]
 // CHECK:STDOUT:   %.14: type = interface_type @Inc [template]
 // CHECK:STDOUT:   %.15: type = assoc_entity_type @Inc, <function> [template]
-// CHECK:STDOUT:   %.16: <associated <function> in Inc> = assoc_entity element0, @TestRef.%import_ref.4 [template]
+// CHECK:STDOUT:   %.16: <associated <function> in Inc> = assoc_entity element0, file.%import_ref.20 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -220,6 +220,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:   %TestBinary: <function> = fn_decl @TestBinary [template] {
 // CHECK:STDOUT:     %C.ref.loc15_18: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %a.loc15_15.1: C = param a
@@ -230,55 +235,54 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:     %C.ref.loc15_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:   %TestRef: <function> = fn_decl @TestRef [template] {
 // CHECK:STDOUT:     %C.ref.loc22: type = name_ref C, %C.decl [template = constants.%C]
 // CHECK:STDOUT:     %b.loc22_12.1: C = param b
 // CHECK:STDOUT:     @TestRef.%b: C = bind_name b, %b.loc22_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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Negate {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Negate> = import_ref ir1, inst+11, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+9, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Add {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Add> = import_ref ir1, inst+32, used [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+30, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.7
+// CHECK:STDOUT:   .Self = file.%import_ref.8
+// CHECK:STDOUT:   witness = (file.%import_ref.9)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @AddAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in AddAssign> = import_ref ir1, inst+52, used [template = constants.%.13]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+36, unused
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+50, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.12
+// CHECK:STDOUT:   .Self = file.%import_ref.13
+// CHECK:STDOUT:   witness = (file.%import_ref.14)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Inc {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Inc> = import_ref ir1, inst+67, used [template = constants.%.16]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+56, unused
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+65, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.17
+// CHECK:STDOUT:   .Self = file.%import_ref.18
+// CHECK:STDOUT:   witness = (file.%import_ref.19)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
@@ -289,9 +293,7 @@ fn TestRef(b: C) {
 // CHECK:STDOUT: fn @TestUnary(%a: C) -> %return: C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
 // CHECK:STDOUT:   %Negate.decl: invalid = interface_decl @Negate [template = constants.%.4] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+9, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -299,9 +301,7 @@ fn TestRef(b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+13, used [template = constants.%.7]
 // CHECK:STDOUT:   %Add.decl: invalid = interface_decl @Add [template = constants.%.7] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+30, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -316,13 +316,9 @@ fn TestRef(b: C) {
 // CHECK:STDOUT:   assign %a.var, %.loc23_15.3
 // CHECK:STDOUT:   %a.ref.loc27: ref C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+34, used [template = constants.%.11]
 // CHECK:STDOUT:   %AddAssign.decl: invalid = interface_decl @AddAssign [template = constants.%.11] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+50, unused
 // CHECK:STDOUT:   %a.ref.loc31: ref C = name_ref a, %a
-// CHECK:STDOUT:   %import_ref.3: type = import_ref ir1, inst+54, used [template = constants.%.14]
 // CHECK:STDOUT:   %Inc.decl: invalid = interface_decl @Inc [template = constants.%.14] {}
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+65, unused
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 21 - 23
toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon

@@ -142,10 +142,10 @@ fn TestAssign(b: D) {
 // CHECK:STDOUT:   %.8: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.9: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.10: type = assoc_entity_type @Add, <function> [template]
-// CHECK:STDOUT:   %.11: <associated <function> in Add> = assoc_entity element0, @Test.%import_ref.2 [template]
+// CHECK:STDOUT:   %.11: <associated <function> in Add> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.12: C = struct_value () [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @AddAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in AddAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in AddAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -159,19 +159,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.6]
 // CHECK:STDOUT:     %AddAssign.decl: invalid = interface_decl @AddAssign [template = constants.%.6] {}
-// CHECK:STDOUT:     %AddAssign.ref: type = name_ref AddAssign, %import_ref.2 [template = constants.%.6]
+// CHECK:STDOUT:     %AddAssign.ref: type = name_ref AddAssign, %import_ref.5 [template = constants.%.6]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %Test: <function> = fn_decl @Test [template] {
 // CHECK:STDOUT:     %C.ref.loc16_12: type = name_ref C, %C.decl [template = constants.%C]
@@ -183,33 +189,29 @@ 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:   %TestAssign: <function> = fn_decl @TestAssign [template] {
 // CHECK:STDOUT:     %D.ref.loc26: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %b.loc26_15.1: D = param b
 // CHECK:STDOUT:     @TestAssign.%b: D = bind_name b, %b.loc26_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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Add {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Add> = import_ref ir1, inst+20, used [template = constants.%.11]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @AddAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in AddAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as Add {
@@ -270,8 +272,6 @@ fn TestAssign(b: D) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc23_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc23_12.2: ref C = temporary_storage
@@ -290,8 +290,6 @@ fn TestAssign(b: D) {
 // CHECK:STDOUT:   assign %a.var, %.loc27_15.3
 // CHECK:STDOUT:   %a.ref: ref C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc34_5.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc34_3: C* = addr_of %a.ref

+ 11 - 12
toolchain/check/testdata/operators/overloaded/inc.carbon

@@ -81,7 +81,7 @@ fn TestOp() {
 // CHECK:STDOUT:   %.7: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.8: C = struct_value () [template]
 // CHECK:STDOUT:   %.9: type = assoc_entity_type @Inc, <function> [template]
-// CHECK:STDOUT:   %.10: <associated <function> in Inc> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.10: <associated <function> in Inc> = assoc_entity element0, file.%import_ref.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -92,25 +92,26 @@ 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:   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]
-// CHECK:STDOUT:     %import_ref: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // CHECK:STDOUT:     %Inc.decl: invalid = interface_decl @Inc [template = constants.%.2] {}
-// CHECK:STDOUT:     %Inc.ref: type = name_ref Inc, %import_ref [template = constants.%.2]
+// 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Inc {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Inc> = import_ref ir1, inst+14, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+12, used [template = imports.%Op]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: C as Inc {
@@ -147,8 +148,6 @@ fn TestOp() {
 // CHECK:STDOUT:   %.loc13_15.3: init C = converted %.loc13_15.1, %.loc13_15.2 [template = constants.%.8]
 // CHECK:STDOUT:   assign %c.var, %.loc13_15.3
 // CHECK:STDOUT:   %c.ref: ref C = name_ref c, %c
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+12, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Op]
 // CHECK:STDOUT:   %.loc14_3.1: <bound method> = bound_method %c.ref, %.1
 // CHECK:STDOUT:   %.loc14_5: C* = addr_of %c.ref

+ 21 - 23
toolchain/check/testdata/operators/overloaded/left_shift.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @LeftShift, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in LeftShift> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in LeftShift> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @LeftShiftAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in LeftShiftAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in LeftShiftAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %LeftShiftAssign.decl: invalid = interface_decl @LeftShiftAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %LeftShiftAssign.ref: type = name_ref LeftShiftAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %LeftShiftAssign.ref: type = name_ref LeftShiftAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @LeftShift {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in LeftShift> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @LeftShiftAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in LeftShiftAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as LeftShift {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 21 - 23
toolchain/check/testdata/operators/overloaded/mod.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @Mod, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in Mod> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in Mod> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @ModAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in ModAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in ModAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %ModAssign.decl: invalid = interface_decl @ModAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %ModAssign.ref: type = name_ref ModAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %ModAssign.ref: type = name_ref ModAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Mod {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Mod> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @ModAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in ModAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as Mod {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 21 - 23
toolchain/check/testdata/operators/overloaded/mul.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @Mul, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in Mul> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in Mul> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @MulAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in MulAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in MulAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %MulAssign.decl: invalid = interface_decl @MulAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %MulAssign.ref: type = name_ref MulAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %MulAssign.ref: type = name_ref MulAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Mul {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Mul> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @MulAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in MulAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as Mul {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 11 - 12
toolchain/check/testdata/operators/overloaded/negate.carbon

@@ -81,7 +81,7 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT:   %.5: C = struct_value () [template]
 // CHECK:STDOUT:   %.6: <witness> = interface_witness (@impl.%Op) [template]
 // CHECK:STDOUT:   %.7: type = assoc_entity_type @Negate, <function> [template]
-// CHECK:STDOUT:   %.8: <associated <function> in Negate> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.8: <associated <function> in Negate> = assoc_entity element0, file.%import_ref.6 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -92,12 +92,15 @@ 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:   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]
-// CHECK:STDOUT:     %import_ref: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // CHECK:STDOUT:     %Negate.decl: invalid = interface_decl @Negate [template = constants.%.2] {}
-// CHECK:STDOUT:     %Negate.ref: type = name_ref Negate, %import_ref [template = constants.%.2]
+// CHECK:STDOUT:     %Negate.ref: type = name_ref Negate, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc14_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -106,17 +109,15 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Negate {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Negate> = import_ref ir1, inst+15, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+13, used [template = imports.%Op]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: C as Negate {
@@ -152,8 +153,6 @@ fn TestOp(a: C) -> C {
 // CHECK:STDOUT: fn @TestOp(%a: C) -> %return: C {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+13, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Op]
 // CHECK:STDOUT:   %.loc15_10.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc14: ref C = splice_block %return {}

+ 56 - 58
toolchain/check/testdata/operators/overloaded/ordered.carbon

@@ -187,10 +187,10 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:   %.4: type = tuple_type () [template]
 // CHECK:STDOUT:   %.5: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.6: type = assoc_entity_type @Ordered, <function> [template]
-// CHECK:STDOUT:   %.7: <associated <function> in Ordered> = assoc_entity element0, @TestLess.%import_ref.2 [template]
-// CHECK:STDOUT:   %.8: <associated <function> in Ordered> = assoc_entity element1, @TestLessEqual.%import_ref.2 [template]
-// CHECK:STDOUT:   %.9: <associated <function> in Ordered> = assoc_entity element2, @TestGreater.%import_ref.2 [template]
-// CHECK:STDOUT:   %.10: <associated <function> in Ordered> = assoc_entity element3, @TestGreaterEqual.%import_ref.2 [template]
+// CHECK:STDOUT:   %.7: <associated <function> in Ordered> = assoc_entity element0, file.%import_ref.12 [template]
+// CHECK:STDOUT:   %.8: <associated <function> in Ordered> = assoc_entity element1, file.%import_ref.14 [template]
+// CHECK:STDOUT:   %.9: <associated <function> in Ordered> = assoc_entity element2, file.%import_ref.16 [template]
+// CHECK:STDOUT:   %.10: <associated <function> in Ordered> = assoc_entity element3, file.%import_ref.18 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -204,12 +204,21 @@ 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:   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]
-// CHECK:STDOUT:     %import_ref: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // CHECK:STDOUT:     %Ordered.decl: invalid = interface_decl @Ordered [template = constants.%.2] {}
-// CHECK:STDOUT:     %Ordered.ref: type = name_ref Ordered, %import_ref [template = constants.%.2]
+// CHECK:STDOUT:     %Ordered.ref: type = name_ref Ordered, %import_ref.1 [template = constants.%.2]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestLess: <function> = fn_decl @TestLess [template] {
 // CHECK:STDOUT:     %C.ref.loc15_16: type = name_ref C, %C.decl [template = constants.%C]
@@ -220,6 +229,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:   %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
@@ -229,6 +240,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:   %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
@@ -238,6 +251,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:   %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
@@ -247,26 +262,18 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Ordered {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Ordered> = import_ref ir1, inst+17, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <associated <function> in Ordered> = import_ref ir1, inst+31, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.4: <associated <function> in Ordered> = import_ref ir1, inst+59, used [template = constants.%.10]
-// CHECK:STDOUT:   %import_ref.5: <associated <function> in Ordered> = import_ref ir1, inst+45, used [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.6: <function> = import_ref ir1, inst+15, used [template = imports.%Less]
-// CHECK:STDOUT:   %import_ref.7: <function> = import_ref ir1, inst+30, used [template = imports.%LessOrEquivalent]
-// CHECK:STDOUT:   %import_ref.8: <function> = import_ref ir1, inst+44, used [template = imports.%Greater]
-// CHECK:STDOUT:   %import_ref.9: <function> = import_ref ir1, inst+58, used [template = imports.%GreaterOrEquivalent]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Less = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   .LessOrEquivalent = %import_ref.3
-// CHECK:STDOUT:   .GreaterOrEquivalent = %import_ref.4
-// CHECK:STDOUT:   .Greater = %import_ref.5
-// CHECK:STDOUT:   witness = (%import_ref.6, %import_ref.7, %import_ref.8, %import_ref.9)
+// CHECK:STDOUT:   .Less = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   .LessOrEquivalent = file.%import_ref.4
+// CHECK:STDOUT:   .GreaterOrEquivalent = file.%import_ref.5
+// CHECK:STDOUT:   .Greater = file.%import_ref.6
+// CHECK:STDOUT:   witness = (file.%import_ref.7, file.%import_ref.8, file.%import_ref.9, file.%import_ref.10)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: C as Ordered {
@@ -341,8 +348,6 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+15, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element0 [template = @impl.%Less]
 // CHECK:STDOUT:   %.loc16_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc16_12.2: init bool = call %.loc16_12.1(%a.ref, %b.ref)
@@ -355,8 +360,6 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+30, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element1 [template = @impl.%LessOrEquivalent]
 // CHECK:STDOUT:   %.loc20_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc20_12.2: init bool = call %.loc20_12.1(%a.ref, %b.ref)
@@ -369,8 +372,6 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+44, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element2 [template = @impl.%Greater]
 // CHECK:STDOUT:   %.loc24_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc24_12.2: init bool = call %.loc24_12.1(%a.ref, %b.ref)
@@ -383,8 +384,6 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+58, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.%.1, element3 [template = @impl.%GreaterOrEquivalent]
 // CHECK:STDOUT:   %.loc28_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc28_12.2: init bool = call %.loc28_12.1(%a.ref, %b.ref)
@@ -402,10 +401,10 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT:   %.4: type = interface_type @Ordered [template]
 // CHECK:STDOUT:   %.5: type = assoc_entity_type @Ordered, <function> [template]
-// CHECK:STDOUT:   %.6: <associated <function> in Ordered> = assoc_entity element0, @TestLess.%import_ref.2 [template]
-// CHECK:STDOUT:   %.7: <associated <function> in Ordered> = assoc_entity element1, @TestLessEqual.%import_ref.2 [template]
-// CHECK:STDOUT:   %.8: <associated <function> in Ordered> = assoc_entity element2, @TestGreater.%import_ref.2 [template]
-// CHECK:STDOUT:   %.9: <associated <function> in Ordered> = assoc_entity element3, @TestGreaterEqual.%import_ref.2 [template]
+// CHECK:STDOUT:   %.6: <associated <function> in Ordered> = assoc_entity element0, file.%import_ref.11 [template]
+// CHECK:STDOUT:   %.7: <associated <function> in Ordered> = assoc_entity element1, file.%import_ref.13 [template]
+// CHECK:STDOUT:   %.8: <associated <function> in Ordered> = assoc_entity element2, file.%import_ref.15 [template]
+// CHECK:STDOUT:   %.9: <associated <function> in Ordered> = assoc_entity element3, file.%import_ref.17 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -428,6 +427,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:   %TestLessEqual: <function> = fn_decl @TestLessEqual [template] {
 // CHECK:STDOUT:     %D.ref.loc15_21: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc15_18.1: D = param a
@@ -437,6 +447,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestLessEqual.%b: D = bind_name b, %b.loc15_24.1
 // CHECK:STDOUT:     %return.var.loc15: 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:   %TestGreater: <function> = fn_decl @TestGreater [template] {
 // CHECK:STDOUT:     %D.ref.loc22_19: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc22_16.1: D = param a
@@ -446,6 +458,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestGreater.%b: D = bind_name b, %b.loc22_22.1
 // CHECK:STDOUT:     %return.var.loc22: 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:   %TestGreaterEqual: <function> = fn_decl @TestGreaterEqual [template] {
 // CHECK:STDOUT:     %D.ref.loc29_24: type = name_ref D, %D.decl [template = constants.%D]
 // CHECK:STDOUT:     %a.loc29_21.1: D = param a
@@ -455,26 +469,18 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT:     @TestGreaterEqual.%b: D = bind_name b, %b.loc29_27.1
 // CHECK:STDOUT:     %return.var.loc29: 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Ordered {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Ordered> = import_ref ir1, inst+17, used [template = constants.%.6]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <associated <function> in Ordered> = import_ref ir1, inst+31, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.4: <associated <function> in Ordered> = import_ref ir1, inst+59, used [template = constants.%.9]
-// CHECK:STDOUT:   %import_ref.5: <associated <function> in Ordered> = import_ref ir1, inst+45, used [template = constants.%.8]
-// CHECK:STDOUT:   %import_ref.6 = import_ref ir1, inst+15, unused
-// CHECK:STDOUT:   %import_ref.7 = import_ref ir1, inst+30, unused
-// CHECK:STDOUT:   %import_ref.8 = import_ref ir1, inst+44, unused
-// CHECK:STDOUT:   %import_ref.9 = import_ref ir1, inst+58, unused
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Less = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   .LessOrEquivalent = %import_ref.3
-// CHECK:STDOUT:   .GreaterOrEquivalent = %import_ref.4
-// CHECK:STDOUT:   .Greater = %import_ref.5
-// CHECK:STDOUT:   witness = (%import_ref.6, %import_ref.7, %import_ref.8, %import_ref.9)
+// CHECK:STDOUT:   .Less = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   .LessOrEquivalent = file.%import_ref.4
+// CHECK:STDOUT:   .GreaterOrEquivalent = file.%import_ref.5
+// CHECK:STDOUT:   .Greater = file.%import_ref.6
+// CHECK:STDOUT:   witness = (file.%import_ref.7, file.%import_ref.8, file.%import_ref.9, file.%import_ref.10)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @D {
@@ -486,9 +492,7 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: D = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
 // CHECK:STDOUT:   %Ordered.decl: invalid = interface_decl @Ordered [template = constants.%.4] {}
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+15, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -496,8 +500,6 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: D = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+30, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -505,8 +507,6 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: D = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+44, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -514,8 +514,6 @@ fn TestGreaterEqual(a: D, b: D) -> bool {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: D = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: D = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.4]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+58, unused
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 21 - 23
toolchain/check/testdata/operators/overloaded/right_shift.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @RightShift, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in RightShift> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in RightShift> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @RightShiftAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in RightShiftAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in RightShiftAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %RightShiftAssign.decl: invalid = interface_decl @RightShiftAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %RightShiftAssign.ref: type = name_ref RightShiftAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %RightShiftAssign.ref: type = name_ref RightShiftAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @RightShift {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in RightShift> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @RightShiftAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in RightShiftAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as RightShift {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 21 - 23
toolchain/check/testdata/operators/overloaded/sub.carbon

@@ -132,9 +132,9 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %.9: type = ptr_type Self [symbolic]
 // CHECK:STDOUT:   %.10: <witness> = interface_witness (@impl.2.%Op) [template]
 // CHECK:STDOUT:   %.11: type = assoc_entity_type @Sub, <function> [template]
-// CHECK:STDOUT:   %.12: <associated <function> in Sub> = assoc_entity element0, @TestOp.%import_ref.2 [template]
+// CHECK:STDOUT:   %.12: <associated <function> in Sub> = assoc_entity element0, file.%import_ref.10 [template]
 // CHECK:STDOUT:   %.13: type = assoc_entity_type @SubAssign, <function> [template]
-// CHECK:STDOUT:   %.14: <associated <function> in SubAssign> = assoc_entity element0, @TestAssign.%import_ref.2 [template]
+// CHECK:STDOUT:   %.14: <associated <function> in SubAssign> = assoc_entity element0, file.%import_ref.12 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -146,19 +146,25 @@ 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:   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:     %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
 // 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:   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]
-// CHECK:STDOUT:     %import_ref.2: type = import_ref ir1, inst+22, used [template = constants.%.7]
 // CHECK:STDOUT:     %SubAssign.decl: invalid = interface_decl @SubAssign [template = constants.%.7] {}
-// CHECK:STDOUT:     %SubAssign.ref: type = name_ref SubAssign, %import_ref.2 [template = constants.%.7]
+// CHECK:STDOUT:     %SubAssign.ref: type = name_ref SubAssign, %import_ref.5 [template = constants.%.7]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %TestOp: <function> = fn_decl @TestOp [template] {
 // CHECK:STDOUT:     %C.ref.loc17_14: type = name_ref C, %C.decl [template = constants.%C]
@@ -170,6 +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:   %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]
@@ -179,28 +187,22 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @Sub {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in Sub> = import_ref ir1, inst+20, used [template = constants.%.12]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+18, used [template = imports.%Op.1]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.2
+// CHECK:STDOUT:   .Self = file.%import_ref.3
+// CHECK:STDOUT:   witness = (file.%import_ref.4)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @SubAssign {
-// CHECK:STDOUT:   %import_ref.1: <associated <function> in SubAssign> = import_ref ir1, inst+40, used [template = constants.%.14]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
-// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+38, used [template = imports.%Op.2]
-// CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .Op = %import_ref.1
-// CHECK:STDOUT:   .Self = %import_ref.2
-// CHECK:STDOUT:   witness = (%import_ref.3)
+// CHECK:STDOUT:   .Op = file.%import_ref.6
+// CHECK:STDOUT:   .Self = file.%import_ref.7
+// CHECK:STDOUT:   witness = (file.%import_ref.8)
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl.1: C as Sub {
@@ -265,8 +267,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.ref: C = name_ref a, %a
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+1, used [template = constants.%.2]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+18, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.1.%.1, element0 [template = @impl.1.%Op]
 // CHECK:STDOUT:   %.loc18_12.1: <bound method> = bound_method %a.ref, %.1
 // CHECK:STDOUT:   %.loc17: ref C = splice_block %return {}
@@ -279,8 +279,6 @@ fn TestAssign(a: C*, b: C) {
 // CHECK:STDOUT:   %a.ref: C* = name_ref a, %a
 // CHECK:STDOUT:   %.loc22_3.1: ref C = deref %a.ref
 // CHECK:STDOUT:   %b.ref: C = name_ref b, %b
-// CHECK:STDOUT:   %import_ref.1: type = import_ref ir1, inst+22, used [template = constants.%.7]
-// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+38, unused
 // CHECK:STDOUT:   %.1: <function> = interface_witness_access @impl.2.%.1, element0 [template = @impl.2.%Op]
 // CHECK:STDOUT:   %.loc22_6.1: <bound method> = bound_method %.loc22_3.1, %.1
 // CHECK:STDOUT:   %.loc22_3.2: C* = addr_of %.loc22_3.1

+ 12 - 13
toolchain/check/testdata/packages/cross_package_import.carbon

@@ -232,17 +232,17 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Other.ref.loc8: <namespace> = name_ref Other, file.%Other [template = file.%Other]
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+1, used [template = imports.%F]
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, %import_ref.1 [template = imports.%F]
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%import_ref.1 [template = imports.%F]
 // CHECK:STDOUT:   %.loc8: init () = call %F.ref()
 // CHECK:STDOUT:   %Other.ref.loc9: <namespace> = name_ref Other, file.%Other [template = file.%Other]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, used [template = imports.%F2]
-// CHECK:STDOUT:   %F2.ref: <function> = name_ref F2, %import_ref.2 [template = imports.%F2]
+// CHECK:STDOUT:   %F2.ref: <function> = name_ref F2, file.%import_ref.2 [template = imports.%F2]
 // CHECK:STDOUT:   %.loc9: init () = call %F2.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -264,14 +264,14 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, file.%Other [template = file.%Other]
-// 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:   %F.ref: <function> = name_ref F, %import_ref.1 [template = imports.%F.1]
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%import_ref.1 [template = imports.%F.1]
 // CHECK:STDOUT:   %.loc17: init () = call %F.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -302,14 +302,14 @@ 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: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Other.ref: <namespace> = name_ref Other, file.%Other [template = file.%Other]
-// 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:   %F.ref: <function> = name_ref F, %import_ref.1 [template = imports.%F.1]
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%import_ref.1 [template = imports.%F.1]
 // CHECK:STDOUT:   %.loc11: init () = call %F.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -326,9 +326,8 @@ fn Other.G() {}
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %import_ref.1: <namespace> = import_ref ir1, inst+1, used
 // CHECK:STDOUT:   %Other: <namespace> = namespace %import_ref.1, [template] {}
-// CHECK:STDOUT:   %.loc19: <function> = fn_decl @.1 [template] {
-// CHECK:STDOUT:     %import_ref.2: <function> = import_ref ir2, inst+1, used [template = imports.%F]
-// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir2, inst+1, used [template = imports.%F]
+// CHECK:STDOUT:   %.loc19: <function> = fn_decl @.1 [template] {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F();

+ 1 - 2
toolchain/lower/file_context.cpp

@@ -91,8 +91,7 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id)
   // Don't lower associated functions.
   // TODO: We shouldn't lower any function that has generic parameters.
   if (sem_ir().insts().Is<SemIR::InterfaceDecl>(
-          sem_ir().name_scopes().GetInstIdIfValid(
-              function.enclosing_scope_id))) {
+          sem_ir().name_scopes().Get(function.enclosing_scope_id).inst_id)) {
     return nullptr;
   }
 

+ 102 - 0
toolchain/lower/testdata/operators/overloaded.carbon

@@ -0,0 +1,102 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+
+// --- prelude.carbon
+
+package Core api;
+
+interface Negate {
+  fn Op[self: Self]() -> Self;
+}
+interface Mul {
+  fn Op[self: Self](other: Self) -> Self;
+}
+
+// --- overloaded.carbon
+
+import Core;
+
+class Number {
+  var is_positive: bool;
+}
+
+impl Number as Core.Negate {
+  fn Op[self: Number]() -> Number {
+    return {.is_positive = not self.is_positive};
+  }
+}
+impl Number as Core.Mul {
+  fn Op[self: Number](other: Number) -> Number {
+    return {.is_positive = (self.is_positive and other.is_positive) or
+                            (not self.is_positive and not other.is_positive)};
+  }
+}
+
+fn Calculate(a: Number, b: Number) -> Number {
+  return -a * b;
+}
+
+// CHECK:STDOUT: ; ModuleID = 'prelude.carbon'
+// CHECK:STDOUT: source_filename = "prelude.carbon"
+// CHECK:STDOUT: ; ModuleID = 'overloaded.carbon'
+// CHECK:STDOUT: source_filename = "overloaded.carbon"
+// CHECK:STDOUT:
+// CHECK:STDOUT: define void @Op(ptr sret({ i1 }) %return, ptr %self) {
+// CHECK:STDOUT:   %is_positive = getelementptr inbounds { i1 }, ptr %self, i32 0, i32 0
+// CHECK:STDOUT:   %1 = load i1, ptr %is_positive, align 1
+// CHECK:STDOUT:   %2 = xor i1 %1, true
+// CHECK:STDOUT:   %is_positive1 = getelementptr inbounds { i1 }, ptr %return, i32 0, i32 0
+// CHECK:STDOUT:   store i1 %2, ptr %is_positive1, align 1
+// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: define void @Op.1(ptr sret({ i1 }) %return, ptr %self, ptr %other) {
+// CHECK:STDOUT:   %is_positive = getelementptr inbounds { i1 }, ptr %self, i32 0, i32 0
+// CHECK:STDOUT:   %1 = load i1, ptr %is_positive, align 1
+// CHECK:STDOUT:   br i1 %1, label %2, label %4
+// CHECK:STDOUT:
+// CHECK:STDOUT: 2:                                                ; preds = %0
+// CHECK:STDOUT:   %is_positive1 = getelementptr inbounds { i1 }, ptr %other, i32 0, i32 0
+// CHECK:STDOUT:   %3 = load i1, ptr %is_positive1, align 1
+// CHECK:STDOUT:   br label %4
+// CHECK:STDOUT:
+// CHECK:STDOUT: 4:                                                ; preds = %2, %0
+// CHECK:STDOUT:   %5 = phi i1 [ false, %0 ], [ %3, %2 ]
+// CHECK:STDOUT:   %6 = xor i1 %5, true
+// CHECK:STDOUT:   br i1 %6, label %7, label %15
+// CHECK:STDOUT:
+// CHECK:STDOUT: 7:                                                ; preds = %4
+// CHECK:STDOUT:   %is_positive2 = getelementptr inbounds { i1 }, ptr %self, i32 0, i32 0
+// CHECK:STDOUT:   %8 = load i1, ptr %is_positive2, align 1
+// CHECK:STDOUT:   %9 = xor i1 %8, true
+// CHECK:STDOUT:   br i1 %9, label %10, label %13
+// CHECK:STDOUT:
+// CHECK:STDOUT: 10:                                               ; preds = %7
+// CHECK:STDOUT:   %is_positive3 = getelementptr inbounds { i1 }, ptr %other, i32 0, i32 0
+// CHECK:STDOUT:   %11 = load i1, ptr %is_positive3, align 1
+// CHECK:STDOUT:   %12 = xor i1 %11, true
+// CHECK:STDOUT:   br label %13
+// CHECK:STDOUT:
+// CHECK:STDOUT: 13:                                               ; preds = %10, %7
+// CHECK:STDOUT:   %14 = phi i1 [ false, %7 ], [ %12, %10 ]
+// CHECK:STDOUT:   br label %15
+// CHECK:STDOUT:
+// CHECK:STDOUT: 15:                                               ; preds = %13, %4
+// CHECK:STDOUT:   %16 = phi i1 [ true, %4 ], [ %14, %13 ]
+// CHECK:STDOUT:   %is_positive4 = getelementptr inbounds { i1 }, ptr %return, i32 0, i32 0
+// CHECK:STDOUT:   store i1 %16, ptr %is_positive4, align 1
+// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: define void @Calculate(ptr sret({ i1 }) %return, ptr %a, ptr %b) {
+// CHECK:STDOUT:   %temp = alloca { i1 }, align 8
+// CHECK:STDOUT:   call void @Op(ptr %temp, ptr %a)
+// CHECK:STDOUT:   call void @Op.1(ptr %return, ptr %temp, ptr %b)
+// CHECK:STDOUT:   ret void
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: ; uselistorder directives
+// CHECK:STDOUT: uselistorder i1 true, { 2, 0, 1, 3, 4 }