Quellcode durchsuchen

Tolerate incomplete interface when stringifying ImplWitnessAccess (#5730)

Closes #5727
Geoff Romer vor 10 Monaten
Ursprung
Commit
1893afe479

+ 23 - 0
toolchain/check/testdata/interface/fail_type_as_facet.carbon

@@ -0,0 +1,23 @@
+// 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/convert.carbon
+//
+// AUTOUPDATE
+// TIP: To test this file alone, run:
+// TIP:   bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/fail_type_as_facet.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/fail_type_as_facet.carbon
+
+interface I {
+  let T:! type;
+  // CHECK:STDERR: fail_type_as_facet.carbon:[[@LINE+7]]:18: error: cannot implicitly convert non-type value of type `Self.(TODO: element 0 in incomplete Self as I)` to `type` [ConversionFailureNonTypeToFacet]
+  // CHECK:STDERR:   fn F[X:! T](x: X);
+  // CHECK:STDERR:                  ^
+  // CHECK:STDERR: fail_type_as_facet.carbon:[[@LINE+4]]:18: note: type `Self.(TODO: element 0 in incomplete Self as I)` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
+  // CHECK:STDERR:   fn F[X:! T](x: X);
+  // CHECK:STDERR:                  ^
+  // CHECK:STDERR:
+  fn F[X:! T](x: X);
+}

+ 10 - 8
toolchain/sem_ir/stringify.cpp

@@ -420,10 +420,15 @@ class Stringifier {
   auto StringifyInst(InstId /*inst_id*/, ImplWitnessAccess inst) -> void {
     auto witness_inst_id =
         sem_ir_->constant_values().GetConstantInstId(inst.witness_id);
-    if (auto specific_interface =
-            TryGetSpecificInterfaceForImplWitness(witness_inst_id)) {
-      const auto& interface =
-          sem_ir_->interfaces().Get(specific_interface->interface_id);
+    auto lookup = sem_ir_->insts().GetAs<LookupImplWitness>(witness_inst_id);
+    auto specific_interface =
+        sem_ir_->specific_interfaces().Get(lookup.query_specific_interface_id);
+    const auto& interface =
+        sem_ir_->interfaces().Get(specific_interface.interface_id);
+    if (!interface.associated_entities_id.has_value()) {
+      step_stack_->Push(".(TODO: element ", inst.index, " in incomplete ",
+                        witness_inst_id, ")");
+    } else {
       auto entities =
           sem_ir_->inst_blocks().Get(interface.associated_entities_id);
       size_t index = inst.index.index;
@@ -446,11 +451,8 @@ class Stringifier {
       }
       step_stack_->Push(
           ".(",
-          StepStack::EntityNameItem{interface, specific_interface->specific_id},
+          StepStack::EntityNameItem{interface, specific_interface.specific_id},
           ".");
-    } else {
-      step_stack_->Push(".(TODO: element ", inst.index, " in ", witness_inst_id,
-                        ")");
     }
 
     if (auto lookup =