Jelajahi Sumber

Error evaluating symbolic tuple (#2957)

Reports an error (`value of generic binding T is not known`) instead of
performing an invalid cast when attempting to index into a tuple. Can
occur when trying to cast a generic constant in the interface position
of an implementation to `type`.

Closes #2938
josh11b 2 tahun lalu
induk
melakukan
798233fe23

+ 6 - 1
explorer/interpreter/interpreter.cpp

@@ -1316,7 +1316,12 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
       } else {
         //    { { v :: [][i] :: C, E, F} :: S, H}
         // -> { { v_i :: C, E, F} : S, H}
-        const auto& tuple = cast<TupleValue>(*act.results()[0]);
+        CARBON_ASSIGN_OR_RETURN(
+            auto converted,
+            Convert(act.results()[0],
+                    &cast<IndexExpression>(exp).object().static_type(),
+                    exp.source_loc()));
+        const auto& tuple = cast<TupleValue>(*converted);
         int i = cast<IntValue>(*act.results()[1]).value();
         if (i < 0 || i >= static_cast<int>(tuple.elements().size())) {
           return ProgramError(exp.source_loc())

+ 14 - 0
explorer/testdata/impl/fail_impl_as_symbolic.carbon

@@ -0,0 +1,14 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+
+package ExplorerTest api;
+
+// CHECK:STDERR: COMPILATION ERROR: fail_impl_as_symbolic.carbon:[[@LINE+1]]: value of generic binding T is not known
+impl forall [T:! ({}, )] {} as T {
+}
+
+fn Main() -> i32 {
+}

+ 15 - 0
explorer/testdata/impl/fail_impl_symbolic_as.carbon

@@ -0,0 +1,15 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+
+package ExplorerTest api;
+
+interface X {
+}
+// CHECK:STDERR: COMPILATION ERROR: fail_impl_symbolic_as.carbon:[[@LINE+1]]: value of generic binding Y is not known
+impl forall [Y:! (X, )] Y as true {
+}
+fn Main() -> i32 {
+}