ソースを参照

Turn `addr self` in destructors into an error. (#2803)

Previously crashed. See #2802
Jon Ross-Perkins 3 年 前
コミット
b9bd7e1eff

+ 9 - 3
explorer/interpreter/interpreter.cpp

@@ -944,9 +944,15 @@ auto Interpreter::CallDestructor(Nonnull<const DestructorDeclaration*> fun,
 
   // TODO: move this logic into PatternMatch, and call it here.
   const auto* p = &method.self_pattern().value();
-  const auto& placeholder = cast<BindingPlaceholderValue>(*p);
-  if (placeholder.value_node().has_value()) {
-    method_scope.Bind(*placeholder.value_node(), receiver);
+  const auto* placeholder = dyn_cast<BindingPlaceholderValue>(p);
+  if (!placeholder) {
+    // TODO: Fix this, probably merging logic with CallFunction.
+    // https://github.com/carbon-language/carbon-lang/issues/2802
+    return ProgramError(fun->source_loc())
+           << "destructors currently don't support `addr self` bindings";
+  }
+  if (placeholder->value_node().has_value()) {
+    method_scope.Bind(*placeholder->value_node(), receiver);
   }
   CARBON_CHECK(method.body().has_value())
       << "Calling a method that's missing a body";

+ 24 - 0
explorer/testdata/destructor/fail_addr.carbon

@@ -0,0 +1,24 @@
+// 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
+// RUN: %{not} %{explorer-run}
+// RUN: %{not} %{explorer-run-trace}
+
+package ExplorerTest impl;
+
+class A {
+  destructor[addr self: Self*] {
+    self->n += 1;
+    Print("DESTRUCTOR A {0}", self->n);
+  // CHECK:STDERR: RUNTIME ERROR: {{.*}}/explorer/testdata/destructor/fail_addr.carbon:[[@LINE+1]]: destructors currently don't support `addr self` bindings
+  }
+
+  var n: i32;
+}
+
+fn Main() -> i32 {
+  var a: A = {.n = 2};
+  return 0;
+}