浏览代码

Allow no-op conversions on incomplete types. (#6926)

This resolves some todos, and makes `Convert` safer to call, which
unblocks some changes in pattern matching that I'm working on.

Assisted-by: Gemini 3.1 Pro via Antigravity
Geoff Romer 1 月之前
父节点
当前提交
6d1130f657

+ 33 - 10
toolchain/check/convert.cpp

@@ -1876,6 +1876,34 @@ auto CategoryConverter::DoStep(const SemIR::InstId expr_id,
   }
 }
 
+// Returns true if converting `expr_id` to `target` requires `target.type_id`
+// to be complete.
+static auto ConversionNeedsCompleteTarget(Context& context,
+                                          SemIR::InstId expr_id,
+                                          ConversionTarget target) -> bool {
+  auto source_type_id = context.insts().Get(expr_id).type_id();
+
+  // We allow conversion to incomplete facet types, since their representation
+  // is fixed. This allows us to support using the `Self` of an interface inside
+  // its definition.
+  if (context.types().IsFacetType(target.type_id)) {
+    return false;
+  }
+
+  // If the types are the same, we only have to worry about form conversions.
+  if (source_type_id == target.type_id) {
+    auto source_category = SemIR::GetExprCategory(context.sem_ir(), expr_id);
+
+    // If there's no form conversion and no type conversion, the conversion is
+    // a no-op, so we don't need a complete type.
+    if (IsValidExprCategoryForConversionTarget(source_category, target.kind)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
              ConversionTarget target) -> SemIR::InstId {
   auto& sem_ir = context.sem_ir();
@@ -1915,16 +1943,11 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
     context.emitter().Emit(expr_id, RefTagNoRefParam);
   }
 
-  // We can only perform initialization for complete, non-abstract types.
-  //
-  // TODO: Don't require a concrete type when `!target.is_initializer()`. We
-  // want to allow constructing a value of an abstract class type, but right now
-  // if we proceed into Convert with an abstract target type, we crash.
-  //
-  // Note that we allow conversion to incomplete to facet types, since their
-  // representation is fixed. This allows us to support using the `Self` of an
-  // interface inside its definition.
-  if (!context.types().IsFacetType(target.type_id)) {
+  // TODO: Allow abstract but complete types if the conversion is just a
+  // same-type value acqisition.
+  // TODO: Push this check down to the points where we perform operations that
+  // need the type to be complete.
+  if (ConversionNeedsCompleteTarget(context, expr_id, target)) {
     if (target.diagnose) {
       if (!RequireConcreteType(
               context, target.type_id, loc_id,

+ 178 - 180
toolchain/check/testdata/basics/raw_sem_ir/one_file.carbon

@@ -94,165 +94,165 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:     import_ir_inst36: {ir_id: import_ir58000004, inst_id: inst70000074}
 // CHECK:STDOUT:     import_ir_inst37: {ir_id: import_ir58000004, inst_id: inst7000008C}
 // CHECK:STDOUT:     import_ir_inst38: {ir_id: import_ir58000004, inst_id: inst7000008D}
-// CHECK:STDOUT:     import_ir_inst39: {ir_id: import_ir58000004, inst_id: inst700000C4}
-// CHECK:STDOUT:     import_ir_inst3A: {ir_id: import_ir58000004, inst_id: inst700000C2}
-// CHECK:STDOUT:     import_ir_inst3B: {ir_id: import_ir58000004, inst_id: inst700000C0}
-// CHECK:STDOUT:     import_ir_inst3C: {ir_id: import_ir58000004, inst_id: inst700000C1}
-// CHECK:STDOUT:     import_ir_inst3D: {ir_id: import_ir58000004, inst_id: inst700000E0}
-// CHECK:STDOUT:     import_ir_inst3E: {ir_id: import_ir58000004, inst_id: inst700000DE}
-// CHECK:STDOUT:     import_ir_inst3F: {ir_id: import_ir58000004, inst_id: inst700000DC}
-// CHECK:STDOUT:     import_ir_inst40: {ir_id: import_ir58000004, inst_id: inst700000DD}
-// CHECK:STDOUT:     import_ir_inst41: {ir_id: import_ir58000004, inst_id: inst700000FC}
-// CHECK:STDOUT:     import_ir_inst42: {ir_id: import_ir58000004, inst_id: inst700000FA}
-// CHECK:STDOUT:     import_ir_inst43: {ir_id: import_ir58000004, inst_id: inst700000F8}
-// CHECK:STDOUT:     import_ir_inst44: {ir_id: import_ir58000004, inst_id: inst700000F9}
-// CHECK:STDOUT:     import_ir_inst45: {ir_id: import_ir58000004, inst_id: inst70000118}
-// CHECK:STDOUT:     import_ir_inst46: {ir_id: import_ir58000004, inst_id: inst70000116}
-// CHECK:STDOUT:     import_ir_inst47: {ir_id: import_ir58000004, inst_id: inst70000114}
-// CHECK:STDOUT:     import_ir_inst48: {ir_id: import_ir58000004, inst_id: inst70000115}
-// CHECK:STDOUT:     import_ir_inst49: {ir_id: import_ir58000004, inst_id: inst7000013B}
-// CHECK:STDOUT:     import_ir_inst4A: {ir_id: import_ir58000004, inst_id: inst70000139}
-// CHECK:STDOUT:     import_ir_inst4B: {ir_id: import_ir58000004, inst_id: inst7000014F}
-// CHECK:STDOUT:     import_ir_inst4C: {ir_id: import_ir58000004, inst_id: inst7000013A}
-// CHECK:STDOUT:     import_ir_inst4D: {ir_id: import_ir58000004, inst_id: inst70000132}
-// CHECK:STDOUT:     import_ir_inst4E: {ir_id: import_ir58000004, inst_id: inst70000134}
-// CHECK:STDOUT:     import_ir_inst4F: {ir_id: import_ir58000004, inst_id: inst70000137}
-// CHECK:STDOUT:     import_ir_inst50: {ir_id: import_ir58000004, inst_id: inst7000012F}
-// CHECK:STDOUT:     import_ir_inst51: {ir_id: import_ir58000004, inst_id: inst70000131}
-// CHECK:STDOUT:     import_ir_inst52: {ir_id: import_ir58000004, inst_id: inst70000136}
-// CHECK:STDOUT:     import_ir_inst53: {ir_id: import_ir58000004, inst_id: inst7000013D}
-// CHECK:STDOUT:     import_ir_inst54: {ir_id: import_ir58000004, inst_id: inst7000014F}
-// CHECK:STDOUT:     import_ir_inst55: {ir_id: import_ir58000004, inst_id: inst7000014A}
-// CHECK:STDOUT:     import_ir_inst56: {ir_id: import_ir58000004, inst_id: inst7000014B}
-// CHECK:STDOUT:     import_ir_inst57: {ir_id: import_ir58000004, inst_id: inst70000143}
-// CHECK:STDOUT:     import_ir_inst58: {ir_id: import_ir58000004, inst_id: inst70000145}
-// CHECK:STDOUT:     import_ir_inst59: {ir_id: import_ir58000004, inst_id: inst70000146}
-// CHECK:STDOUT:     import_ir_inst5A: {ir_id: import_ir58000004, inst_id: inst70000147}
-// CHECK:STDOUT:     import_ir_inst5B: {ir_id: import_ir58000004, inst_id: inst7000012F}
-// CHECK:STDOUT:     import_ir_inst5C: {ir_id: import_ir58000004, inst_id: inst7000013F}
-// CHECK:STDOUT:     import_ir_inst5D: {ir_id: import_ir58000004, inst_id: inst70000140}
-// CHECK:STDOUT:     import_ir_inst5E: {ir_id: import_ir58000004, inst_id: inst70000144}
-// CHECK:STDOUT:     import_ir_inst5F: {ir_id: import_ir58000004, inst_id: inst70000149}
-// CHECK:STDOUT:     import_ir_inst60: {ir_id: import_ir58000004, inst_id: inst70000152}
-// CHECK:STDOUT:     import_ir_inst61: {ir_id: import_ir58000004, inst_id: inst70000153}
-// CHECK:STDOUT:     import_ir_inst62: {ir_id: import_ir58000004, inst_id: inst70000156}
-// CHECK:STDOUT:     import_ir_inst63: {ir_id: import_ir58000004, inst_id: inst7000015E}
-// CHECK:STDOUT:     import_ir_inst64: {ir_id: import_ir58000004, inst_id: inst7000015C}
-// CHECK:STDOUT:     import_ir_inst65: {ir_id: import_ir58000004, inst_id: inst7000015A}
-// CHECK:STDOUT:     import_ir_inst66: {ir_id: import_ir58000004, inst_id: inst7000015B}
-// CHECK:STDOUT:     import_ir_inst67: {ir_id: import_ir58000004, inst_id: inst70000177}
-// CHECK:STDOUT:     import_ir_inst68: {ir_id: import_ir58000004, inst_id: inst70000175}
-// CHECK:STDOUT:     import_ir_inst69: {ir_id: import_ir58000004, inst_id: inst70000173}
-// CHECK:STDOUT:     import_ir_inst6A: {ir_id: import_ir58000004, inst_id: inst70000174}
-// CHECK:STDOUT:     import_ir_inst6B: {ir_id: import_ir58000004, inst_id: inst700001AD}
-// CHECK:STDOUT:     import_ir_inst6C: {ir_id: import_ir58000004, inst_id: inst700001AB}
-// CHECK:STDOUT:     import_ir_inst6D: {ir_id: import_ir58000004, inst_id: inst700001C8}
-// CHECK:STDOUT:     import_ir_inst6E: {ir_id: import_ir58000004, inst_id: inst700001AC}
-// CHECK:STDOUT:     import_ir_inst6F: {ir_id: import_ir58000004, inst_id: inst700001C8}
-// CHECK:STDOUT:     import_ir_inst70: {ir_id: import_ir58000004, inst_id: inst700001C3}
-// CHECK:STDOUT:     import_ir_inst71: {ir_id: import_ir58000004, inst_id: inst700001C4}
-// CHECK:STDOUT:     import_ir_inst72: {ir_id: import_ir58000004, inst_id: inst700001BC}
-// CHECK:STDOUT:     import_ir_inst73: {ir_id: import_ir58000004, inst_id: inst700001BE}
-// CHECK:STDOUT:     import_ir_inst74: {ir_id: import_ir58000004, inst_id: inst700001BF}
-// CHECK:STDOUT:     import_ir_inst75: {ir_id: import_ir58000004, inst_id: inst700001C0}
-// CHECK:STDOUT:     import_ir_inst76: {ir_id: import_ir58000004, inst_id: inst7000018E}
-// CHECK:STDOUT:     import_ir_inst77: {ir_id: import_ir58000004, inst_id: inst70000193}
-// CHECK:STDOUT:     import_ir_inst78: {ir_id: import_ir58000004, inst_id: inst700001B5}
-// CHECK:STDOUT:     import_ir_inst79: {ir_id: import_ir58000004, inst_id: inst700001B6}
-// CHECK:STDOUT:     import_ir_inst7A: {ir_id: import_ir58000004, inst_id: inst700001B7}
-// CHECK:STDOUT:     import_ir_inst7B: {ir_id: import_ir58000004, inst_id: inst700001B8}
-// CHECK:STDOUT:     import_ir_inst7C: {ir_id: import_ir58000004, inst_id: inst700001B9}
-// CHECK:STDOUT:     import_ir_inst7D: {ir_id: import_ir58000004, inst_id: inst700001BD}
-// CHECK:STDOUT:     import_ir_inst7E: {ir_id: import_ir58000004, inst_id: inst700001C2}
-// CHECK:STDOUT:     import_ir_inst7F: {ir_id: import_ir58000004, inst_id: inst700001D3}
-// CHECK:STDOUT:     import_ir_inst80: {ir_id: import_ir58000004, inst_id: inst700001DA}
-// CHECK:STDOUT:     import_ir_inst81: {ir_id: import_ir58000004, inst_id: inst700001DE}
-// CHECK:STDOUT:     import_ir_inst82: {ir_id: import_ir58000004, inst_id: inst700001E0}
-// CHECK:STDOUT:     import_ir_inst83: {ir_id: import_ir58000004, inst_id: inst700001E1}
-// CHECK:STDOUT:     import_ir_inst84: {ir_id: import_ir58000004, inst_id: inst700001E2}
-// CHECK:STDOUT:     import_ir_inst85: {ir_id: import_ir58000004, inst_id: inst700001E5}
-// CHECK:STDOUT:     import_ir_inst86: {ir_id: import_ir58000004, inst_id: inst700001F1}
-// CHECK:STDOUT:     import_ir_inst87: {ir_id: import_ir58000004, inst_id: inst700001F8}
-// CHECK:STDOUT:     import_ir_inst88: {ir_id: import_ir58000004, inst_id: inst700001FC}
-// CHECK:STDOUT:     import_ir_inst89: {ir_id: import_ir58000004, inst_id: inst700001FD}
-// CHECK:STDOUT:     import_ir_inst8A: {ir_id: import_ir58000004, inst_id: inst700001FE}
-// CHECK:STDOUT:     import_ir_inst8B: {ir_id: import_ir58000004, inst_id: inst70000204}
-// CHECK:STDOUT:     import_ir_inst8C: {ir_id: import_ir58000004, inst_id: inst70000196}
-// CHECK:STDOUT:     import_ir_inst8D: {ir_id: import_ir58000004, inst_id: inst70000190}
-// CHECK:STDOUT:     import_ir_inst8E: {ir_id: import_ir58000004, inst_id: inst700001A6}
-// CHECK:STDOUT:     import_ir_inst8F: {ir_id: import_ir58000004, inst_id: inst700001A8}
-// CHECK:STDOUT:     import_ir_inst90: {ir_id: import_ir58000004, inst_id: inst7000018E}
-// CHECK:STDOUT:     import_ir_inst91: {ir_id: import_ir58000004, inst_id: inst70000193}
-// CHECK:STDOUT:     import_ir_inst92: {ir_id: import_ir58000004, inst_id: inst7000018F}
-// CHECK:STDOUT:     import_ir_inst93: {ir_id: import_ir58000004, inst_id: inst70000195}
-// CHECK:STDOUT:     import_ir_inst94: {ir_id: import_ir58000004, inst_id: inst7000019C}
-// CHECK:STDOUT:     import_ir_inst95: {ir_id: import_ir58000004, inst_id: inst7000019F}
-// CHECK:STDOUT:     import_ir_inst96: {ir_id: import_ir58000004, inst_id: inst700001A3}
-// CHECK:STDOUT:     import_ir_inst97: {ir_id: import_ir58000004, inst_id: inst700001A7}
-// CHECK:STDOUT:     import_ir_inst98: {ir_id: import_ir58000004, inst_id: inst700001AF}
-// CHECK:STDOUT:     import_ir_inst99: {ir_id: import_ir58000004, inst_id: inst700001CB}
-// CHECK:STDOUT:     import_ir_inst9A: {ir_id: import_ir58000004, inst_id: inst700001CC}
-// CHECK:STDOUT:     import_ir_inst9B: {ir_id: import_ir58000004, inst_id: inst7000023F}
-// CHECK:STDOUT:     import_ir_inst9C: {ir_id: import_ir58000004, inst_id: inst7000023D}
-// CHECK:STDOUT:     import_ir_inst9D: {ir_id: import_ir58000004, inst_id: inst7000025E}
-// CHECK:STDOUT:     import_ir_inst9E: {ir_id: import_ir58000004, inst_id: inst7000023E}
-// CHECK:STDOUT:     import_ir_inst9F: {ir_id: import_ir58000004, inst_id: inst7000025E}
-// CHECK:STDOUT:     import_ir_instA0: {ir_id: import_ir58000004, inst_id: inst70000259}
-// CHECK:STDOUT:     import_ir_instA1: {ir_id: import_ir58000004, inst_id: inst7000025A}
-// CHECK:STDOUT:     import_ir_instA2: {ir_id: import_ir58000004, inst_id: inst70000252}
-// CHECK:STDOUT:     import_ir_instA3: {ir_id: import_ir58000004, inst_id: inst70000254}
-// CHECK:STDOUT:     import_ir_instA4: {ir_id: import_ir58000004, inst_id: inst70000255}
-// CHECK:STDOUT:     import_ir_instA5: {ir_id: import_ir58000004, inst_id: inst70000256}
-// CHECK:STDOUT:     import_ir_instA6: {ir_id: import_ir58000004, inst_id: inst70000216}
-// CHECK:STDOUT:     import_ir_instA7: {ir_id: import_ir58000004, inst_id: inst7000021B}
-// CHECK:STDOUT:     import_ir_instA8: {ir_id: import_ir58000004, inst_id: inst70000220}
-// CHECK:STDOUT:     import_ir_instA9: {ir_id: import_ir58000004, inst_id: inst70000249}
-// CHECK:STDOUT:     import_ir_instAA: {ir_id: import_ir58000004, inst_id: inst7000024A}
-// CHECK:STDOUT:     import_ir_instAB: {ir_id: import_ir58000004, inst_id: inst7000024B}
-// CHECK:STDOUT:     import_ir_instAC: {ir_id: import_ir58000004, inst_id: inst7000024C}
-// CHECK:STDOUT:     import_ir_instAD: {ir_id: import_ir58000004, inst_id: inst7000024D}
-// CHECK:STDOUT:     import_ir_instAE: {ir_id: import_ir58000004, inst_id: inst7000024E}
-// CHECK:STDOUT:     import_ir_instAF: {ir_id: import_ir58000004, inst_id: inst7000024F}
-// CHECK:STDOUT:     import_ir_instB0: {ir_id: import_ir58000004, inst_id: inst70000253}
-// CHECK:STDOUT:     import_ir_instB1: {ir_id: import_ir58000004, inst_id: inst70000258}
-// CHECK:STDOUT:     import_ir_instB2: {ir_id: import_ir58000004, inst_id: inst70000269}
-// CHECK:STDOUT:     import_ir_instB3: {ir_id: import_ir58000004, inst_id: inst7000026F}
-// CHECK:STDOUT:     import_ir_instB4: {ir_id: import_ir58000004, inst_id: inst70000273}
-// CHECK:STDOUT:     import_ir_instB5: {ir_id: import_ir58000004, inst_id: inst70000275}
-// CHECK:STDOUT:     import_ir_instB6: {ir_id: import_ir58000004, inst_id: inst70000276}
-// CHECK:STDOUT:     import_ir_instB7: {ir_id: import_ir58000004, inst_id: inst70000277}
-// CHECK:STDOUT:     import_ir_instB8: {ir_id: import_ir58000004, inst_id: inst7000027A}
-// CHECK:STDOUT:     import_ir_instB9: {ir_id: import_ir58000004, inst_id: inst70000284}
-// CHECK:STDOUT:     import_ir_instBA: {ir_id: import_ir58000004, inst_id: inst70000288}
-// CHECK:STDOUT:     import_ir_instBB: {ir_id: import_ir58000004, inst_id: inst7000028A}
-// CHECK:STDOUT:     import_ir_instBC: {ir_id: import_ir58000004, inst_id: inst7000028B}
-// CHECK:STDOUT:     import_ir_instBD: {ir_id: import_ir58000004, inst_id: inst7000028C}
-// CHECK:STDOUT:     import_ir_instBE: {ir_id: import_ir58000004, inst_id: inst7000028F}
-// CHECK:STDOUT:     import_ir_instBF: {ir_id: import_ir58000004, inst_id: inst7000029B}
-// CHECK:STDOUT:     import_ir_instC0: {ir_id: import_ir58000004, inst_id: inst700002A2}
-// CHECK:STDOUT:     import_ir_instC1: {ir_id: import_ir58000004, inst_id: inst700002A6}
-// CHECK:STDOUT:     import_ir_instC2: {ir_id: import_ir58000004, inst_id: inst700002A7}
-// CHECK:STDOUT:     import_ir_instC3: {ir_id: import_ir58000004, inst_id: inst700002A8}
-// CHECK:STDOUT:     import_ir_instC4: {ir_id: import_ir58000004, inst_id: inst700002AE}
-// CHECK:STDOUT:     import_ir_instC5: {ir_id: import_ir58000004, inst_id: inst70000223}
-// CHECK:STDOUT:     import_ir_instC6: {ir_id: import_ir58000004, inst_id: inst7000021D}
-// CHECK:STDOUT:     import_ir_instC7: {ir_id: import_ir58000004, inst_id: inst70000218}
-// CHECK:STDOUT:     import_ir_instC8: {ir_id: import_ir58000004, inst_id: inst70000237}
-// CHECK:STDOUT:     import_ir_instC9: {ir_id: import_ir58000004, inst_id: inst70000239}
-// CHECK:STDOUT:     import_ir_instCA: {ir_id: import_ir58000004, inst_id: inst70000216}
-// CHECK:STDOUT:     import_ir_instCB: {ir_id: import_ir58000004, inst_id: inst7000021B}
-// CHECK:STDOUT:     import_ir_instCC: {ir_id: import_ir58000004, inst_id: inst70000220}
-// CHECK:STDOUT:     import_ir_instCD: {ir_id: import_ir58000004, inst_id: inst70000217}
-// CHECK:STDOUT:     import_ir_instCE: {ir_id: import_ir58000004, inst_id: inst7000021C}
-// CHECK:STDOUT:     import_ir_instCF: {ir_id: import_ir58000004, inst_id: inst70000222}
-// CHECK:STDOUT:     import_ir_instD0: {ir_id: import_ir58000004, inst_id: inst7000022A}
-// CHECK:STDOUT:     import_ir_instD1: {ir_id: import_ir58000004, inst_id: inst7000022D}
-// CHECK:STDOUT:     import_ir_instD2: {ir_id: import_ir58000004, inst_id: inst70000230}
-// CHECK:STDOUT:     import_ir_instD3: {ir_id: import_ir58000004, inst_id: inst70000234}
-// CHECK:STDOUT:     import_ir_instD4: {ir_id: import_ir58000004, inst_id: inst70000238}
-// CHECK:STDOUT:     import_ir_instD5: {ir_id: import_ir58000004, inst_id: inst70000241}
-// CHECK:STDOUT:     import_ir_instD6: {ir_id: import_ir58000004, inst_id: inst70000261}
-// CHECK:STDOUT:     import_ir_instD7: {ir_id: import_ir58000004, inst_id: inst70000262}
+// CHECK:STDOUT:     import_ir_inst39: {ir_id: import_ir58000004, inst_id: inst700000C2}
+// CHECK:STDOUT:     import_ir_inst3A: {ir_id: import_ir58000004, inst_id: inst700000C0}
+// CHECK:STDOUT:     import_ir_inst3B: {ir_id: import_ir58000004, inst_id: inst700000BE}
+// CHECK:STDOUT:     import_ir_inst3C: {ir_id: import_ir58000004, inst_id: inst700000BF}
+// CHECK:STDOUT:     import_ir_inst3D: {ir_id: import_ir58000004, inst_id: inst700000DE}
+// CHECK:STDOUT:     import_ir_inst3E: {ir_id: import_ir58000004, inst_id: inst700000DC}
+// CHECK:STDOUT:     import_ir_inst3F: {ir_id: import_ir58000004, inst_id: inst700000DA}
+// CHECK:STDOUT:     import_ir_inst40: {ir_id: import_ir58000004, inst_id: inst700000DB}
+// CHECK:STDOUT:     import_ir_inst41: {ir_id: import_ir58000004, inst_id: inst700000FA}
+// CHECK:STDOUT:     import_ir_inst42: {ir_id: import_ir58000004, inst_id: inst700000F8}
+// CHECK:STDOUT:     import_ir_inst43: {ir_id: import_ir58000004, inst_id: inst700000F6}
+// CHECK:STDOUT:     import_ir_inst44: {ir_id: import_ir58000004, inst_id: inst700000F7}
+// CHECK:STDOUT:     import_ir_inst45: {ir_id: import_ir58000004, inst_id: inst70000116}
+// CHECK:STDOUT:     import_ir_inst46: {ir_id: import_ir58000004, inst_id: inst70000114}
+// CHECK:STDOUT:     import_ir_inst47: {ir_id: import_ir58000004, inst_id: inst70000112}
+// CHECK:STDOUT:     import_ir_inst48: {ir_id: import_ir58000004, inst_id: inst70000113}
+// CHECK:STDOUT:     import_ir_inst49: {ir_id: import_ir58000004, inst_id: inst70000139}
+// CHECK:STDOUT:     import_ir_inst4A: {ir_id: import_ir58000004, inst_id: inst70000137}
+// CHECK:STDOUT:     import_ir_inst4B: {ir_id: import_ir58000004, inst_id: inst7000014D}
+// CHECK:STDOUT:     import_ir_inst4C: {ir_id: import_ir58000004, inst_id: inst70000138}
+// CHECK:STDOUT:     import_ir_inst4D: {ir_id: import_ir58000004, inst_id: inst70000130}
+// CHECK:STDOUT:     import_ir_inst4E: {ir_id: import_ir58000004, inst_id: inst70000132}
+// CHECK:STDOUT:     import_ir_inst4F: {ir_id: import_ir58000004, inst_id: inst70000135}
+// CHECK:STDOUT:     import_ir_inst50: {ir_id: import_ir58000004, inst_id: inst7000012D}
+// CHECK:STDOUT:     import_ir_inst51: {ir_id: import_ir58000004, inst_id: inst7000012F}
+// CHECK:STDOUT:     import_ir_inst52: {ir_id: import_ir58000004, inst_id: inst70000134}
+// CHECK:STDOUT:     import_ir_inst53: {ir_id: import_ir58000004, inst_id: inst7000013B}
+// CHECK:STDOUT:     import_ir_inst54: {ir_id: import_ir58000004, inst_id: inst7000014D}
+// CHECK:STDOUT:     import_ir_inst55: {ir_id: import_ir58000004, inst_id: inst70000148}
+// CHECK:STDOUT:     import_ir_inst56: {ir_id: import_ir58000004, inst_id: inst70000149}
+// CHECK:STDOUT:     import_ir_inst57: {ir_id: import_ir58000004, inst_id: inst70000141}
+// CHECK:STDOUT:     import_ir_inst58: {ir_id: import_ir58000004, inst_id: inst70000143}
+// CHECK:STDOUT:     import_ir_inst59: {ir_id: import_ir58000004, inst_id: inst70000144}
+// CHECK:STDOUT:     import_ir_inst5A: {ir_id: import_ir58000004, inst_id: inst70000145}
+// CHECK:STDOUT:     import_ir_inst5B: {ir_id: import_ir58000004, inst_id: inst7000012D}
+// CHECK:STDOUT:     import_ir_inst5C: {ir_id: import_ir58000004, inst_id: inst7000013D}
+// CHECK:STDOUT:     import_ir_inst5D: {ir_id: import_ir58000004, inst_id: inst7000013E}
+// CHECK:STDOUT:     import_ir_inst5E: {ir_id: import_ir58000004, inst_id: inst70000142}
+// CHECK:STDOUT:     import_ir_inst5F: {ir_id: import_ir58000004, inst_id: inst70000147}
+// CHECK:STDOUT:     import_ir_inst60: {ir_id: import_ir58000004, inst_id: inst70000150}
+// CHECK:STDOUT:     import_ir_inst61: {ir_id: import_ir58000004, inst_id: inst70000151}
+// CHECK:STDOUT:     import_ir_inst62: {ir_id: import_ir58000004, inst_id: inst70000154}
+// CHECK:STDOUT:     import_ir_inst63: {ir_id: import_ir58000004, inst_id: inst7000015C}
+// CHECK:STDOUT:     import_ir_inst64: {ir_id: import_ir58000004, inst_id: inst7000015A}
+// CHECK:STDOUT:     import_ir_inst65: {ir_id: import_ir58000004, inst_id: inst70000158}
+// CHECK:STDOUT:     import_ir_inst66: {ir_id: import_ir58000004, inst_id: inst70000159}
+// CHECK:STDOUT:     import_ir_inst67: {ir_id: import_ir58000004, inst_id: inst70000175}
+// CHECK:STDOUT:     import_ir_inst68: {ir_id: import_ir58000004, inst_id: inst70000173}
+// CHECK:STDOUT:     import_ir_inst69: {ir_id: import_ir58000004, inst_id: inst70000171}
+// CHECK:STDOUT:     import_ir_inst6A: {ir_id: import_ir58000004, inst_id: inst70000172}
+// CHECK:STDOUT:     import_ir_inst6B: {ir_id: import_ir58000004, inst_id: inst700001AB}
+// CHECK:STDOUT:     import_ir_inst6C: {ir_id: import_ir58000004, inst_id: inst700001A9}
+// CHECK:STDOUT:     import_ir_inst6D: {ir_id: import_ir58000004, inst_id: inst700001C6}
+// CHECK:STDOUT:     import_ir_inst6E: {ir_id: import_ir58000004, inst_id: inst700001AA}
+// CHECK:STDOUT:     import_ir_inst6F: {ir_id: import_ir58000004, inst_id: inst700001C6}
+// CHECK:STDOUT:     import_ir_inst70: {ir_id: import_ir58000004, inst_id: inst700001C1}
+// CHECK:STDOUT:     import_ir_inst71: {ir_id: import_ir58000004, inst_id: inst700001C2}
+// CHECK:STDOUT:     import_ir_inst72: {ir_id: import_ir58000004, inst_id: inst700001BA}
+// CHECK:STDOUT:     import_ir_inst73: {ir_id: import_ir58000004, inst_id: inst700001BC}
+// CHECK:STDOUT:     import_ir_inst74: {ir_id: import_ir58000004, inst_id: inst700001BD}
+// CHECK:STDOUT:     import_ir_inst75: {ir_id: import_ir58000004, inst_id: inst700001BE}
+// CHECK:STDOUT:     import_ir_inst76: {ir_id: import_ir58000004, inst_id: inst7000018C}
+// CHECK:STDOUT:     import_ir_inst77: {ir_id: import_ir58000004, inst_id: inst70000191}
+// CHECK:STDOUT:     import_ir_inst78: {ir_id: import_ir58000004, inst_id: inst700001B3}
+// CHECK:STDOUT:     import_ir_inst79: {ir_id: import_ir58000004, inst_id: inst700001B4}
+// CHECK:STDOUT:     import_ir_inst7A: {ir_id: import_ir58000004, inst_id: inst700001B5}
+// CHECK:STDOUT:     import_ir_inst7B: {ir_id: import_ir58000004, inst_id: inst700001B6}
+// CHECK:STDOUT:     import_ir_inst7C: {ir_id: import_ir58000004, inst_id: inst700001B7}
+// CHECK:STDOUT:     import_ir_inst7D: {ir_id: import_ir58000004, inst_id: inst700001BB}
+// CHECK:STDOUT:     import_ir_inst7E: {ir_id: import_ir58000004, inst_id: inst700001C0}
+// CHECK:STDOUT:     import_ir_inst7F: {ir_id: import_ir58000004, inst_id: inst700001D1}
+// CHECK:STDOUT:     import_ir_inst80: {ir_id: import_ir58000004, inst_id: inst700001D7}
+// CHECK:STDOUT:     import_ir_inst81: {ir_id: import_ir58000004, inst_id: inst700001DA}
+// CHECK:STDOUT:     import_ir_inst82: {ir_id: import_ir58000004, inst_id: inst700001DC}
+// CHECK:STDOUT:     import_ir_inst83: {ir_id: import_ir58000004, inst_id: inst700001DD}
+// CHECK:STDOUT:     import_ir_inst84: {ir_id: import_ir58000004, inst_id: inst700001DE}
+// CHECK:STDOUT:     import_ir_inst85: {ir_id: import_ir58000004, inst_id: inst700001E1}
+// CHECK:STDOUT:     import_ir_inst86: {ir_id: import_ir58000004, inst_id: inst700001EB}
+// CHECK:STDOUT:     import_ir_inst87: {ir_id: import_ir58000004, inst_id: inst700001F1}
+// CHECK:STDOUT:     import_ir_inst88: {ir_id: import_ir58000004, inst_id: inst700001F5}
+// CHECK:STDOUT:     import_ir_inst89: {ir_id: import_ir58000004, inst_id: inst700001F6}
+// CHECK:STDOUT:     import_ir_inst8A: {ir_id: import_ir58000004, inst_id: inst700001F7}
+// CHECK:STDOUT:     import_ir_inst8B: {ir_id: import_ir58000004, inst_id: inst700001FD}
+// CHECK:STDOUT:     import_ir_inst8C: {ir_id: import_ir58000004, inst_id: inst70000194}
+// CHECK:STDOUT:     import_ir_inst8D: {ir_id: import_ir58000004, inst_id: inst7000018E}
+// CHECK:STDOUT:     import_ir_inst8E: {ir_id: import_ir58000004, inst_id: inst700001A4}
+// CHECK:STDOUT:     import_ir_inst8F: {ir_id: import_ir58000004, inst_id: inst700001A6}
+// CHECK:STDOUT:     import_ir_inst90: {ir_id: import_ir58000004, inst_id: inst7000018C}
+// CHECK:STDOUT:     import_ir_inst91: {ir_id: import_ir58000004, inst_id: inst70000191}
+// CHECK:STDOUT:     import_ir_inst92: {ir_id: import_ir58000004, inst_id: inst7000018D}
+// CHECK:STDOUT:     import_ir_inst93: {ir_id: import_ir58000004, inst_id: inst70000193}
+// CHECK:STDOUT:     import_ir_inst94: {ir_id: import_ir58000004, inst_id: inst7000019A}
+// CHECK:STDOUT:     import_ir_inst95: {ir_id: import_ir58000004, inst_id: inst7000019D}
+// CHECK:STDOUT:     import_ir_inst96: {ir_id: import_ir58000004, inst_id: inst700001A1}
+// CHECK:STDOUT:     import_ir_inst97: {ir_id: import_ir58000004, inst_id: inst700001A5}
+// CHECK:STDOUT:     import_ir_inst98: {ir_id: import_ir58000004, inst_id: inst700001AD}
+// CHECK:STDOUT:     import_ir_inst99: {ir_id: import_ir58000004, inst_id: inst700001C9}
+// CHECK:STDOUT:     import_ir_inst9A: {ir_id: import_ir58000004, inst_id: inst700001CA}
+// CHECK:STDOUT:     import_ir_inst9B: {ir_id: import_ir58000004, inst_id: inst70000237}
+// CHECK:STDOUT:     import_ir_inst9C: {ir_id: import_ir58000004, inst_id: inst70000235}
+// CHECK:STDOUT:     import_ir_inst9D: {ir_id: import_ir58000004, inst_id: inst70000256}
+// CHECK:STDOUT:     import_ir_inst9E: {ir_id: import_ir58000004, inst_id: inst70000236}
+// CHECK:STDOUT:     import_ir_inst9F: {ir_id: import_ir58000004, inst_id: inst70000256}
+// CHECK:STDOUT:     import_ir_instA0: {ir_id: import_ir58000004, inst_id: inst70000251}
+// CHECK:STDOUT:     import_ir_instA1: {ir_id: import_ir58000004, inst_id: inst70000252}
+// CHECK:STDOUT:     import_ir_instA2: {ir_id: import_ir58000004, inst_id: inst7000024A}
+// CHECK:STDOUT:     import_ir_instA3: {ir_id: import_ir58000004, inst_id: inst7000024C}
+// CHECK:STDOUT:     import_ir_instA4: {ir_id: import_ir58000004, inst_id: inst7000024D}
+// CHECK:STDOUT:     import_ir_instA5: {ir_id: import_ir58000004, inst_id: inst7000024E}
+// CHECK:STDOUT:     import_ir_instA6: {ir_id: import_ir58000004, inst_id: inst7000020E}
+// CHECK:STDOUT:     import_ir_instA7: {ir_id: import_ir58000004, inst_id: inst70000213}
+// CHECK:STDOUT:     import_ir_instA8: {ir_id: import_ir58000004, inst_id: inst70000218}
+// CHECK:STDOUT:     import_ir_instA9: {ir_id: import_ir58000004, inst_id: inst70000241}
+// CHECK:STDOUT:     import_ir_instAA: {ir_id: import_ir58000004, inst_id: inst70000242}
+// CHECK:STDOUT:     import_ir_instAB: {ir_id: import_ir58000004, inst_id: inst70000243}
+// CHECK:STDOUT:     import_ir_instAC: {ir_id: import_ir58000004, inst_id: inst70000244}
+// CHECK:STDOUT:     import_ir_instAD: {ir_id: import_ir58000004, inst_id: inst70000245}
+// CHECK:STDOUT:     import_ir_instAE: {ir_id: import_ir58000004, inst_id: inst70000246}
+// CHECK:STDOUT:     import_ir_instAF: {ir_id: import_ir58000004, inst_id: inst70000247}
+// CHECK:STDOUT:     import_ir_instB0: {ir_id: import_ir58000004, inst_id: inst7000024B}
+// CHECK:STDOUT:     import_ir_instB1: {ir_id: import_ir58000004, inst_id: inst70000250}
+// CHECK:STDOUT:     import_ir_instB2: {ir_id: import_ir58000004, inst_id: inst70000261}
+// CHECK:STDOUT:     import_ir_instB3: {ir_id: import_ir58000004, inst_id: inst70000266}
+// CHECK:STDOUT:     import_ir_instB4: {ir_id: import_ir58000004, inst_id: inst70000269}
+// CHECK:STDOUT:     import_ir_instB5: {ir_id: import_ir58000004, inst_id: inst7000026B}
+// CHECK:STDOUT:     import_ir_instB6: {ir_id: import_ir58000004, inst_id: inst7000026C}
+// CHECK:STDOUT:     import_ir_instB7: {ir_id: import_ir58000004, inst_id: inst7000026D}
+// CHECK:STDOUT:     import_ir_instB8: {ir_id: import_ir58000004, inst_id: inst70000270}
+// CHECK:STDOUT:     import_ir_instB9: {ir_id: import_ir58000004, inst_id: inst70000278}
+// CHECK:STDOUT:     import_ir_instBA: {ir_id: import_ir58000004, inst_id: inst7000027B}
+// CHECK:STDOUT:     import_ir_instBB: {ir_id: import_ir58000004, inst_id: inst7000027D}
+// CHECK:STDOUT:     import_ir_instBC: {ir_id: import_ir58000004, inst_id: inst7000027E}
+// CHECK:STDOUT:     import_ir_instBD: {ir_id: import_ir58000004, inst_id: inst7000027F}
+// CHECK:STDOUT:     import_ir_instBE: {ir_id: import_ir58000004, inst_id: inst70000282}
+// CHECK:STDOUT:     import_ir_instBF: {ir_id: import_ir58000004, inst_id: inst7000028C}
+// CHECK:STDOUT:     import_ir_instC0: {ir_id: import_ir58000004, inst_id: inst70000292}
+// CHECK:STDOUT:     import_ir_instC1: {ir_id: import_ir58000004, inst_id: inst70000296}
+// CHECK:STDOUT:     import_ir_instC2: {ir_id: import_ir58000004, inst_id: inst70000297}
+// CHECK:STDOUT:     import_ir_instC3: {ir_id: import_ir58000004, inst_id: inst70000298}
+// CHECK:STDOUT:     import_ir_instC4: {ir_id: import_ir58000004, inst_id: inst7000029E}
+// CHECK:STDOUT:     import_ir_instC5: {ir_id: import_ir58000004, inst_id: inst7000021B}
+// CHECK:STDOUT:     import_ir_instC6: {ir_id: import_ir58000004, inst_id: inst70000215}
+// CHECK:STDOUT:     import_ir_instC7: {ir_id: import_ir58000004, inst_id: inst70000210}
+// CHECK:STDOUT:     import_ir_instC8: {ir_id: import_ir58000004, inst_id: inst7000022F}
+// CHECK:STDOUT:     import_ir_instC9: {ir_id: import_ir58000004, inst_id: inst70000231}
+// CHECK:STDOUT:     import_ir_instCA: {ir_id: import_ir58000004, inst_id: inst7000020E}
+// CHECK:STDOUT:     import_ir_instCB: {ir_id: import_ir58000004, inst_id: inst70000213}
+// CHECK:STDOUT:     import_ir_instCC: {ir_id: import_ir58000004, inst_id: inst70000218}
+// CHECK:STDOUT:     import_ir_instCD: {ir_id: import_ir58000004, inst_id: inst7000020F}
+// CHECK:STDOUT:     import_ir_instCE: {ir_id: import_ir58000004, inst_id: inst70000214}
+// CHECK:STDOUT:     import_ir_instCF: {ir_id: import_ir58000004, inst_id: inst7000021A}
+// CHECK:STDOUT:     import_ir_instD0: {ir_id: import_ir58000004, inst_id: inst70000222}
+// CHECK:STDOUT:     import_ir_instD1: {ir_id: import_ir58000004, inst_id: inst70000225}
+// CHECK:STDOUT:     import_ir_instD2: {ir_id: import_ir58000004, inst_id: inst70000228}
+// CHECK:STDOUT:     import_ir_instD3: {ir_id: import_ir58000004, inst_id: inst7000022C}
+// CHECK:STDOUT:     import_ir_instD4: {ir_id: import_ir58000004, inst_id: inst70000230}
+// CHECK:STDOUT:     import_ir_instD5: {ir_id: import_ir58000004, inst_id: inst70000239}
+// CHECK:STDOUT:     import_ir_instD6: {ir_id: import_ir58000004, inst_id: inst70000259}
+// CHECK:STDOUT:     import_ir_instD7: {ir_id: import_ir58000004, inst_id: inst7000025A}
 // CHECK:STDOUT:   clang_decls:     {}
 // CHECK:STDOUT:   name_scopes:
 // CHECK:STDOUT:     name_scope0:     {inst: instF, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Core): inst58000011, name0: inst5800003E}}
@@ -832,15 +832,14 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:     inst58000180:    {kind: SpecificImplFunction, arg0: inst58000179, arg1: specific58000025, type: type(inst(SpecificFunctionType))}
 // CHECK:STDOUT:     inst58000181:    {kind: SpecificImplFunction, arg0: inst5800017D, arg1: specific58000026, type: type(inst(SpecificFunctionType))}
 // CHECK:STDOUT:     inst58000182:    {kind: BoundMethod, arg0: inst58000048, arg1: inst5800017F, type: type(inst(BoundMethodType))}
-// CHECK:STDOUT:     inst58000183:    {kind: RequireCompleteType, arg0: inst5800001D, type: type(inst(WitnessType))}
-// CHECK:STDOUT:     inst58000184:    {kind: Call, arg0: inst58000182, arg1: inst_block5800008F, type: type(symbolic_constant58000004)}
-// CHECK:STDOUT:     inst58000185:    {kind: InPlaceInit, arg0: inst58000184, arg1: inst5800004C, type: type(symbolic_constant58000004)}
-// CHECK:STDOUT:     inst58000186:    {kind: TupleAccess, arg0: inst5800003C, arg1: element1, type: type(inst58000026)}
-// CHECK:STDOUT:     inst58000187:    {kind: TupleInit, arg0: inst_block_empty, arg1: inst<none>, type: type(inst58000026)}
-// CHECK:STDOUT:     inst58000188:    {kind: Converted, arg0: inst58000049, arg1: inst58000187, type: type(inst58000026)}
-// CHECK:STDOUT:     inst58000189:    {kind: TupleInit, arg0: inst_block58000090, arg1: inst5800003C, type: type(symbolic_constant5800000A)}
-// CHECK:STDOUT:     inst5800018A:    {kind: Converted, arg0: inst5800004A, arg1: inst58000189, type: type(symbolic_constant5800000A)}
-// CHECK:STDOUT:     inst5800018B:    {kind: ReturnExpr, arg0: inst5800018A, arg1: inst5800003C}
+// CHECK:STDOUT:     inst58000183:    {kind: Call, arg0: inst58000182, arg1: inst_block5800008F, type: type(symbolic_constant58000004)}
+// CHECK:STDOUT:     inst58000184:    {kind: InPlaceInit, arg0: inst58000183, arg1: inst5800004C, type: type(symbolic_constant58000004)}
+// CHECK:STDOUT:     inst58000185:    {kind: TupleAccess, arg0: inst5800003C, arg1: element1, type: type(inst58000026)}
+// CHECK:STDOUT:     inst58000186:    {kind: TupleInit, arg0: inst_block_empty, arg1: inst<none>, type: type(inst58000026)}
+// CHECK:STDOUT:     inst58000187:    {kind: Converted, arg0: inst58000049, arg1: inst58000186, type: type(inst58000026)}
+// CHECK:STDOUT:     inst58000188:    {kind: TupleInit, arg0: inst_block58000090, arg1: inst5800003C, type: type(symbolic_constant5800000A)}
+// CHECK:STDOUT:     inst58000189:    {kind: Converted, arg0: inst5800004A, arg1: inst58000188, type: type(symbolic_constant5800000A)}
+// CHECK:STDOUT:     inst5800018A:    {kind: ReturnExpr, arg0: inst58000189, arg1: inst5800003C}
 // CHECK:STDOUT:   constant_values:
 // CHECK:STDOUT:     values:
 // CHECK:STDOUT:       instF:           concrete_constant(instF)
@@ -1205,9 +1204,8 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:       inst5800017F:    symbolic_constant5800014D
 // CHECK:STDOUT:       inst58000180:    symbolic_constant5800014C
 // CHECK:STDOUT:       inst58000181:    symbolic_constant5800014D
-// CHECK:STDOUT:       inst58000183:    symbolic_constant58000010
+// CHECK:STDOUT:       inst58000186:    concrete_constant(inst58000028)
 // CHECK:STDOUT:       inst58000187:    concrete_constant(inst58000028)
-// CHECK:STDOUT:       inst58000188:    concrete_constant(inst58000028)
 // CHECK:STDOUT:     symbolic_constants:
 // CHECK:STDOUT:       symbolic_constant58000000: {inst: inst58000014, kind: self, attached: null}
 // CHECK:STDOUT:       symbolic_constant58000001: {inst: inst58000017, kind: checked, attached: null}
@@ -1752,15 +1750,15 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:       4:               inst5800017E
 // CHECK:STDOUT:       5:               inst5800017F
 // CHECK:STDOUT:       6:               inst58000182
-// CHECK:STDOUT:       7:               inst58000184
+// CHECK:STDOUT:       7:               inst58000183
 // CHECK:STDOUT:       8:               inst5800004C
-// CHECK:STDOUT:       9:               inst58000185
-// CHECK:STDOUT:       10:              inst58000186
-// CHECK:STDOUT:       11:              inst58000187
-// CHECK:STDOUT:       12:              inst58000188
-// CHECK:STDOUT:       13:              inst58000189
-// CHECK:STDOUT:       14:              inst5800018A
-// CHECK:STDOUT:       15:              inst5800018B
+// CHECK:STDOUT:       9:               inst58000184
+// CHECK:STDOUT:       10:              inst58000185
+// CHECK:STDOUT:       11:              inst58000186
+// CHECK:STDOUT:       12:              inst58000187
+// CHECK:STDOUT:       13:              inst58000188
+// CHECK:STDOUT:       14:              inst58000189
+// CHECK:STDOUT:       15:              inst5800018A
 // CHECK:STDOUT:     inst_block5800001A:
 // CHECK:STDOUT:       0:               inst58000048
 // CHECK:STDOUT:       1:               inst58000049
@@ -2193,8 +2191,8 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
 // CHECK:STDOUT:     inst_block5800008F:
 // CHECK:STDOUT:       0:               inst58000048
 // CHECK:STDOUT:     inst_block58000090:
-// CHECK:STDOUT:       0:               inst58000185
-// CHECK:STDOUT:       1:               inst58000188
+// CHECK:STDOUT:       0:               inst58000184
+// CHECK:STDOUT:       1:               inst58000187
 // CHECK:STDOUT:     inst_block58000091:
 // CHECK:STDOUT:       0:               inst58000043
 // CHECK:STDOUT:       1:               inst58000047

+ 7 - 24
toolchain/check/testdata/class/abstract/abstract.carbon

@@ -62,20 +62,13 @@ abstract class Abstract {
 fn F(var _: Abstract) {
 }
 
-// --- fail_todo_abstract_let.carbon
+// --- abstract_let.carbon
 library "[[@TEST_NAME]]";
 
 abstract class Abstract {
 }
 
 fn F(a: Abstract) {
-  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE+7]]:28: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
-  // CHECK:STDERR:   let unused l: Abstract = a;
-  // CHECK:STDERR:                            ^
-  // CHECK:STDERR: fail_todo_abstract_let.carbon:[[@LINE-7]]:1: note: class was declared abstract here [ClassAbstractHere]
-  // CHECK:STDERR: abstract class Abstract {
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR:
   let unused l: Abstract = a;
 }
 
@@ -97,7 +90,7 @@ class Adapter {
   adapt Abstract;
 }
 
-// --- fail_todo_define_and_call_abstract_param.carbon
+// --- define_and_call_abstract_param.carbon
 library "[[@TEST_NAME]]";
 
 abstract class Abstract {
@@ -106,16 +99,6 @@ abstract class Abstract {
 fn Param(a: Abstract);
 
 fn Call(p: Abstract) {
-  // CHECK:STDERR: fail_todo_define_and_call_abstract_param.carbon:[[@LINE+10]]:9: error: initialization of abstract type `Abstract` [AbstractTypeInInit]
-  // CHECK:STDERR:   Param(p);
-  // CHECK:STDERR:         ^
-  // CHECK:STDERR: fail_todo_define_and_call_abstract_param.carbon:[[@LINE-9]]:1: note: class was declared abstract here [ClassAbstractHere]
-  // CHECK:STDERR: abstract class Abstract {
-  // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_todo_define_and_call_abstract_param.carbon:[[@LINE-9]]:10: note: initializing function parameter [InCallToFunctionParam]
-  // CHECK:STDERR: fn Param(a: Abstract);
-  // CHECK:STDERR:          ^~~~~~~~~~~
-  // CHECK:STDERR:
   Param(p);
 }
 
@@ -393,7 +376,7 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: --- fail_todo_abstract_let.carbon
+// CHECK:STDOUT: --- abstract_let.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Abstract: type = class_type @Abstract [concrete]
@@ -443,8 +426,8 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:     %l.patt: %pattern_type = value_binding_pattern l [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %a.ref: %Abstract = name_ref a, %a
-// CHECK:STDOUT:   %Abstract.ref.loc14: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract]
-// CHECK:STDOUT:   %l: %Abstract = value_binding l, <error> [concrete = <error>]
+// CHECK:STDOUT:   %Abstract.ref.loc7: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract]
+// CHECK:STDOUT:   %l: %Abstract = value_binding l, %a.ref
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -494,7 +477,7 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT:   .Abstract = <poisoned>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: --- fail_todo_define_and_call_abstract_param.carbon
+// CHECK:STDOUT: --- define_and_call_abstract_param.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Abstract: type = class_type @Abstract [concrete]
@@ -556,7 +539,7 @@ fn CallReturnAbstract() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Param.ref: %Param.type = name_ref Param, file.%Param.decl [concrete = constants.%Param]
 // CHECK:STDOUT:   %p.ref: %Abstract = name_ref p, %p
-// CHECK:STDOUT:   %Param.call: init %empty_tuple.type = call %Param.ref(<error>)
+// CHECK:STDOUT:   %Param.call: init %empty_tuple.type = call %Param.ref(%p.ref)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 0 - 19
toolchain/check/testdata/class/fail_incomplete.carbon

@@ -142,25 +142,6 @@ fn CallReturnIncomplete() {
   ReturnIncomplete();
 }
 
-class IncompleteRefSelf {
-  fn F[ref self: Class]();
-}
-
-fn CallIncompleteAddrSelf(p: Class*) {
-  // TODO: Should this be valid?
-  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE+10]]:3: error: invalid use of incomplete type `Class` [IncompleteTypeInConversion]
-  // CHECK:STDERR:   p->(IncompleteRefSelf.F)();
-  // CHECK:STDERR:   ^~~~~~~~~~~~~~~~~~~~~~~~
-  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-137]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
-  // CHECK:STDERR: class Class;
-  // CHECK:STDERR: ^~~~~~~~~~~~
-  // CHECK:STDERR: fail_forward_decl.carbon:[[@LINE-11]]:8: note: initializing function parameter [InCallToFunctionParam]
-  // CHECK:STDERR:   fn F[ref self: Class]();
-  // CHECK:STDERR:        ^~~~~~~~~~~~~~~
-  // CHECK:STDERR:
-  p->(IncompleteRefSelf.F)();
-}
-
 // --- fail_in_definition.carbon
 
 library "[[@TEST_NAME]]";

+ 3 - 6
toolchain/check/testdata/class/generic/method_deduce.carbon

@@ -271,11 +271,10 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
 // CHECK:STDOUT:   %pattern_type.loc20_34: type = pattern_type %tuple.type [symbolic = %pattern_type.loc20_34 (constants.%pattern_type.eee)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc20_19: <witness> = require_complete_type %T [symbolic = %require_complete.loc20_19 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.944)]
 // CHECK:STDOUT:   %Class.GetNoDeduce.type: type = fn_type @Class.GetNoDeduce, @Class(%T) [symbolic = %Class.GetNoDeduce.type (constants.%Class.GetNoDeduce.type.cf2)]
 // CHECK:STDOUT:   %Class.GetNoDeduce: @Class.GetNoDeduce.%Class.GetNoDeduce.type (%Class.GetNoDeduce.type.cf2) = struct_value () [symbolic = %Class.GetNoDeduce (constants.%Class.GetNoDeduce.1a5)]
 // CHECK:STDOUT:   %Class.GetNoDeduce.specific_fn.loc20_53.2: <specific function> = specific_function %Class.GetNoDeduce, @Class.GetNoDeduce(%T, %U.loc20_24.1) [symbolic = %Class.GetNoDeduce.specific_fn.loc20_53.2 (constants.%Class.GetNoDeduce.specific_fn.710)]
-// CHECK:STDOUT:   %require_complete.loc20_70: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc20_70 (constants.%require_complete.220)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%x.param: @Class.GetNoDeduce.%T (%T)) -> out %return.param: @Class.GetNoDeduce.%tuple.type (%tuple.type.a5e) {
 // CHECK:STDOUT:   !entry:
@@ -359,11 +358,10 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
 // CHECK:STDOUT:   %pattern_type.loc20_34 => constants.%pattern_type.eee
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc20_19 => constants.%require_complete.944
+// CHECK:STDOUT:   %require_complete => constants.%require_complete.944
 // CHECK:STDOUT:   %Class.GetNoDeduce.type => constants.%Class.GetNoDeduce.type.cf2
 // CHECK:STDOUT:   %Class.GetNoDeduce => constants.%Class.GetNoDeduce.1a5
 // CHECK:STDOUT:   %Class.GetNoDeduce.specific_fn.loc20_53.2 => constants.%Class.GetNoDeduce.specific_fn.710
-// CHECK:STDOUT:   %require_complete.loc20_70 => constants.%require_complete.220
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Class(constants.%A) {
@@ -401,10 +399,9 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) {
 // CHECK:STDOUT:   %pattern_type.loc20_34 => constants.%pattern_type.b74
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc20_19 => constants.%complete_type.357
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.357
 // CHECK:STDOUT:   %Class.GetNoDeduce.type => constants.%Class.GetNoDeduce.type.902
 // CHECK:STDOUT:   %Class.GetNoDeduce => constants.%Class.GetNoDeduce.472
 // CHECK:STDOUT:   %Class.GetNoDeduce.specific_fn.loc20_53.2 => constants.%Class.GetNoDeduce.specific_fn.83b
-// CHECK:STDOUT:   %require_complete.loc20_70 => constants.%complete_type.f71
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 21 - 0
toolchain/check/testdata/class/incomplete_ref.carbon

@@ -0,0 +1,21 @@
+// 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
+//
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
+//
+// AUTOUPDATE
+// TIP: To test this file alone, run:
+// TIP:   bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/incomplete_ref.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/incomplete_ref.carbon
+
+class Class;
+
+class IncompleteRefSelf {
+  fn F[ref self: Class]();
+}
+
+fn CallIncompleteRefSelf(p: Class*) {
+  p->(IncompleteRefSelf.F)();
+}

+ 8 - 16
toolchain/check/testdata/deduce/array.carbon

@@ -163,9 +163,8 @@ fn G() {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
-// CHECK:STDOUT:   %require_complete.ff3: <witness> = require_complete_type %array_type.3ec [symbolic]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.3ec [symbolic]
 // CHECK:STDOUT:   %F.specific_fn.643: <specific function> = specific_function %F, @F(%T) [symbolic]
-// CHECK:STDOUT:   %require_complete.944: <witness> = require_complete_type %T [symbolic]
 // CHECK:STDOUT:   %.a69: Core.Form = init_form %C [concrete]
 // CHECK:STDOUT:   %pattern_type.7c7: type = pattern_type %C [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
@@ -256,9 +255,8 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_32 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.ff3)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.643)]
-// CHECK:STDOUT:   %require_complete.loc6_50: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_50 (constants.%require_complete.944)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_29.1 (%array_type.3ec)) -> out %return.param: @F.%T.loc6_6.1 (%T) {
 // CHECK:STDOUT:   !entry:
@@ -324,9 +322,8 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.51d
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.ff3
+// CHECK:STDOUT:   %require_complete => constants.%require_complete
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.643
-// CHECK:STDOUT:   %require_complete.loc6_50 => constants.%require_complete.944
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%C) {
@@ -337,9 +334,8 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.7c7
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.c7a
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.c7a
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.540
-// CHECK:STDOUT:   %require_complete.loc6_50 => constants.%complete_type.357
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- bound_only.carbon
@@ -757,9 +753,8 @@ fn G() {
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
-// CHECK:STDOUT:   %require_complete.fc9: <witness> = require_complete_type %array_type.a0b [symbolic]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.a0b [symbolic]
 // CHECK:STDOUT:   %F.specific_fn.643: <specific function> = specific_function %F, @F(%T) [symbolic]
-// CHECK:STDOUT:   %require_complete.944: <witness> = require_complete_type %T [symbolic]
 // CHECK:STDOUT:   %.a69: Core.Form = init_form %C [concrete]
 // CHECK:STDOUT:   %pattern_type.7c7: type = pattern_type %C [concrete]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
@@ -856,9 +851,8 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc6_32 (constants.%pattern_type.51d1c4.1)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_17: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.fc9)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.643)]
-// CHECK:STDOUT:   %require_complete.loc6_50: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc6_50 (constants.%require_complete.944)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%a.param: @F.%array_type.loc6_29.1 (%array_type.a0b)) -> out %return.param: @F.%T.loc6_6.1 (%T) {
 // CHECK:STDOUT:   !entry:
@@ -924,9 +918,8 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.51d1c4.1
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_17 => constants.%require_complete.fc9
+// CHECK:STDOUT:   %require_complete => constants.%require_complete
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.643
-// CHECK:STDOUT:   %require_complete.loc6_50 => constants.%require_complete.944
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%C) {
@@ -937,9 +930,8 @@ fn G() {
 // CHECK:STDOUT:   %pattern_type.loc6_32 => constants.%pattern_type.7c7
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc6_17 => constants.%complete_type.b8b
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.b8b
 // CHECK:STDOUT:   %F.specific_fn.loc6_46.2 => constants.%F.specific_fn.540
-// CHECK:STDOUT:   %require_complete.loc6_50 => constants.%complete_type.357
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- fail_type_mismatch.carbon

+ 4 - 8
toolchain/check/testdata/deduce/tuple.carbon

@@ -77,9 +77,8 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %pattern_type.946: type = pattern_type %U [symbolic]
 // CHECK:STDOUT:   %F.type: type = fn_type @F [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
-// CHECK:STDOUT:   %require_complete.220: <witness> = require_complete_type %tuple.type.a5e [symbolic]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %tuple.type.a5e [symbolic]
 // CHECK:STDOUT:   %F.specific_fn.a54: <specific function> = specific_function %F, @F(%T, %U) [symbolic]
-// CHECK:STDOUT:   %require_complete.441: <witness> = require_complete_type %U [symbolic]
 // CHECK:STDOUT:   %tuple.a0a: %tuple.type.24b = tuple_value (%C, %D) [concrete]
 // CHECK:STDOUT:   %tuple.type.281: type = tuple_type (%C, %D) [concrete]
 // CHECK:STDOUT:   %pattern_type.881: type = pattern_type %tuple.type.281 [concrete]
@@ -187,9 +186,8 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %pattern_type.loc7_40: type = pattern_type %U.loc7_16.1 [symbolic = %pattern_type.loc7_40 (constants.%pattern_type.946)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_30: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc7_30 (constants.%require_complete.220)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %tuple.type [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:   %F.specific_fn.loc7_54.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.1, %U.loc7_16.1) [symbolic = %F.specific_fn.loc7_54.2 (constants.%F.specific_fn.a54)]
-// CHECK:STDOUT:   %require_complete.loc7_61: <witness> = require_complete_type %U.loc7_16.1 [symbolic = %require_complete.loc7_61 (constants.%require_complete.441)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%pair.param: @F.%tuple.type (%tuple.type.a5e)) -> out %return.param: @F.%U.loc7_16.1 (%U) {
 // CHECK:STDOUT:   !entry:
@@ -222,9 +220,8 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %pattern_type.loc7_40 => constants.%pattern_type.946
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_30 => constants.%require_complete.220
+// CHECK:STDOUT:   %require_complete => constants.%require_complete
 // CHECK:STDOUT:   %F.specific_fn.loc7_54.2 => constants.%F.specific_fn.a54
-// CHECK:STDOUT:   %require_complete.loc7_61 => constants.%require_complete.441
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F(constants.%C, constants.%D) {
@@ -237,9 +234,8 @@ fn G(pair: (C, D)) -> D {
 // CHECK:STDOUT:   %pattern_type.loc7_40 => constants.%pattern_type.9c8
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc7_30 => constants.%complete_type.734
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.734
 // CHECK:STDOUT:   %F.specific_fn.loc7_54.2 => constants.%F.specific_fn.107
-// CHECK:STDOUT:   %require_complete.loc7_61 => constants.%complete_type.357
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: --- tuple_value.carbon

+ 0 - 2
toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon

@@ -229,7 +229,6 @@ fn F[A:! J, B:! A](x: C(A, B)) {
 // CHECK:STDOUT:   %pattern_type.14f: type = pattern_type %A.binding.as_type [symbolic]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %C: type = class_type @C, @C(%A, %B) [symbolic]
-// CHECK:STDOUT:   %require_complete.19a: <witness> = require_complete_type %A.binding.as_type [symbolic]
 // CHECK:STDOUT:   %pattern_type.e04: type = pattern_type %C [symbolic]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
@@ -259,7 +258,6 @@ fn F[A:! J, B:! A](x: C(A, B)) {
 // CHECK:STDOUT:   %A.binding.as_type => constants.%A.binding.as_type
 // CHECK:STDOUT:   %B.loc25_13.1 => constants.%B
 // CHECK:STDOUT:   %pattern_type.loc25_13 => constants.%pattern_type.14f
-// CHECK:STDOUT:   %require_complete.loc25_29 => constants.%require_complete.19a
 // CHECK:STDOUT:   %C.loc25_29.1 => constants.%C
 // CHECK:STDOUT:   %pattern_type.loc25_20 => constants.%pattern_type.e04
 // CHECK:STDOUT: }

+ 0 - 1
toolchain/check/testdata/function/generic/deduce.carbon

@@ -498,7 +498,6 @@ fn F() {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %ExplicitGenericParam.specific_fn.loc7_3.2: <specific function> = specific_function constants.%ExplicitGenericParam, @ExplicitGenericParam(%T.loc6_34.1) [symbolic = %ExplicitGenericParam.specific_fn.loc7_3.2 (constants.%ExplicitGenericParam.specific_fn)]
 // CHECK:STDOUT:   %ptr: type = ptr_type %T.loc6_34.1 [symbolic = %ptr (constants.%ptr)]
-// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %ptr [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:

+ 32 - 25
toolchain/check/testdata/generic/complete_type.carbon

@@ -66,16 +66,16 @@ library "[[@TEST_NAME]]";
 class B;
 
 fn F(T:! type) {
-  var v: T*;
-  *v;
+  var p: T*;
+  let _: T = *p;
 }
 
 // CHECK:STDERR: fail_incomplete_in_function_at_eof.carbon:[[@LINE+10]]:10: error: unable to monomorphize specific `F(B)` [ResolvingSpecificHere]
 // CHECK:STDERR: fn G() { F(B); }
 // CHECK:STDERR:          ^
-// CHECK:STDERR: fail_incomplete_in_function_at_eof.carbon:[[@LINE-6]]:3: note: `T` evaluates to incomplete type `B` [IncompleteTypeInMonomorphization]
-// CHECK:STDERR:   *v;
-// CHECK:STDERR:   ^~
+// CHECK:STDERR: fail_incomplete_in_function_at_eof.carbon:[[@LINE-6]]:10: note: `T` evaluates to incomplete type `B` [IncompleteTypeInMonomorphization]
+// CHECK:STDERR:   let _: T = *p;
+// CHECK:STDERR:          ^
 // CHECK:STDERR: fail_incomplete_in_function_at_eof.carbon:[[@LINE-13]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
 // CHECK:STDERR: class B;
 // CHECK:STDERR: ^~~~~~~~
@@ -211,9 +211,8 @@ fn G() { F(B); }
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
 // CHECK:STDOUT:   %F: %F.type = struct_value () [concrete]
 // CHECK:STDOUT:   %ptr.e8f: type = ptr_type %T [symbolic]
-// CHECK:STDOUT:   %require_complete.ef1: <witness> = require_complete_type %ptr.e8f [symbolic]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %ptr.e8f [symbolic]
 // CHECK:STDOUT:   %pattern_type.4f4: type = pattern_type %ptr.e8f [symbolic]
-// CHECK:STDOUT:   %require_complete.944: <witness> = require_complete_type %T [symbolic]
 // CHECK:STDOUT:   %Destroy.type: type = facet_type <@Destroy> [concrete]
 // CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.e8f, @Destroy [symbolic]
 // CHECK:STDOUT:   %Destroy.facet.617: %Destroy.type = facet_value %ptr.e8f, (%Destroy.lookup_impl_witness) [symbolic]
@@ -281,9 +280,8 @@ fn G() { F(B); }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %ptr.loc7_11.2: type = ptr_type %T.loc6_6.1 [symbolic = %ptr.loc7_11.2 (constants.%ptr.e8f)]
-// CHECK:STDOUT:   %require_complete.loc7: <witness> = require_complete_type %ptr.loc7_11.2 [symbolic = %require_complete.loc7 (constants.%require_complete.ef1)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %ptr.loc7_11.2 [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:   %pattern_type: type = pattern_type %ptr.loc7_11.2 [symbolic = %pattern_type (constants.%pattern_type.4f4)]
-// CHECK:STDOUT:   %require_complete.loc8: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc8 (constants.%require_complete.944)]
 // CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc7_11.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
 // CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %ptr.loc7_11.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.617)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Destroy.facet) [symbolic = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.bb2)]
@@ -335,9 +333,8 @@ fn G() { F(B); }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %ptr.loc7_11.2 => constants.%ptr.27c
-// CHECK:STDOUT:   %require_complete.loc7 => constants.%complete_type.04a
+// CHECK:STDOUT:   %require_complete => constants.%complete_type.04a
 // CHECK:STDOUT:   %pattern_type => constants.%pattern_type.191
-// CHECK:STDOUT:   %require_complete.loc8 => constants.%complete_type.357
 // CHECK:STDOUT:   %Destroy.lookup_impl_witness => constants.%custom_witness.8d7
 // CHECK:STDOUT:   %Destroy.facet => constants.%Destroy.facet.d35
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type => constants.%Destroy.WithSelf.Op.type.540
@@ -361,6 +358,7 @@ fn G() { F(B); }
 // CHECK:STDOUT:   %require_complete.ef1: <witness> = require_complete_type %ptr.e8f [symbolic]
 // CHECK:STDOUT:   %pattern_type.4f4: type = pattern_type %ptr.e8f [symbolic]
 // CHECK:STDOUT:   %require_complete.944: <witness> = require_complete_type %T [symbolic]
+// CHECK:STDOUT:   %pattern_type.51d: type = pattern_type %T [symbolic]
 // CHECK:STDOUT:   %Destroy.type: type = facet_type <@Destroy> [concrete]
 // CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.e8f, @Destroy [symbolic]
 // CHECK:STDOUT:   %Destroy.facet.617: %Destroy.type = facet_value %ptr.e8f, (%Destroy.lookup_impl_witness) [symbolic]
@@ -374,6 +372,7 @@ fn G() { F(B); }
 // CHECK:STDOUT:   %ptr.27c: type = ptr_type %B [concrete]
 // CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %ptr.27c [concrete]
 // CHECK:STDOUT:   %pattern_type.191: type = pattern_type %ptr.27c [concrete]
+// CHECK:STDOUT:   %pattern_type.1f4: type = pattern_type %B [concrete]
 // CHECK:STDOUT:   %Destroy.Op.type: type = fn_type @Destroy.Op [concrete]
 // CHECK:STDOUT:   %Destroy.Op: %Destroy.Op.type = struct_value () [concrete]
 // CHECK:STDOUT:   %custom_witness.8d7: <witness> = custom_witness (%Destroy.Op), @Destroy [concrete]
@@ -420,8 +419,9 @@ fn G() { F(B); }
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %ptr.loc7_11.2: type = ptr_type %T.loc6_6.1 [symbolic = %ptr.loc7_11.2 (constants.%ptr.e8f)]
 // CHECK:STDOUT:   %require_complete.loc7: <witness> = require_complete_type %ptr.loc7_11.2 [symbolic = %require_complete.loc7 (constants.%require_complete.ef1)]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %ptr.loc7_11.2 [symbolic = %pattern_type (constants.%pattern_type.4f4)]
+// CHECK:STDOUT:   %pattern_type.loc7: type = pattern_type %ptr.loc7_11.2 [symbolic = %pattern_type.loc7 (constants.%pattern_type.4f4)]
 // CHECK:STDOUT:   %require_complete.loc8: <witness> = require_complete_type %T.loc6_6.1 [symbolic = %require_complete.loc8 (constants.%require_complete.944)]
+// CHECK:STDOUT:   %pattern_type.loc8: type = pattern_type %T.loc6_6.1 [symbolic = %pattern_type.loc8 (constants.%pattern_type.51d)]
 // CHECK:STDOUT:   %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc7_11.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
 // CHECK:STDOUT:   %Destroy.facet: %Destroy.type = facet_value %ptr.loc7_11.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.617)]
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op, @Destroy.WithSelf(%Destroy.facet) [symbolic = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.bb2)]
@@ -432,23 +432,29 @@ fn G() { F(B); }
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     name_binding_decl {
-// CHECK:STDOUT:       %v.patt: @F.%pattern_type (%pattern_type.4f4) = ref_binding_pattern v [concrete]
-// CHECK:STDOUT:       %v.var_patt: @F.%pattern_type (%pattern_type.4f4) = var_pattern %v.patt [concrete]
+// CHECK:STDOUT:       %p.patt: @F.%pattern_type.loc7 (%pattern_type.4f4) = ref_binding_pattern p [concrete]
+// CHECK:STDOUT:       %p.var_patt: @F.%pattern_type.loc7 (%pattern_type.4f4) = var_pattern %p.patt [concrete]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %v.var: ref @F.%ptr.loc7_11.2 (%ptr.e8f) = var %v.var_patt
+// CHECK:STDOUT:     %p.var: ref @F.%ptr.loc7_11.2 (%ptr.e8f) = var %p.var_patt
 // CHECK:STDOUT:     %.loc7_11: type = splice_block %ptr.loc7_11.1 [symbolic = %ptr.loc7_11.2 (constants.%ptr.e8f)] {
-// CHECK:STDOUT:       %T.ref: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
-// CHECK:STDOUT:       %ptr.loc7_11.1: type = ptr_type %T.ref [symbolic = %ptr.loc7_11.2 (constants.%ptr.e8f)]
+// CHECK:STDOUT:       %T.ref.loc7: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
+// CHECK:STDOUT:       %ptr.loc7_11.1: type = ptr_type %T.ref.loc7 [symbolic = %ptr.loc7_11.2 (constants.%ptr.e8f)]
 // CHECK:STDOUT:     }
-// CHECK:STDOUT:     %v: ref @F.%ptr.loc7_11.2 (%ptr.e8f) = ref_binding v, %v.var
-// CHECK:STDOUT:     %v.ref: ref @F.%ptr.loc7_11.2 (%ptr.e8f) = name_ref v, %v
-// CHECK:STDOUT:     %.loc8_4: @F.%ptr.loc7_11.2 (%ptr.e8f) = acquire_value %v.ref
-// CHECK:STDOUT:     %.loc8_3: ref @F.%T.loc6_6.1 (%T) = deref %.loc8_4
+// CHECK:STDOUT:     %p: ref @F.%ptr.loc7_11.2 (%ptr.e8f) = ref_binding p, %p.var
+// CHECK:STDOUT:     name_binding_decl {
+// CHECK:STDOUT:       %_.patt: @F.%pattern_type.loc8 (%pattern_type.51d) = value_binding_pattern _ [concrete]
+// CHECK:STDOUT:     }
+// CHECK:STDOUT:     %p.ref: ref @F.%ptr.loc7_11.2 (%ptr.e8f) = name_ref p, %p
+// CHECK:STDOUT:     %.loc8_15: @F.%ptr.loc7_11.2 (%ptr.e8f) = acquire_value %p.ref
+// CHECK:STDOUT:     %.loc8_14.1: ref @F.%T.loc6_6.1 (%T) = deref %.loc8_15
+// CHECK:STDOUT:     %T.ref.loc8: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
+// CHECK:STDOUT:     %.loc8_14.2: @F.%T.loc6_6.1 (%T) = acquire_value %.loc8_14.1
+// CHECK:STDOUT:     %_: @F.%T.loc6_6.1 (%T) = value_binding _, %.loc8_14.2
 // CHECK:STDOUT:     %impl.elem0.loc7_3.1: @F.%.loc7_3 (%.c3f) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
-// CHECK:STDOUT:     %bound_method.loc7_3.1: <bound method> = bound_method %v.var, %impl.elem0.loc7_3.1
+// CHECK:STDOUT:     %bound_method.loc7_3.1: <bound method> = bound_method %p.var, %impl.elem0.loc7_3.1
 // CHECK:STDOUT:     %specific_impl_fn.loc7_3.1: <specific function> = specific_impl_function %impl.elem0.loc7_3.1, @Destroy.WithSelf.Op(constants.%Destroy.facet.617) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn)]
-// CHECK:STDOUT:     %bound_method.loc7_3.2: <bound method> = bound_method %v.var, %specific_impl_fn.loc7_3.1
-// CHECK:STDOUT:     %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %bound_method.loc7_3.2(%v.var)
+// CHECK:STDOUT:     %bound_method.loc7_3.2: <bound method> = bound_method %p.var, %specific_impl_fn.loc7_3.1
+// CHECK:STDOUT:     %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %bound_method.loc7_3.2(%p.var)
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
@@ -474,8 +480,9 @@ fn G() { F(B); }
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %ptr.loc7_11.2 => constants.%ptr.27c
 // CHECK:STDOUT:   %require_complete.loc7 => constants.%complete_type
-// CHECK:STDOUT:   %pattern_type => constants.%pattern_type.191
+// CHECK:STDOUT:   %pattern_type.loc7 => constants.%pattern_type.191
 // CHECK:STDOUT:   %require_complete.loc8 => <error>
+// CHECK:STDOUT:   %pattern_type.loc8 => constants.%pattern_type.1f4
 // CHECK:STDOUT:   %Destroy.lookup_impl_witness => constants.%custom_witness.8d7
 // CHECK:STDOUT:   %Destroy.facet => constants.%Destroy.facet.d35
 // CHECK:STDOUT:   %Destroy.WithSelf.Op.type => constants.%Destroy.WithSelf.Op.type.540

+ 3 - 5
toolchain/check/testdata/impl/lookup/impl_forall.carbon

@@ -65,7 +65,7 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:   %A.as.I.impl.F.type.58747b.1: type = fn_type @A.as.I.impl.F, @A.as.I.impl(%V.67d) [symbolic]
 // CHECK:STDOUT:   %A.as.I.impl.F.afeb91.1: %A.as.I.impl.F.type.58747b.1 = struct_value () [symbolic]
 // CHECK:STDOUT:   %A.elem.8a20fa.2: type = unbound_element_type %A.95c0c7.2, %V.67d [symbolic]
-// CHECK:STDOUT:   %require_complete.fd656a.1: <witness> = require_complete_type %A.95c0c7.2 [symbolic]
+// CHECK:STDOUT:   %require_complete.fd6: <witness> = require_complete_type %A.95c0c7.2 [symbolic]
 // CHECK:STDOUT:   %require_complete.ef162c.1: <witness> = require_complete_type %ptr.e8f8f9.2 [symbolic]
 // CHECK:STDOUT:   %Copy.type: type = facet_type <@Copy> [concrete]
 // CHECK:STDOUT:   %ptr.as.Copy.impl.Op.type.2d4455.1: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.67d) [symbolic]
@@ -98,7 +98,6 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:   %.695: type = fn_type_with_self_type %I.WithSelf.F.type.912, %I.facet.558 [symbolic]
 // CHECK:STDOUT:   %impl.elem0.976: %.695 = impl_witness_access %I.lookup_impl_witness, element0 [symbolic]
 // CHECK:STDOUT:   %specific_impl_fn.3c2: <specific function> = specific_impl_function %impl.elem0.976, @I.WithSelf.F(%W, %I.facet.558) [symbolic]
-// CHECK:STDOUT:   %require_complete.fd656a.2: <witness> = require_complete_type %A.95c0c7.3 [symbolic]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %empty_struct: %empty_struct_type = struct_value () [concrete]
 // CHECK:STDOUT:   %A.ed7: type = class_type @A, @A(%empty_struct_type) [concrete]
@@ -201,7 +200,7 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:   %pattern_type.loc13_26: type = pattern_type %ptr.loc13_30.1 [symbolic = %pattern_type.loc13_26 (constants.%pattern_type.4f4b84.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
-// CHECK:STDOUT:   %require_complete.loc13_16: <witness> = require_complete_type %A [symbolic = %require_complete.loc13_16 (constants.%require_complete.fd656a.1)]
+// CHECK:STDOUT:   %require_complete.loc13_16: <witness> = require_complete_type %A [symbolic = %require_complete.loc13_16 (constants.%require_complete.fd6)]
 // CHECK:STDOUT:   %require_complete.loc13_30: <witness> = require_complete_type %ptr.loc13_30.1 [symbolic = %require_complete.loc13_30 (constants.%require_complete.ef162c.1)]
 // CHECK:STDOUT:   %A.elem: type = unbound_element_type %A, %V [symbolic = %A.elem (constants.%A.elem.8a20fa.2)]
 // CHECK:STDOUT:   %.loc14_12.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%V) [symbolic = %.loc14_12.1 (constants.%.2f2)]
@@ -233,7 +232,7 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   <elided>
 // CHECK:STDOUT:   %I.type.loc21_17.2: type = facet_type <@I, @I(%W.loc19_16.1)> [symbolic = %I.type.loc21_17.2 (constants.%I.type.1ab3e4.3)]
-// CHECK:STDOUT:   %require_complete.loc21_18: <witness> = require_complete_type %I.type.loc21_17.2 [symbolic = %require_complete.loc21_18 (constants.%require_complete.e360af.2)]
+// CHECK:STDOUT:   %require_complete.loc21: <witness> = require_complete_type %I.type.loc21_17.2 [symbolic = %require_complete.loc21 (constants.%require_complete.e360af.2)]
 // CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I, @I(%W.loc19_16.1) [symbolic = %I.assoc_type (constants.%I.assoc_type.76c031.3)]
 // CHECK:STDOUT:   %assoc0: @TestGeneric.%I.assoc_type (%I.assoc_type.76c031.3) = assoc_entity element0, @I.WithSelf.%I.WithSelf.F.decl [symbolic = %assoc0 (constants.%assoc0.203667.3)]
 // CHECK:STDOUT:   %.loc21_11.2: require_specific_def_type = require_specific_def @A.as.I.impl(%W.loc19_16.1) [symbolic = %.loc21_11.2 (constants.%.0fe)]
@@ -243,7 +242,6 @@ fn TestSpecific(a: A({})*) -> {}* {
 // CHECK:STDOUT:   %.loc21_11.3: type = fn_type_with_self_type %I.WithSelf.F.type, %I.facet [symbolic = %.loc21_11.3 (constants.%.695)]
 // CHECK:STDOUT:   %impl.elem0.loc21_11.2: @TestGeneric.%.loc21_11.3 (%.695) = impl_witness_access %I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.976)]
 // CHECK:STDOUT:   %specific_impl_fn.loc21_11.2: <specific function> = specific_impl_function %impl.elem0.loc21_11.2, @I.WithSelf.F(%W.loc19_16.1, %I.facet) [symbolic = %specific_impl_fn.loc21_11.2 (constants.%specific_impl_fn.3c2)]
-// CHECK:STDOUT:   %require_complete.loc21_11: <witness> = require_complete_type %A.loc19_32.1 [symbolic = %require_complete.loc21_11 (constants.%require_complete.fd656a.2)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%a.param: @TestGeneric.%ptr.loc19_33.1 (%ptr.5da)) -> out %return.param: @TestGeneric.%ptr.loc19_40.1 (%ptr.e8f8f9.4) {
 // CHECK:STDOUT:   !entry:

+ 4 - 8
toolchain/check/testdata/interface/assoc_const_in_generic.carbon

@@ -48,8 +48,7 @@ fn H() {
 // CHECK:STDOUT:   %assoc0.203: %I.assoc_type.76c = assoc_entity element0, @I.WithSelf.%I.WithSelf.F.decl [symbolic]
 // CHECK:STDOUT:   %G.type: type = fn_type @G [concrete]
 // CHECK:STDOUT:   %G: %G.type = struct_value () [concrete]
-// CHECK:STDOUT:   %require_complete.e36: <witness> = require_complete_type %I.type.1ab [symbolic]
-// CHECK:STDOUT:   %require_complete.ac0: <witness> = require_complete_type %I.assoc_type.76c [symbolic]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I.type.1ab [symbolic]
 // CHECK:STDOUT:   %H.type: type = fn_type @H [concrete]
 // CHECK:STDOUT:   %H: %H.type = struct_value () [concrete]
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
@@ -61,8 +60,7 @@ fn H() {
 // CHECK:STDOUT:   %I.WithSelf.F.02c: %I.WithSelf.F.type.3f5 = struct_value () [symbolic]
 // CHECK:STDOUT:   %I.assoc_type.294: type = assoc_entity_type @I, @I(%empty_struct_type) [concrete]
 // CHECK:STDOUT:   %assoc0.c64: %I.assoc_type.294 = assoc_entity element0, @I.WithSelf.%I.WithSelf.F.decl [concrete]
-// CHECK:STDOUT:   %complete_type.5b1: <witness> = complete_type_witness %I.type.ab5 [concrete]
-// CHECK:STDOUT:   %complete_type.7fc: <witness> = complete_type_witness %I.assoc_type.294 [concrete]
+// CHECK:STDOUT:   %complete_type: <witness> = complete_type_witness %I.type.ab5 [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -143,10 +141,9 @@ fn H() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %I.type.loc23_6.2: type = facet_type <@I, @I(%T.loc19_6.1)> [symbolic = %I.type.loc23_6.2 (constants.%I.type.1ab)]
-// CHECK:STDOUT:   %require_complete.loc23_7.1: <witness> = require_complete_type %I.type.loc23_6.2 [symbolic = %require_complete.loc23_7.1 (constants.%require_complete.e36)]
+// CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %I.type.loc23_6.2 [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:   %I.assoc_type: type = assoc_entity_type @I, @I(%T.loc19_6.1) [symbolic = %I.assoc_type (constants.%I.assoc_type.76c)]
 // CHECK:STDOUT:   %assoc0: @G.%I.assoc_type (%I.assoc_type.76c) = assoc_entity element0, @I.WithSelf.%I.WithSelf.F.decl [symbolic = %assoc0 (constants.%assoc0.203)]
-// CHECK:STDOUT:   %require_complete.loc23_7.2: <witness> = require_complete_type %I.assoc_type [symbolic = %require_complete.loc23_7.2 (constants.%require_complete.ac0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
@@ -203,10 +200,9 @@ fn H() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %I.type.loc23_6.2 => constants.%I.type.ab5
-// CHECK:STDOUT:   %require_complete.loc23_7.1 => constants.%complete_type.5b1
+// CHECK:STDOUT:   %require_complete => constants.%complete_type
 // CHECK:STDOUT:   %I.assoc_type => constants.%I.assoc_type.294
 // CHECK:STDOUT:   %assoc0 => constants.%assoc0.c64
-// CHECK:STDOUT:   %require_complete.loc23_7.2 => constants.%complete_type.7fc
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @I(constants.%empty_struct_type) {

+ 5 - 11
toolchain/check/testdata/interface/incomplete.carbon

@@ -39,7 +39,7 @@ interface I {
 // CHECK:STDERR:
 impl {} as I where .T = ({} as C) {}
 
-// --- fail_incomplete_type_usage.carbon
+// --- incomplete_type_usage.carbon
 library "[[@TEST_NAME]]";
 
 class C;
@@ -49,13 +49,7 @@ interface I {
 }
 
 fn F[U:! I](a: U) {
-  // CHECK:STDERR: fail_incomplete_type_usage.carbon:[[@LINE+7]]:3: error: invalid use of incomplete type `C` [IncompleteTypeInConversion]
-  // CHECK:STDERR:   a.T;
-  // CHECK:STDERR:   ^~~
-  // CHECK:STDERR: fail_incomplete_type_usage.carbon:[[@LINE-10]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
-  // CHECK:STDERR: class C;
-  // CHECK:STDERR: ^~~~~~~~
-  // CHECK:STDERR:
+  // TODO: Should this be diagnosed as having an incomplete type?
   a.T;
 }
 
@@ -221,7 +215,7 @@ interface A(T:! type) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: --- fail_incomplete_type_usage.carbon
+// CHECK:STDOUT: --- incomplete_type_usage.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %C: type = class_type @C [concrete]
@@ -299,13 +293,13 @@ interface A(T:! type) {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT:   %require_complete: <witness> = require_complete_type %U.binding.as_type [symbolic = %require_complete (constants.%require_complete)]
 // CHECK:STDOUT:   %I.lookup_impl_witness: <witness> = lookup_impl_witness %U.loc9_6.1, @I [symbolic = %I.lookup_impl_witness (constants.%I.lookup_impl_witness)]
-// CHECK:STDOUT:   %impl.elem0.loc17_4.2: %C = impl_witness_access %I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc17_4.2 (constants.%impl.elem0)]
+// CHECK:STDOUT:   %impl.elem0.loc11_4.2: %C = impl_witness_access %I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_4.2 (constants.%impl.elem0)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn(%a.param: @F.%U.binding.as_type (%U.binding.as_type)) {
 // CHECK:STDOUT:   !entry:
 // CHECK:STDOUT:     %a.ref: @F.%U.binding.as_type (%U.binding.as_type) = name_ref a, %a
 // CHECK:STDOUT:     %T.ref: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0]
-// CHECK:STDOUT:     %impl.elem0.loc17_4.1: %C = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc17_4.2 (constants.%impl.elem0)]
+// CHECK:STDOUT:     %impl.elem0.loc11_4.1: %C = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_4.2 (constants.%impl.elem0)]
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }

+ 4 - 0
toolchain/check/type_completion.h

@@ -36,6 +36,10 @@ auto CompleteTypeOrCheckFail(Context& context, SemIR::TypeId type_id) -> void;
 // `diagnoser` should build an error diagnostic. If `type_id` is dependent,
 // the completeness of the type will be enforced during monomorphization, and
 // `loc_id` is used as the location for a diagnostic produced at that time.
+//
+// Note that in general, the code that creates an inst is responsible for
+// enforcing any type completeness requirements associated with that inst; it
+// should not rely on its downstream consumers to do so.
 auto RequireCompleteType(Context& context, SemIR::TypeId type_id,
                          SemIR::LocId loc_id,
                          DiagnosticContextFn diagnostic_context) -> bool;