From 69b9982e95bfa3a769ba741717a6ef02ce11d7ff Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 9 May 2025 09:35:28 -0700 Subject: [PATCH] Convert discarded calls in thunks. (#5452) No functionality change right now: we reject thunks where the signature has no return type and the callee has a return type. But discarding the expression is still the right thing to do. --- toolchain/check/convert.cpp | 10 ++++++++++ toolchain/check/convert.h | 3 +++ toolchain/check/handle_expr_statement.cpp | 15 +-------------- toolchain/check/thunk.cpp | 2 ++ 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 6cdac75bb560..4ce13e5e95b5 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -1511,6 +1511,16 @@ auto ExprAsType(Context& context, SemIR::LocId loc_id, SemIR::InstId value_id, .type_id = context.types().GetTypeIdForTypeConstantId(type_const_id)}; } +auto DiscardExpr(Context& context, SemIR::InstId expr_id) -> void { + // If we discard an initializing expression, convert it to a value or + // reference so that it has something to initialize. + auto expr = context.insts().Get(expr_id); + Convert(context, SemIR::LocId(expr_id), expr_id, + {.kind = ConversionTarget::Discarded, .type_id = expr.type_id()}); + + // TODO: This will eventually need to do some "do not discard" analysis. +} + } // namespace Carbon::Check // NOLINTEND(misc-no-recursion) diff --git a/toolchain/check/convert.h b/toolchain/check/convert.h index ac32105c2fc9..e1d6e37f30be 100644 --- a/toolchain/check/convert.h +++ b/toolchain/check/convert.h @@ -136,6 +136,9 @@ struct TypeExpr { auto ExprAsType(Context& context, SemIR::LocId loc_id, SemIR::InstId value_id, bool diagnose = true) -> TypeExpr; +// Handles an expression whose result value is unused. +auto DiscardExpr(Context& context, SemIR::InstId expr_id) -> void; + } // namespace Carbon::Check #endif // CARBON_TOOLCHAIN_CHECK_CONVERT_H_ diff --git a/toolchain/check/handle_expr_statement.cpp b/toolchain/check/handle_expr_statement.cpp index 96ea6060db5b..a3f9c6f0c226 100644 --- a/toolchain/check/handle_expr_statement.cpp +++ b/toolchain/check/handle_expr_statement.cpp @@ -9,22 +9,9 @@ namespace Carbon::Check { -// TODO: Find a better home for this. We'll likely need it for more than just -// expression statements. -static auto HandleDiscardedExpr(Context& context, SemIR::InstId expr_id) - -> void { - // If we discard an initializing expression, convert it to a value or - // reference so that it has something to initialize. - auto expr = context.insts().Get(expr_id); - Convert(context, SemIR::LocId(expr_id), expr_id, - {.kind = ConversionTarget::Discarded, .type_id = expr.type_id()}); - - // TODO: This will eventually need to do some "do not discard" analysis. -} - auto HandleParseNode(Context& context, Parse::ExprStatementId /*node_id*/) -> bool { - HandleDiscardedExpr(context, context.node_stack().PopExpr()); + DiscardExpr(context, context.node_stack().PopExpr()); return true; } diff --git a/toolchain/check/thunk.cpp b/toolchain/check/thunk.cpp index 7c7bf445a682..68444d254048 100644 --- a/toolchain/check/thunk.cpp +++ b/toolchain/check/thunk.cpp @@ -6,6 +6,7 @@ #include "toolchain/base/kind_switch.h" #include "toolchain/check/call.h" +#include "toolchain/check/convert.h" #include "toolchain/check/deferred_definition_scope.h" #include "toolchain/check/diagnostic_helpers.h" #include "toolchain/check/function.h" @@ -400,6 +401,7 @@ static auto BuildThunkDefinition(Context& context, if (HasDeclaredReturnType(context, function_id)) { BuildReturnWithExpr(context, SemIR::LocId(callee_id), call_id); } else { + DiscardExpr(context, call_id); BuildReturnWithNoExpr(context, SemIR::LocId(callee_id)); }