Kaynağa Gözat

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.
Richard Smith 1 yıl önce
ebeveyn
işleme
69b9982e95

+ 10 - 0
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)

+ 3 - 0
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_

+ 1 - 14
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;
 }
 

+ 2 - 0
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));
   }