From b0da9c0c6a11ffaf30499e130f3f4f3165a9f759 Mon Sep 17 00:00:00 2001 From: Christopher Di Bella Date: Fri, 25 Sep 2026 20:21:52 +0000 Subject: [PATCH] Add `BuildSelfDestructCall` (#7824) The toolchain builds `.(Destroy.SelfDestruct)()` in a few different places. This function keeps things consistent across call sites. --- toolchain/check/control_flow.cpp | 7 ++----- toolchain/check/operator.cpp | 9 +++++++++ toolchain/check/operator.h | 5 +++++ toolchain/check/thunk.cpp | 6 +----- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/toolchain/check/control_flow.cpp b/toolchain/check/control_flow.cpp index 2bc4e463e41c..51fca32d08a7 100644 --- a/toolchain/check/control_flow.cpp +++ b/toolchain/check/control_flow.cpp @@ -155,11 +155,8 @@ static auto AddCleanups(Context& context, ScopeStack::CleanupScopeDepth depth) // TODO: This does the `Destroy` lookup and call at every cleanup block. // Control flow can lead to the same variable being destroyed by multiple // cleanup blocks, so we'll want to avoid this in the future. - BuildUnaryOperator(context, - context.insts().GetLocIdForDesugaring(destroy_id), - {.interface_name = CoreIdentifier::Destroy, - .op_name = CoreIdentifier::SelfDestruct}, - destroy_id); + BuildSelfDestructCall( + context, context.insts().GetLocIdForDesugaring(destroy_id), destroy_id); } } diff --git a/toolchain/check/operator.cpp b/toolchain/check/operator.cpp index 0c2c65e5f4fc..5029d8132690 100644 --- a/toolchain/check/operator.cpp +++ b/toolchain/check/operator.cpp @@ -8,6 +8,7 @@ #include "toolchain/check/call.h" #include "toolchain/check/context.h" +#include "toolchain/check/convert.h" #include "toolchain/check/cpp/call.h" #include "toolchain/check/cpp/operators.h" #include "toolchain/check/generic.h" @@ -102,6 +103,14 @@ auto BuildUnaryOperator(Context& context, SemIR::LocId loc_id, Operator op, /*is_desugared=*/true); } +auto BuildSelfDestructCall(Context& context, SemIR::LocId loc_id, + SemIR::InstId object_id) -> SemIR::InstId { + return BuildUnaryOperator(context, loc_id, + {.interface_name = CoreIdentifier::Destroy, + .op_name = CoreIdentifier::SelfDestruct}, + object_id); +} + auto BuildBinaryOperator(Context& context, SemIR::LocId loc_id, Operator op, SemIR::InstId lhs_id, SemIR::InstId rhs_id, bool diagnose, diff --git a/toolchain/check/operator.h b/toolchain/check/operator.h index 4e6cc724401c..1c2d64e7e697 100644 --- a/toolchain/check/operator.h +++ b/toolchain/check/operator.h @@ -47,6 +47,11 @@ auto BuildBinaryOperator( DiagnosticContextFn missing_impl_diagnostic_context = nullptr) -> SemIR::InstId; +// Builds `.(Destroy.SelfDestruct)()`, converting adapters to their +// underlying types in the process. +auto BuildSelfDestructCall(Context& context, SemIR::LocId loc_id, + SemIR::InstId object_id) -> SemIR::InstId; + } // namespace Carbon::Check #endif // CARBON_TOOLCHAIN_CHECK_OPERATOR_H_ diff --git a/toolchain/check/thunk.cpp b/toolchain/check/thunk.cpp index 2fb618884b0b..8040561d2d92 100644 --- a/toolchain/check/thunk.cpp +++ b/toolchain/check/thunk.cpp @@ -554,11 +554,7 @@ auto BuildDestroyThunk(Context& context, SemIR::LocId loc_id, auto self_inst_id = params[0]; // Build the function body. This calls the `Destroy` operator on `self`. - auto destroy_inst_id = - BuildUnaryOperator(context, loc_id, - {.interface_name = CoreIdentifier::Destroy, - .op_name = CoreIdentifier::SelfDestruct}, - self_inst_id); + auto destroy_inst_id = BuildSelfDestructCall(context, loc_id, self_inst_id); DiscardExpr(context, destroy_inst_id); BuildReturnWithNoExpr(context, loc_id);