Просмотр исходного кода

Convert returned associated constants. (#3029)

Associated constants were getting returned directly, crashing because
the value InterpProgram received was an AssociatedConstant instead of an
IntValue. We have a similar Convert call in ReturnVar, so I _think_ this
is the right approach.
Jon Ross-Perkins 2 лет назад
Родитель
Сommit
bbf896e165

+ 7 - 3
explorer/interpreter/interpreter.cpp

@@ -2526,12 +2526,16 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
         //    { {v :: return [] :: C, E, F} :: {C', E', F'} :: S, H}
         // -> { {v :: C', E', F'} :: S, H}
         const CallableDeclaration& function = cast<Return>(stmt).function();
+        CARBON_ASSIGN_OR_RETURN(
+            Nonnull<const Value*> return_value,
+            Convert(act.results()[0], &function.return_term().static_type(),
+                    stmt.source_loc()));
         // Write to initialized storage location, if any.
         if (const auto location = act.location_received()) {
-          CARBON_RETURN_IF_ERROR(heap_.Write(
-              Address(*location), act.results()[0], stmt.source_loc()));
+          CARBON_RETURN_IF_ERROR(
+              heap_.Write(Address(*location), return_value, stmt.source_loc()));
         }
-        return todo_.UnwindPast(*function.body(), act.results()[0]);
+        return todo_.UnwindPast(*function.body(), return_value);
       }
   }
 }

+ 27 - 0
explorer/testdata/return/convert_return_assoc.carbon

@@ -0,0 +1,27 @@
+// 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
+// CHECK:STDOUT: result: 1
+
+package ExplorerTest api;
+
+interface I {
+  let Assoc:! i32;
+}
+
+class C {
+  impl Self as I where .Assoc = 1 {}
+}
+
+alias A = I where .Assoc == 1;
+
+fn F[T:! A](x: T) -> i32 {
+  return x.(A.Assoc);
+}
+
+fn Main() -> i32 {
+  var a: C = {};
+  return F(a);
+}