Kaynağa Gözat

Refactor LazyImportRef into ImportRefUnused. (#3656)

This makes some changes to the formatter so that ImportRefUnused and
ImportRefUsed will both be labeled as "import_ref" with an "unused ->
used" argument change in textual IR, but is otherwise not changing
logic.
Jon Ross-Perkins 2 yıl önce
ebeveyn
işleme
adad286b74

+ 1 - 1
toolchain/check/check.cpp

@@ -52,7 +52,7 @@ class SemIRLocationTranslator
 
       // If the parse node was invalid, recurse through import references when
       // possible.
-      if (auto import_ref = cursor_ir->insts().TryGetAs<SemIR::LazyImportRef>(
+      if (auto import_ref = cursor_ir->insts().TryGetAs<SemIR::ImportRefUnused>(
               cursor_inst_id)) {
         cursor_ir = cursor_ir->cross_ref_irs().Get(import_ref->ir_id);
         cursor_inst_id = import_ref->inst_id;

+ 7 - 7
toolchain/check/context.cpp

@@ -219,9 +219,9 @@ auto Context::AddNameToLookup(SemIR::NameId name_id, SemIR::InstId target_id)
   }
 }
 
-auto Context::ResolveIfLazyImportRef(SemIR::InstId inst_id) -> void {
+auto Context::ResolveIfImportRefUnused(SemIR::InstId inst_id) -> void {
   auto inst = insts().Get(inst_id);
-  auto lazy_inst = inst.TryAs<SemIR::LazyImportRef>();
+  auto lazy_inst = inst.TryAs<SemIR::ImportRefUnused>();
   if (!lazy_inst) {
     return;
   }
@@ -296,7 +296,7 @@ auto Context::LookupNameInDecl(Parse::NodeId /*parse_node*/,
     if (!lexical_results.empty()) {
       auto result = lexical_results.back();
       if (result.scope_index == current_scope_index()) {
-        ResolveIfLazyImportRef(result.inst_id);
+        ResolveIfImportRefUnused(result.inst_id);
         return result.inst_id;
       }
     }
@@ -331,7 +331,7 @@ auto Context::LookupUnqualifiedName(Parse::NodeId parse_node,
     if (!lexical_results.empty() &&
         lexical_results.back().scope_index > index) {
       auto inst_id = lexical_results.back().inst_id;
-      ResolveIfLazyImportRef(inst_id);
+      ResolveIfImportRefUnused(inst_id);
       return inst_id;
     }
 
@@ -345,7 +345,7 @@ auto Context::LookupUnqualifiedName(Parse::NodeId parse_node,
 
   if (!lexical_results.empty()) {
     auto inst_id = lexical_results.back().inst_id;
-    ResolveIfLazyImportRef(inst_id);
+    ResolveIfImportRefUnused(inst_id);
     return inst_id;
   }
 
@@ -360,7 +360,7 @@ auto Context::LookupNameInExactScope(SemIR::NameId name_id,
                                      const SemIR::NameScope& scope)
     -> SemIR::InstId {
   if (auto it = scope.names.find(name_id); it != scope.names.end()) {
-    ResolveIfLazyImportRef(it->second);
+    ResolveIfImportRefUnused(it->second);
     return it->second;
   }
   return SemIR::InstId::Invalid;
@@ -969,7 +969,7 @@ class TypeCompleter {
       case SemIR::InitializeFrom::Kind:
       case SemIR::InterfaceDecl::Kind:
       case SemIR::IntLiteral::Kind:
-      case SemIR::LazyImportRef::Kind:
+      case SemIR::ImportRefUnused::Kind:
       case SemIR::NameRef::Kind:
       case SemIR::Namespace::Kind:
       case SemIR::Param::Kind:

+ 2 - 2
toolchain/check/context.h

@@ -491,9 +491,9 @@ class Context {
     // TODO: This likely needs to track things which need to be destructed.
   };
 
-  // If the passed in instruction ID is a LazyImportRef, resolves it for use.
+  // If the passed in instruction ID is a ImportRefUnused, resolves it for use.
   // Called when name lookup intends to return an inst_id.
-  auto ResolveIfLazyImportRef(SemIR::InstId inst_id) -> void;
+  auto ResolveIfImportRefUnused(SemIR::InstId inst_id) -> void;
 
   auto current_scope() -> ScopeStackEntry& { return scope_stack_.back(); }
   auto current_scope() const -> const ScopeStackEntry& {

+ 1 - 1
toolchain/check/eval.cpp

@@ -476,8 +476,8 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
     case SemIR::BranchWithArg::Kind:
     case SemIR::ClassDecl::Kind:
     case SemIR::Import::Kind:
+    case SemIR::ImportRefUnused::Kind:
     case SemIR::InterfaceDecl::Kind:
-    case SemIR::LazyImportRef::Kind:
     case SemIR::Param::Kind:
     case SemIR::ReturnExpr::Kind:
     case SemIR::Return::Kind:

+ 2 - 2
toolchain/check/import.cpp

@@ -104,7 +104,7 @@ static auto CopySingleNameScopeFromImportIR(
 
   // Produce the namespace for the entry.
   auto ref_id = context.AddInst(
-      SemIR::LazyImportRef{.ir_id = ir_id, .inst_id = import_inst_id});
+      SemIR::ImportRefUnused{.ir_id = ir_id, .inst_id = import_inst_id});
   auto namespace_inst =
       SemIR::Namespace{namespace_type_id, SemIR::NameScopeId::Invalid, ref_id};
   // Use the invalid node because there's no node to associate with.
@@ -211,7 +211,7 @@ auto Import(Context& context, SemIR::TypeId namespace_type_id,
     } else {
       // Leave a placeholder that the inst comes from the other IR.
       auto target_id = context.AddPlaceholderInst(
-          {SemIR::LazyImportRef{.ir_id = ir_id, .inst_id = import_inst_id}});
+          {SemIR::ImportRefUnused{.ir_id = ir_id, .inst_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

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

@@ -57,8 +57,8 @@ import library "a";
 // CHECK:STDOUT: --- b.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.Empty = %lazy_import_ref.1, .ForwardDeclared = %lazy_import_ref.2} [template]
-// CHECK:STDOUT:   %lazy_import_ref.1 = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %lazy_import_ref.2 = lazy_import_ref ir1, inst+4
+// CHECK:STDOUT:   package: <namespace> = namespace {.Empty = %import_ref.1, .ForwardDeclared = %import_ref.2} [template]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+4, unused
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/function/declaration/import.carbon

@@ -30,7 +30,7 @@ import library "a";
 // CHECK:STDOUT: --- b.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.F = %lazy_import_ref} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
+// CHECK:STDOUT:   package: <namespace> = namespace {.F = %import_ref} [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -33,7 +33,7 @@ import library "a";
 // CHECK:STDOUT: --- b.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.F = %lazy_import_ref} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
+// CHECK:STDOUT:   package: <namespace> = namespace {.F = %import_ref} [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -51,8 +51,8 @@ import library "a";
 // CHECK:STDOUT: --- b.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.Empty = %lazy_import_ref.1, .ForwardDeclared = %lazy_import_ref.2} [template]
-// CHECK:STDOUT:   %lazy_import_ref.1 = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %lazy_import_ref.2 = lazy_import_ref ir1, inst+2
+// CHECK:STDOUT:   package: <namespace> = namespace {.Empty = %import_ref.1, .ForwardDeclared = %import_ref.2} [template]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -33,8 +33,8 @@ var a: i32 = NS.A();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.NS = %.2, .a = %a} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %.2: <namespace> = namespace {.A = %A}, %lazy_import_ref [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %.2: <namespace> = namespace {.A = %A}, %import_ref [template]
 // CHECK:STDOUT:   %A: <function> = fn_decl @A [template]
 // CHECK:STDOUT:   %a.var: ref i32 = var a
 // CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var

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

@@ -51,8 +51,8 @@ fn NS();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.NS = %.loc8_13.1} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %.loc8_13.1: <namespace> = namespace {}, %lazy_import_ref [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %.loc8_13.1: <namespace> = namespace {}, %import_ref [template]
 // CHECK:STDOUT:   %.loc8_13.2: <namespace> = namespace {} [template]
 // CHECK:STDOUT:   %.loc16: <function> = fn_decl @.1 [template]
 // CHECK:STDOUT:   %.loc20: <namespace> = namespace {} [template]

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

@@ -37,8 +37,8 @@ fn NS.Foo();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.NS = %.2} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %.2: <namespace> = namespace {.Foo = %Foo}, %lazy_import_ref [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %.2: <namespace> = namespace {.Foo = %Foo}, %import_ref [template]
 // CHECK:STDOUT:   %.loc12: <function> = fn_decl @.1 [template]
 // CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo [template]
 // CHECK:STDOUT: }

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

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

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

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

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

@@ -46,10 +46,10 @@ var package_b: () = package.NS.ChildNS.B();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.NS = %.2, .a = %a, .b = %b, .package_a = %package_a, .package_b = %package_b} [template]
-// CHECK:STDOUT:   %lazy_import_ref.1 = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %.2: <namespace> = namespace {.ChildNS = %.3, .A = %.4}, %lazy_import_ref.1 [template]
-// CHECK:STDOUT:   %lazy_import_ref.2 = lazy_import_ref ir1, inst+2
-// CHECK:STDOUT:   %.3: <namespace> = namespace {.B = %.5}, %lazy_import_ref.2 [template]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %.2: <namespace> = namespace {.ChildNS = %.3, .A = %.4}, %import_ref.1 [template]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %.3: <namespace> = namespace {.B = %.5}, %import_ref.2 [template]
 // CHECK:STDOUT:   %.4: <function> = fn_decl @.1 [template]
 // CHECK:STDOUT:   %.5: <function> = fn_decl @.2 [template]
 // CHECK:STDOUT:   %.loc4_9.1: () = tuple_literal ()

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

@@ -49,8 +49,8 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.A = %.2} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.loc5}, %lazy_import_ref [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.loc5}, %import_ref [template]
 // CHECK:STDOUT:   %.loc5: <namespace> = namespace {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -58,10 +58,10 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.A = %.2} [template]
-// CHECK:STDOUT:   %lazy_import_ref.1 = lazy_import_ref ir1, inst+2
-// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.3}, %lazy_import_ref.1 [template]
-// CHECK:STDOUT:   %lazy_import_ref.2 = lazy_import_ref ir1, inst+3
-// CHECK:STDOUT:   %.3: <namespace> = namespace {.C = %.loc5}, %lazy_import_ref.2 [template]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.3}, %import_ref.1 [template]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+3, unused
+// CHECK:STDOUT:   %.3: <namespace> = namespace {.C = %.loc5}, %import_ref.2 [template]
 // CHECK:STDOUT:   %.loc5: <namespace> = namespace {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -69,12 +69,12 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.A = %.2} [template]
-// CHECK:STDOUT:   %lazy_import_ref.1 = lazy_import_ref ir1, inst+2
-// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.3}, %lazy_import_ref.1 [template]
-// CHECK:STDOUT:   %lazy_import_ref.2 = lazy_import_ref ir1, inst+4
-// CHECK:STDOUT:   %.3: <namespace> = namespace {.C = %.4}, %lazy_import_ref.2 [template]
-// CHECK:STDOUT:   %lazy_import_ref.3 = lazy_import_ref ir1, inst+5
-// CHECK:STDOUT:   %.4: <namespace> = namespace {.D = %D}, %lazy_import_ref.3 [template]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.3}, %import_ref.1 [template]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+4, unused
+// CHECK:STDOUT:   %.3: <namespace> = namespace {.C = %.4}, %import_ref.2 [template]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+5, unused
+// CHECK:STDOUT:   %.4: <namespace> = namespace {.D = %D}, %import_ref.3 [template]
 // CHECK:STDOUT:   %D: <function> = fn_decl @D [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -91,12 +91,12 @@ var e: () = A.B.C.D();
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.A = %.2, .e = %e} [template]
-// CHECK:STDOUT:   %lazy_import_ref.1 = lazy_import_ref ir1, inst+2
-// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.3}, %lazy_import_ref.1 [template]
-// CHECK:STDOUT:   %lazy_import_ref.2 = lazy_import_ref ir1, inst+4
-// CHECK:STDOUT:   %.3: <namespace> = namespace {.C = %.4}, %lazy_import_ref.2 [template]
-// CHECK:STDOUT:   %lazy_import_ref.3 = lazy_import_ref ir1, inst+6
-// CHECK:STDOUT:   %.4: <namespace> = namespace {.D = %.5}, %lazy_import_ref.3 [template]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %.2: <namespace> = namespace {.B = %.3}, %import_ref.1 [template]
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+4, unused
+// CHECK:STDOUT:   %.3: <namespace> = namespace {.C = %.4}, %import_ref.2 [template]
+// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+6, unused
+// CHECK:STDOUT:   %.4: <namespace> = namespace {.D = %.5}, %import_ref.3 [template]
 // CHECK:STDOUT:   %.5: <function> = fn_decl @.1 [template]
 // CHECK:STDOUT:   %.loc5_9.1: () = tuple_literal ()
 // CHECK:STDOUT:   %.loc5_9.2: type = converted %.loc5_9.1, constants.%.1 [template = constants.%.1]

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

@@ -83,8 +83,8 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {.NS = %.loc7_13.1, .Run = %Run} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %.loc7_13.1: <namespace> = namespace {.A = %.2, .B1 = %.3, .B2 = %.4, .C = %C}, %lazy_import_ref [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %.loc7_13.1: <namespace> = namespace {.A = %.2, .B1 = %.3, .B2 = %.4, .C = %C}, %import_ref [template]
 // CHECK:STDOUT:   %.2: <function> = fn_decl @.1 [template]
 // CHECK:STDOUT:   %.3: <function> = fn_decl @.2 [template]
 // CHECK:STDOUT:   %.4: <function> = fn_decl @.3 [template]

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

@@ -49,8 +49,8 @@ import library "var";
 // CHECK:STDOUT: --- conflict.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.Foo = %lazy_import_ref.1} [template]
-// CHECK:STDOUT:   %lazy_import_ref.1 = lazy_import_ref ir1, inst+1
-// CHECK:STDOUT:   %lazy_import_ref.2 = lazy_import_ref ir2, inst+2
+// CHECK:STDOUT:   package: <namespace> = namespace {.Foo = %import_ref.1} [template]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+1, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir2, inst+2, unused
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

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

@@ -26,7 +26,7 @@ package Implicit impl;
 // CHECK:STDOUT: --- implicit.impl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
-// CHECK:STDOUT:   package: <namespace> = namespace {.A = %lazy_import_ref} [template]
-// CHECK:STDOUT:   %lazy_import_ref = lazy_import_ref ir1, inst+1
+// CHECK:STDOUT:   package: <namespace> = namespace {.A = %import_ref} [template]
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+1, unused
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 6 - 6
toolchain/lower/handle.cpp

@@ -200,6 +200,12 @@ auto HandleImport(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
   FatalErrorIfEncountered(inst);
 }
 
+auto HandleImportRefUnused(FunctionContext& /*context*/,
+                           SemIR::InstId /*inst_id*/,
+                           SemIR::ImportRefUnused inst) -> void {
+  FatalErrorIfEncountered(inst);
+}
+
 auto HandleInitializeFrom(FunctionContext& context, SemIR::InstId /*inst_id*/,
                           SemIR::InitializeFrom inst) -> void {
   auto storage_type_id = context.sem_ir().insts().Get(inst.dest_id).type_id();
@@ -221,12 +227,6 @@ auto HandleIntLiteral(FunctionContext& context, SemIR::InstId inst_id,
   context.SetLocal(inst_id, v);
 }
 
-auto HandleLazyImportRef(FunctionContext& /*context*/,
-                         SemIR::InstId /*inst_id*/, SemIR::LazyImportRef inst)
-    -> void {
-  FatalErrorIfEncountered(inst);
-}
-
 auto HandleNameRef(FunctionContext& context, SemIR::InstId inst_id,
                    SemIR::NameRef inst) -> void {
   auto type_inst_id = context.sem_ir().types().GetInstId(inst.type_id);

+ 3 - 3
toolchain/sem_ir/file.cpp

@@ -245,10 +245,10 @@ static auto GetTypePrecedence(InstKind kind) -> int {
     case FieldDecl::Kind:
     case FunctionDecl::Kind:
     case Import::Kind:
+    case ImportRefUnused::Kind:
     case InitializeFrom::Kind:
     case InterfaceDecl::Kind:
     case IntLiteral::Kind:
-    case LazyImportRef::Kind:
     case Namespace::Kind:
     case Param::Kind:
     case RealLiteral::Kind:
@@ -451,10 +451,10 @@ auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
       case FieldDecl::Kind:
       case FunctionDecl::Kind:
       case Import::Kind:
+      case ImportRefUnused::Kind:
       case InitializeFrom::Kind:
       case InterfaceDecl::Kind:
       case IntLiteral::Kind:
-      case LazyImportRef::Kind:
       case Namespace::Kind:
       case Param::Kind:
       case RealLiteral::Kind:
@@ -509,8 +509,8 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
       case FieldDecl::Kind:
       case FunctionDecl::Kind:
       case Import::Kind:
+      case ImportRefUnused::Kind:
       case InterfaceDecl::Kind:
-      case LazyImportRef::Kind:
       case Namespace::Kind:
       case Return::Kind:
       case ReturnExpr::Kind:

+ 8 - 8
toolchain/sem_ir/formatter.cpp

@@ -493,6 +493,10 @@ class InstNamer {
           add_inst_name("import");
           continue;
         }
+        case ImportRefUnused::Kind: {
+          add_inst_name("import_ref");
+          continue;
+        }
         case InterfaceDecl::Kind: {
           add_inst_name_id(sem_ir_.interfaces()
                                .Get(inst.As<InterfaceDecl>().interface_id)
@@ -500,10 +504,6 @@ class InstNamer {
                            ".decl");
           continue;
         }
-        case LazyImportRef::Kind: {
-          add_inst_name("lazy_import_ref");
-          continue;
-        }
         case NameRef::Kind: {
           add_inst_name_id(inst.As<NameRef>().name_id, ".ref");
           continue;
@@ -823,9 +823,9 @@ class Formatter {
     out_ << " = ";
   }
 
-  // Print LazyImportRef with type-like semantics even though it lacks a
+  // Print ImportRefUnused with type-like semantics even though it lacks a
   // type_id.
-  auto FormatInstructionLHS(InstId inst_id, LazyImportRef /*inst*/) -> void {
+  auto FormatInstructionLHS(InstId inst_id, ImportRefUnused /*inst*/) -> void {
     FormatInstName(inst_id);
     out_ << " = ";
   }
@@ -947,10 +947,10 @@ class Formatter {
     out_ << " " << inst.ir_id << ", " << inst.inst_id;
   }
 
-  auto FormatInstructionRHS(LazyImportRef inst) -> void {
+  auto FormatInstructionRHS(ImportRefUnused inst) -> void {
     // Don't format the inst_id because it refers to a different IR.
     // TODO: Consider a better way to format the InstID from other IRs.
-    out_ << " " << inst.ir_id << ", " << inst.inst_id;
+    out_ << " " << inst.ir_id << ", " << inst.inst_id << ", unused";
   }
 
   auto FormatInstructionRHS(SpliceBlock inst) -> void {

+ 1 - 1
toolchain/sem_ir/inst_kind.def

@@ -46,10 +46,10 @@ CARBON_SEM_IR_INST_KIND(Deref)
 CARBON_SEM_IR_INST_KIND(FieldDecl)
 CARBON_SEM_IR_INST_KIND(FunctionDecl)
 CARBON_SEM_IR_INST_KIND(Import)
+CARBON_SEM_IR_INST_KIND(ImportRefUnused)
 CARBON_SEM_IR_INST_KIND(InitializeFrom)
 CARBON_SEM_IR_INST_KIND(InterfaceDecl)
 CARBON_SEM_IR_INST_KIND(IntLiteral)
-CARBON_SEM_IR_INST_KIND(LazyImportRef)
 CARBON_SEM_IR_INST_KIND(NameRef)
 CARBON_SEM_IR_INST_KIND(Namespace)
 CARBON_SEM_IR_INST_KIND(Param)

+ 12 - 13
toolchain/sem_ir/typed_insts.h

@@ -416,6 +416,18 @@ struct Import {
   CrossRefIRId last_cross_ref_ir_id;
 };
 
+// An imported entity that hasn't yet been referenced. If referenced, it should
+// turn into an ImportRefUsed.
+// TODO: Add ImportRefUsed.
+struct ImportRefUnused {
+  // No parse node: any parse node logic must use the referenced IR.
+  static constexpr auto Kind =
+      InstKind::ImportRefUnused.Define<Parse::InvalidNodeId>("import_ref");
+
+  CrossRefIRId ir_id;
+  InstId inst_id;
+};
+
 // Finalizes the initialization of `dest_id` from the initializer expression
 // `src_id`, by performing a final copy from source to destination, for types
 // whose initialization is not in-place.
@@ -453,19 +465,6 @@ struct IntLiteral {
   IntId int_id;
 };
 
-// This instruction is not intended for direct use. Instead, it should be loaded
-// if it's referenced through name resolution.
-struct LazyImportRef {
-  // No parse node: an instruction's parse tree node must refer to a node in the
-  // current parse tree. This cannot use the cross-referenced instruction's
-  // parse tree node because it will be in a different parse tree.
-  static constexpr auto Kind =
-      InstKind::LazyImportRef.Define<Parse::InvalidNodeId>("lazy_import_ref");
-
-  CrossRefIRId ir_id;
-  InstId inst_id;
-};
-
 struct NameRef {
   // TODO: Make Parse::NodeId more specific.
   static constexpr auto Kind =