From b9bd7e1eff59e7f90a052d75fffcb123eaddb365 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 1 May 2023 11:30:19 -0700 Subject: [PATCH] Turn `addr self` in destructors into an error. (#2803) Previously crashed. See #2802 --- explorer/interpreter/interpreter.cpp | 12 +++++++--- explorer/testdata/destructor/fail_addr.carbon | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 explorer/testdata/destructor/fail_addr.carbon diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index 78ead1789c8c..32f6a8fe7166 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -944,9 +944,15 @@ auto Interpreter::CallDestructor(Nonnull fun, // TODO: move this logic into PatternMatch, and call it here. const auto* p = &method.self_pattern().value(); - const auto& placeholder = cast(*p); - if (placeholder.value_node().has_value()) { - method_scope.Bind(*placeholder.value_node(), receiver); + const auto* placeholder = dyn_cast(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"; diff --git a/explorer/testdata/destructor/fail_addr.carbon b/explorer/testdata/destructor/fail_addr.carbon new file mode 100644 index 000000000000..54a602a39305 --- /dev/null +++ b/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; +}