diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index ec2957eb1e26..94d79b1e4a8b 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -93,8 +93,6 @@ class Interpreter { // State transition for object destruction. auto StepCleanUp() -> ErrorOr; auto StepDestroy() -> ErrorOr; - // State transition for tuple destruction. - auto StepCleanUpTuple() -> ErrorOr; auto CreateStruct(const std::vector& fields, const std::vector>& values) @@ -2204,17 +2202,19 @@ auto Interpreter::StepDestroy() -> ErrorOr { } auto Interpreter::StepCleanUp() -> ErrorOr { - Action& act = todo_.CurrentAction(); - CleanUpAction& cleanup = cast(act); + const Action& act = todo_.CurrentAction(); + const auto& cleanup = cast(act); if (act.pos() < cleanup.allocations_count()) { auto allocation = act.scope()->allocations()[cleanup.allocations_count() - act.pos() - 1]; - auto lvalue = arena_->New(Address(allocation)); + const auto* lvalue = arena_->New(Address(allocation)); SourceLocation source_loc("destructor", 1); auto value = heap_.Read(lvalue->address(), source_loc); // Step over uninitialized values if (value.ok()) { return todo_.Spawn(std::make_unique(lvalue, *value)); + } else { + return todo_.RunAgain(); } } todo_.Pop(); diff --git a/explorer/testdata/unformed/destroy_formed_only.carbon b/explorer/testdata/unformed/destroy_formed_only.carbon new file mode 100644 index 000000000000..707a8fe576ba --- /dev/null +++ b/explorer/testdata/unformed/destroy_formed_only.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 +// RUN: %{explorer-run} +// RUN: %{explorer-run-trace} +// CHECK:STDOUT: Destructor A 3 +// CHECK:STDOUT: Destructor A 1 +// CHECK:STDOUT: result: 0 + +package ExplorerTest api; + +class A { + var i: i32; + destructor[self: Self] { + Print("Destructor A {0}", self.i); + } +} + +fn Main() -> i32 { + var a0: A; + var a1: A = {.i = 1}; + var a2: A; + var a3: A = {.i = 3}; + return 0; +}