Selaa lähdekoodia

Remove a use of zip/to_array in eval (#6393)

The to_array was mainly needed for zip_equal, and the
GetBlockAsTypeInstIds is forming a vector that should also be size two.
But just writing this out should avoid memory allocations.

Of course, then I'm like "but maybe a lambda or function would be
clearer than a for loop"... So the second commit.
Jon Ross-Perkins 5 kuukautta sitten
vanhempi
sitoutus
ee49d65e29
1 muutettua tiedostoa jossa 23 lisäystä ja 21 poistoa
  1. 23 21
      toolchain/check/eval.cpp

+ 23 - 21
toolchain/check/eval.cpp

@@ -1649,6 +1649,26 @@ static auto PerformBuiltinBoolComparison(
                             : lhs != rhs);
 }
 
+// Converts a call argument to a FacetTypeId.
+static auto ArgToFacetTypeId(Context& context, SemIR::LocId loc_id,
+                             SemIR::InstId arg_id) -> SemIR::FacetTypeId {
+  auto type_arg_id = context.types().GetAsTypeInstId(arg_id);
+  if (auto facet_type =
+          context.insts().TryGetAs<SemIR::FacetType>(type_arg_id)) {
+    return facet_type->facet_type_id;
+  }
+  CARBON_DIAGNOSTIC(FacetTypeRequiredForTypeAndOperator, Error,
+                    "non-facet type {0} combined with `&` operator",
+                    SemIR::TypeId);
+  // TODO: Find a location for the lhs or rhs specifically, instead of
+  // the whole thing. If that's not possible we can change the text to
+  // say if it's referring to the left or the right side for the error.
+  // The `arg_id` instruction has no location in it for some reason.
+  context.emitter().Emit(loc_id, FacetTypeRequiredForTypeAndOperator,
+                         context.types().GetTypeIdForTypeInstId(type_arg_id));
+  return SemIR::FacetTypeId::None;
+}
+
 // Returns a constant for a call to a builtin function.
 static auto MakeConstantForBuiltinCall(EvalContext& eval_context,
                                        SemIR::LocId loc_id, SemIR::Call call,
@@ -1718,27 +1738,9 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context,
 
     case SemIR::BuiltinFunctionKind::TypeAnd: {
       CARBON_CHECK(arg_ids.size() == 2);
-      auto lhs_facet_type_id = SemIR::FacetTypeId::None;
-      auto rhs_facet_type_id = SemIR::FacetTypeId::None;
-      for (auto [facet_type_id, type_arg_id] : llvm::zip_equal(
-               std::to_array({&lhs_facet_type_id, &rhs_facet_type_id}),
-               context.types().GetBlockAsTypeInstIds(arg_ids))) {
-        if (auto facet_type =
-                context.insts().TryGetAs<SemIR::FacetType>(type_arg_id)) {
-          *facet_type_id = facet_type->facet_type_id;
-        } else {
-          CARBON_DIAGNOSTIC(FacetTypeRequiredForTypeAndOperator, Error,
-                            "non-facet type {0} combined with `&` operator",
-                            SemIR::TypeId);
-          // TODO: Find a location for the lhs or rhs specifically, instead of
-          // the whole thing. If that's not possible we can change the text to
-          // say if it's referring to the left or the right side for the error.
-          // The `arg_id` instruction has no location in it for some reason.
-          context.emitter().Emit(
-              loc_id, FacetTypeRequiredForTypeAndOperator,
-              context.types().GetTypeIdForTypeInstId(type_arg_id));
-        }
-      }
+      auto lhs_facet_type_id = ArgToFacetTypeId(context, loc_id, arg_ids[0]);
+      auto rhs_facet_type_id = ArgToFacetTypeId(context, loc_id, arg_ids[1]);
+
       // Allow errors to be diagnosed for both sides of the operator before
       // returning here if any error occurred on either side.
       if (!lhs_facet_type_id.has_value() || !rhs_facet_type_id.has_value()) {