Fix users of toolchain resolution to call the new skyfunction.

Part of work on execution transitions, #7935.

Closes #8102.

PiperOrigin-RevId: 244878862
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java
deleted file mode 100644
index 4a92d5b..0000000
--- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java
+++ /dev/null
@@ -1,507 +0,0 @@
-// Copyright 2018 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.analysis;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.ImmutableList.toImmutableList;
-import static java.util.stream.Collectors.joining;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Table;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
-import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
-import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
-import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
-import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
-import com.google.devtools.build.lib.skyframe.ConstraintValueLookupUtil;
-import com.google.devtools.build.lib.skyframe.ConstraintValueLookupUtil.InvalidConstraintValueException;
-import com.google.devtools.build.lib.skyframe.PlatformLookupUtil;
-import com.google.devtools.build.lib.skyframe.PlatformLookupUtil.InvalidPlatformException;
-import com.google.devtools.build.lib.skyframe.RegisteredExecutionPlatformsValue;
-import com.google.devtools.build.lib.skyframe.RegisteredToolchainsFunction.InvalidToolchainLabelException;
-import com.google.devtools.build.lib.skyframe.SingleToolchainResolutionFunction;
-import com.google.devtools.build.lib.skyframe.SingleToolchainResolutionFunction.NoToolchainFoundException;
-import com.google.devtools.build.lib.skyframe.SingleToolchainResolutionValue;
-import com.google.devtools.build.lib.skyframe.ToolchainException;
-import com.google.devtools.build.lib.skyframe.UnloadedToolchainContext;
-import com.google.devtools.build.skyframe.SkyFunction.Environment;
-import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.ValueOrException2;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.Nullable;
-
-/**
- * Performs the toolchain resolution process to determine the correct toolchain target dependencies
- * for a target being configured, based on the required toolchain types, target platform, and
- * available execution platforms.
- */
-public class ToolchainResolver {
-  // Required data.
-  private final Environment environment;
-  private final BuildConfigurationValue.Key configurationKey;
-
-  // Optional data.
-  private ImmutableSet<Label> requiredToolchainTypeLabels = ImmutableSet.of();
-  private ImmutableSet<Label> execConstraintLabels = ImmutableSet.of();
-  private boolean shouldSanityCheckConfiguration = false;
-
-  // Determined during execution.
-  private boolean debug = false;
-
-  /**
-   * Creates a new {@link ToolchainResolver} to help find the required toolchains for a configured
-   * target.
-   *
-   * @param env the environment to use to request dependent Skyframe nodes
-   * @param configurationKey The build configuration to use for dependent targets
-   */
-  public ToolchainResolver(Environment env, BuildConfigurationValue.Key configurationKey) {
-    this.environment = checkNotNull(env);
-    this.configurationKey = checkNotNull(configurationKey);
-  }
-
-  /**
-   * Sets the labels of the required toolchain types that this resolver needs to find toolchains
-   * for.
-   */
-  public ToolchainResolver setRequiredToolchainTypes(Set<Label> requiredToolchainTypeLabels) {
-    this.requiredToolchainTypeLabels = ImmutableSet.copyOf(requiredToolchainTypeLabels);
-    return this;
-  }
-
-  /**
-   * Sets extra constraints on the execution platform. Targets can use this to ensure that the
-   * execution platform has some desired characteristics, such as having enough memory to run tests.
-   */
-  public ToolchainResolver setExecConstraintLabels(Set<Label> execConstraintLabels) {
-    this.execConstraintLabels = ImmutableSet.copyOf(execConstraintLabels);
-    return this;
-  }
-
-  /**
-   * Sets whether the experimental retroactive trimming mode is in use. This determines whether
-   * sanity checks regarding the fragments in use for the configurations of platforms and toolchains
-   * are used - specifically, whether platforms use only the PlatformConfiguration, and toolchains
-   * do not use any configuration at all.
-   */
-  public ToolchainResolver setShouldSanityCheckConfiguration(boolean useSanityChecks) {
-    this.shouldSanityCheckConfiguration = useSanityChecks;
-    return this;
-  }
-
-  /**
-   * Determines the specific toolchains that are required, given the requested toolchain types,
-   * target platform, and configuration.
-   *
-   * <p>In order to resolve toolchains, first the {@link ToolchainResolver} must be created, and
-   * then an {@link UnloadedToolchainContext} generated. The {@link UnloadedToolchainContext} will
-   * report the specific toolchain targets to depend on, and those can be found using the typical
-   * dependency machinery. Once dependencies, including toolchains, have been loaded, the {@link
-   * ResolvedToolchainContext#load} method can be called to generate the final {@link
-   * ResolvedToolchainContext} to be used by the target.
-   *
-   * <p>This makes several SkyFrame calls, particularly to {@link
-   * com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction} (to load platforms and
-   * toolchains), to {@link
-   * com.google.devtools.build.lib.skyframe.RegisteredExecutionPlatformsFunction}, and to {@link
-   * SingleToolchainResolutionFunction}. This method returns {@code null} to signal a SkyFrame
-   * restart is needed to resolve dependencies.
-   */
-  @Nullable
-  public UnloadedToolchainContext resolve() throws InterruptedException, ToolchainException {
-
-    try {
-      UnloadedToolchainContext.Builder unloadedToolchainContext =
-          UnloadedToolchainContext.builder();
-
-      // Determine the configuration being used.
-      BuildConfigurationValue value =
-          (BuildConfigurationValue) environment.getValue(configurationKey);
-      if (value == null) {
-        throw new ValueMissingException();
-      }
-      BuildConfiguration configuration = value.getConfiguration();
-      PlatformConfiguration platformConfiguration =
-          configuration.getFragment(PlatformConfiguration.class);
-      if (platformConfiguration == null) {
-        throw new ValueMissingException();
-      }
-
-      // Check if debug output should be generated.
-      this.debug = configuration.getOptions().get(PlatformOptions.class).toolchainResolutionDebug;
-
-      // Create keys for all platforms that will be used, and validate them early.
-      PlatformKeys platformKeys = loadPlatformKeys(configuration, platformConfiguration);
-      if (environment.valuesMissing()) {
-        return null;
-      }
-
-      // Determine the actual toolchain implementations to use.
-      determineToolchainImplementations(unloadedToolchainContext, platformKeys);
-
-      return unloadedToolchainContext.build();
-    } catch (ValueMissingException e) {
-      return null;
-    }
-  }
-
-  @AutoValue
-  abstract static class PlatformKeys {
-    abstract ConfiguredTargetKey hostPlatformKey();
-
-    abstract ConfiguredTargetKey targetPlatformKey();
-
-    abstract ImmutableList<ConfiguredTargetKey> executionPlatformKeys();
-
-    static PlatformKeys create(
-        ConfiguredTargetKey hostPlatformKey,
-        ConfiguredTargetKey targetPlatformKey,
-        List<ConfiguredTargetKey> executionPlatformKeys) {
-      return new AutoValue_ToolchainResolver_PlatformKeys(
-          hostPlatformKey, targetPlatformKey, ImmutableList.copyOf(executionPlatformKeys));
-    }
-  }
-
-  private PlatformKeys loadPlatformKeys(
-      BuildConfiguration configuration, PlatformConfiguration platformConfiguration)
-      throws InterruptedException, InvalidPlatformException, ValueMissingException,
-          InvalidConstraintValueException {
-    // Determine the target and host platform keys.
-    Label hostPlatformLabel = platformConfiguration.getHostPlatform();
-    Label targetPlatformLabel = platformConfiguration.getTargetPlatform();
-
-    ConfiguredTargetKey hostPlatformKey = ConfiguredTargetKey.of(hostPlatformLabel, configuration);
-    ConfiguredTargetKey targetPlatformKey =
-        ConfiguredTargetKey.of(targetPlatformLabel, configuration);
-
-    // Load the host and target platforms early, to check for errors.
-    PlatformLookupUtil.getPlatformInfo(
-        ImmutableList.of(hostPlatformKey, targetPlatformKey),
-        environment,
-        shouldSanityCheckConfiguration);
-    if (environment.valuesMissing()) {
-      throw new ValueMissingException();
-    }
-
-    ImmutableList<ConfiguredTargetKey> executionPlatformKeys =
-        loadExecutionPlatformKeys(configuration, hostPlatformKey);
-
-    return PlatformKeys.create(hostPlatformKey, targetPlatformKey, executionPlatformKeys);
-  }
-
-  private ImmutableList<ConfiguredTargetKey> loadExecutionPlatformKeys(
-      BuildConfiguration configuration, ConfiguredTargetKey defaultPlatformKey)
-      throws InvalidPlatformException, InterruptedException, InvalidConstraintValueException,
-          ValueMissingException {
-    RegisteredExecutionPlatformsValue registeredExecutionPlatforms =
-        (RegisteredExecutionPlatformsValue)
-            environment.getValueOrThrow(
-                RegisteredExecutionPlatformsValue.key(configurationKey),
-                InvalidPlatformException.class);
-    if (registeredExecutionPlatforms == null) {
-      throw new ValueMissingException();
-    }
-
-    ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys =
-        new ImmutableList.Builder<ConfiguredTargetKey>()
-            .addAll(registeredExecutionPlatforms.registeredExecutionPlatformKeys())
-            .add(defaultPlatformKey)
-            .build();
-
-    // Filter out execution platforms that don't satisfy the extra constraints.
-    ImmutableList<ConfiguredTargetKey> execConstraintKeys =
-        execConstraintLabels.stream()
-            .map(label -> ConfiguredTargetKey.of(label, configuration))
-            .collect(toImmutableList());
-
-    return filterAvailablePlatforms(availableExecutionPlatformKeys, execConstraintKeys);
-  }
-
-  /** Returns only the platform keys that match the given constraints. */
-  private ImmutableList<ConfiguredTargetKey> filterAvailablePlatforms(
-      ImmutableList<ConfiguredTargetKey> platformKeys,
-      ImmutableList<ConfiguredTargetKey> constraintKeys)
-      throws InterruptedException, InvalidPlatformException, InvalidConstraintValueException,
-          ValueMissingException {
-
-    // Short circuit if not needed.
-    if (constraintKeys.isEmpty()) {
-      return platformKeys;
-    }
-
-    // At this point the host and target platforms have been loaded, but not necessarily the chosen
-    // execution platform (it might be the same as the host platform, and might not).
-    //
-    // It's not worth trying to optimize away this call, since in the optimizable case (the exec
-    // platform is the host platform), Skyframe will return the correct results immediately without
-    // need of a restart.
-    Map<ConfiguredTargetKey, PlatformInfo> platformInfoMap =
-        PlatformLookupUtil.getPlatformInfo(
-            platformKeys, environment, shouldSanityCheckConfiguration);
-    if (platformInfoMap == null) {
-      throw new ValueMissingException();
-    }
-    List<ConstraintValueInfo> constraints =
-        ConstraintValueLookupUtil.getConstraintValueInfo(constraintKeys, environment);
-    if (constraints == null) {
-      throw new ValueMissingException();
-    }
-
-    return platformKeys.stream()
-        .filter(key -> filterPlatform(platformInfoMap.get(key), constraints))
-        .collect(toImmutableList());
-  }
-
-  /** Returns {@code true} if the given platform has all of the constraints. */
-  private boolean filterPlatform(PlatformInfo platformInfo, List<ConstraintValueInfo> constraints) {
-    ImmutableList<ConstraintValueInfo> missingConstraints =
-        platformInfo.constraints().findMissing(constraints);
-    if (debug) {
-      for (ConstraintValueInfo constraint : missingConstraints) {
-        // The value for this setting is not present in the platform, or doesn't match the expected
-        // value.
-        environment
-            .getListener()
-            .handle(
-                Event.info(
-                    String.format(
-                        "ToolchainResolver: Removed execution platform %s from"
-                            + " available execution platforms, it is missing constraint %s",
-                        platformInfo.label(), constraint.label())));
-        }
-    }
-
-    return missingConstraints.isEmpty();
-  }
-
-  private void determineToolchainImplementations(
-      UnloadedToolchainContext.Builder unloadedToolchainContext, PlatformKeys platformKeys)
-      throws InterruptedException, ToolchainException, ValueMissingException {
-
-    // Find the toolchains for the required toolchain types.
-    List<SingleToolchainResolutionValue.Key> registeredToolchainKeys = new ArrayList<>();
-    for (Label toolchainTypeLabel : requiredToolchainTypeLabels) {
-      registeredToolchainKeys.add(
-          SingleToolchainResolutionValue.key(
-              configurationKey,
-              toolchainTypeLabel,
-              platformKeys.targetPlatformKey(),
-              platformKeys.executionPlatformKeys()));
-    }
-
-    Map<SkyKey, ValueOrException2<NoToolchainFoundException, InvalidToolchainLabelException>>
-        results =
-            environment.getValuesOrThrow(
-                registeredToolchainKeys,
-                NoToolchainFoundException.class,
-                InvalidToolchainLabelException.class);
-    boolean valuesMissing = false;
-
-    // Determine the potential set of toolchains.
-    Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains =
-        HashBasedTable.create();
-    ImmutableSet.Builder<ToolchainTypeInfo> requiredToolchainTypesBuilder = ImmutableSet.builder();
-    List<Label> missingToolchains = new ArrayList<>();
-    for (Map.Entry<
-            SkyKey, ValueOrException2<NoToolchainFoundException, InvalidToolchainLabelException>>
-        entry : results.entrySet()) {
-      try {
-        ValueOrException2<NoToolchainFoundException, InvalidToolchainLabelException>
-            valueOrException = entry.getValue();
-        SingleToolchainResolutionValue singleToolchainResolutionValue =
-            (SingleToolchainResolutionValue) valueOrException.get();
-        if (singleToolchainResolutionValue == null) {
-          valuesMissing = true;
-          continue;
-        }
-
-        ToolchainTypeInfo requiredToolchainType = singleToolchainResolutionValue.toolchainType();
-        requiredToolchainTypesBuilder.add(requiredToolchainType);
-        resolvedToolchains.putAll(
-            findPlatformsAndLabels(requiredToolchainType, singleToolchainResolutionValue));
-      } catch (NoToolchainFoundException e) {
-        // Save the missing type and continue looping to check for more.
-        missingToolchains.add(e.missingToolchainTypeLabel());
-      }
-    }
-
-    if (!missingToolchains.isEmpty()) {
-      throw new UnresolvedToolchainsException(missingToolchains);
-    }
-
-    if (valuesMissing) {
-      throw new ValueMissingException();
-    }
-
-    ImmutableSet<ToolchainTypeInfo> requiredToolchainTypes = requiredToolchainTypesBuilder.build();
-
-    // Find and return the first execution platform which has all required toolchains.
-    Optional<ConfiguredTargetKey> selectedExecutionPlatformKey;
-    if (requiredToolchainTypeLabels.isEmpty()
-        && platformKeys.executionPlatformKeys().contains(platformKeys.hostPlatformKey())) {
-      // Fall back to the legacy behavior: use the host platform if it's available, otherwise the
-      // first execution platform.
-      selectedExecutionPlatformKey = Optional.of(platformKeys.hostPlatformKey());
-    } else {
-      // If there are no toolchains, this will return the first execution platform.
-      selectedExecutionPlatformKey =
-          findExecutionPlatformForToolchains(
-              requiredToolchainTypes, platformKeys.executionPlatformKeys(), resolvedToolchains);
-    }
-
-    if (!selectedExecutionPlatformKey.isPresent()) {
-      throw new NoMatchingPlatformException(
-          requiredToolchainTypeLabels,
-          platformKeys.executionPlatformKeys(),
-          platformKeys.targetPlatformKey());
-    }
-
-    Map<ConfiguredTargetKey, PlatformInfo> platforms =
-        PlatformLookupUtil.getPlatformInfo(
-            ImmutableList.of(selectedExecutionPlatformKey.get(), platformKeys.targetPlatformKey()),
-            environment,
-            shouldSanityCheckConfiguration);
-    if (platforms == null) {
-      throw new ValueMissingException();
-    }
-
-    unloadedToolchainContext.setRequiredToolchainTypes(requiredToolchainTypes);
-    unloadedToolchainContext.setExecutionPlatform(
-        platforms.get(selectedExecutionPlatformKey.get()));
-    unloadedToolchainContext.setTargetPlatform(platforms.get(platformKeys.targetPlatformKey()));
-
-    Map<ToolchainTypeInfo, Label> toolchains =
-        resolvedToolchains.row(selectedExecutionPlatformKey.get());
-    unloadedToolchainContext.setToolchainTypeToResolved(ImmutableBiMap.copyOf(toolchains));
-  }
-
-  /**
-   * Adds all of toolchain labels from{@code toolchainResolutionValue} to {@code
-   * resolvedToolchains}.
-   */
-  private static Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> findPlatformsAndLabels(
-      ToolchainTypeInfo requiredToolchainType,
-      SingleToolchainResolutionValue singleToolchainResolutionValue) {
-
-    Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains =
-        HashBasedTable.create();
-    for (Map.Entry<ConfiguredTargetKey, Label> entry :
-        singleToolchainResolutionValue.availableToolchainLabels().entrySet()) {
-      resolvedToolchains.put(entry.getKey(), requiredToolchainType, entry.getValue());
-    }
-    return resolvedToolchains;
-  }
-
-  /**
-   * Finds the first platform from {@code availableExecutionPlatformKeys} that is present in {@code
-   * resolvedToolchains} and has all required toolchain types.
-   */
-  private Optional<ConfiguredTargetKey> findExecutionPlatformForToolchains(
-      ImmutableSet<ToolchainTypeInfo> requiredToolchainTypes,
-      ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
-      Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains) {
-    for (ConfiguredTargetKey executionPlatformKey : availableExecutionPlatformKeys) {
-      Map<ToolchainTypeInfo, Label> toolchains = resolvedToolchains.row(executionPlatformKey);
-
-      if (!toolchains.keySet().containsAll(requiredToolchainTypes)) {
-        // Not all toolchains are present, keep going
-        continue;
-      }
-
-      if (debug) {
-        String selectedToolchains =
-            toolchains.entrySet().stream()
-                .map(
-                    e ->
-                        String.format(
-                            "type %s -> toolchain %s", e.getKey().typeLabel(), e.getValue()))
-                .collect(joining(", "));
-        environment
-            .getListener()
-            .handle(
-                Event.info(
-                    String.format(
-                        "ToolchainResolver: Selected execution platform %s, %s",
-                        executionPlatformKey.getLabel(), selectedToolchains)));
-      }
-      return Optional.of(executionPlatformKey);
-    }
-
-    return Optional.empty();
-  }
-
-  private static final class ValueMissingException extends Exception {
-    private ValueMissingException() {
-      super();
-    }
-  }
-
-  /** Exception used when no execution platform can be found. */
-  static final class NoMatchingPlatformException extends ToolchainException {
-    NoMatchingPlatformException(
-        Set<Label> requiredToolchainTypeLabels,
-        ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
-        ConfiguredTargetKey targetPlatformKey) {
-      super(
-          formatError(
-              requiredToolchainTypeLabels, availableExecutionPlatformKeys, targetPlatformKey));
-    }
-
-    private static String formatError(
-        Set<Label> requiredToolchainTypeLabels,
-        ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
-        ConfiguredTargetKey targetPlatformKey) {
-      if (requiredToolchainTypeLabels.isEmpty()) {
-        return String.format(
-            "Unable to find an execution platform for target platform %s"
-                + " from available execution platforms [%s]",
-            targetPlatformKey.getLabel(),
-            availableExecutionPlatformKeys.stream()
-                .map(key -> key.getLabel().toString())
-                .collect(Collectors.joining(", ")));
-      }
-      return String.format(
-          "Unable to find an execution platform for toolchains [%s] and target platform %s"
-              + " from available execution platforms [%s]",
-          requiredToolchainTypeLabels.stream().map(Label::toString).collect(joining(", ")),
-          targetPlatformKey.getLabel(),
-          availableExecutionPlatformKeys.stream()
-              .map(key -> key.getLabel().toString())
-              .collect(Collectors.joining(", ")));
-    }
-  }
-
-  /** Exception used when a toolchain type is required but no matching toolchain is found. */
-  static final class UnresolvedToolchainsException extends ToolchainException {
-    UnresolvedToolchainsException(List<Label> missingToolchainTypes) {
-      super(
-          String.format(
-              "no matching toolchains found for types %s",
-              missingToolchainTypes.stream().map(Label::toString).collect(joining(", "))));
-    }
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
index dff58a5..edefd40 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.query2;
 
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -368,17 +369,26 @@
 
   protected abstract RuleConfiguredTarget getRuleConfiguredTarget(T target);
 
+  protected Collection<T> targetifyValues(Iterable<SkyKey> dependencies)
+      throws InterruptedException {
+    Collection<T> values = new ArrayList<>();
+    for (SkyKey key : dependencies) {
+      if (key.functionName().equals(SkyFunctions.CONFIGURED_TARGET)) {
+        values.add(getValueFromKey(key));
+      } else if (key.functionName().equals(SkyFunctions.TOOLCHAIN_RESOLUTION)) {
+        // Also fetch these dependencies.
+        Collection<T> toolchainDeps = targetifyValues(graph.getDirectDeps(key));
+        values.addAll(toolchainDeps);
+      }
+    }
+    return values;
+  }
+
   protected Map<SkyKey, Collection<T>> targetifyValues(
       Map<SkyKey, ? extends Iterable<SkyKey>> input) throws InterruptedException {
     Map<SkyKey, Collection<T>> result = new HashMap<>();
     for (Map.Entry<SkyKey, ? extends Iterable<SkyKey>> entry : input.entrySet()) {
-      Collection<T> value = new ArrayList<>();
-      for (SkyKey key : entry.getValue()) {
-        if (key.functionName().equals(SkyFunctions.CONFIGURED_TARGET)) {
-          value.add(getValueFromKey(key));
-        }
-      }
-      result.put(entry.getKey(), value);
+      result.put(entry.getKey(), targetifyValues(entry.getValue()));
     }
     return result;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index 743c7d2..d278350 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -31,7 +31,6 @@
 import com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException;
 import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
 import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
-import com.google.devtools.build.lib.analysis.ToolchainResolver;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
@@ -413,9 +412,15 @@
         try {
           ImmutableSet<Label> requiredToolchains = aspect.getDefinition().getRequiredToolchains();
           unloadedToolchainContext =
-              new ToolchainResolver(env, BuildConfigurationValue.key(configuration))
-                  .setRequiredToolchainTypes(requiredToolchains)
-                  .resolve();
+              (UnloadedToolchainContext)
+                  env.getValueOrThrow(
+                      UnloadedToolchainContext.key()
+                          .configurationKey(BuildConfigurationValue.key(configuration))
+                          .requiredToolchainTypeLabels(requiredToolchains)
+                          .shouldSanityCheckConfiguration(
+                              configuration.trimConfigurationsRetroactively())
+                          .build(),
+                      ToolchainException.class);
         } catch (ToolchainException e) {
           // TODO(katre): better error handling
           throw new AspectCreationException(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
index a266129..1e36cb7 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
@@ -37,7 +37,6 @@
 import com.google.devtools.build.lib.analysis.EmptyConfiguredTarget;
 import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
 import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
-import com.google.devtools.build.lib.analysis.ToolchainResolver;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
@@ -309,12 +308,16 @@
           // Collect local (target, rule) constraints for filtering out execution platforms.
           ImmutableSet<Label> execConstraintLabels = getExecutionPlatformConstraints(rule);
           unloadedToolchainContext =
-              new ToolchainResolver(env, configuredTargetKey.getConfigurationKey())
-                  .setRequiredToolchainTypes(requiredToolchains)
-                  .setExecConstraintLabels(execConstraintLabels)
-                  .setShouldSanityCheckConfiguration(
-                      configuration.trimConfigurationsRetroactively())
-                  .resolve();
+              (UnloadedToolchainContext)
+                  env.getValueOrThrow(
+                      UnloadedToolchainContext.key()
+                          .configurationKey(configuredTargetKey.getConfigurationKey())
+                          .requiredToolchainTypeLabels(requiredToolchains)
+                          .execConstraintLabels(execConstraintLabels)
+                          .shouldSanityCheckConfiguration(
+                              configuration.trimConfigurationsRetroactively())
+                          .build(),
+                      ToolchainException.class);
           if (env.valuesMissing()) {
             return null;
           }
@@ -426,10 +429,8 @@
               e.getCauses()));
     } catch (ToolchainException e) {
       // We need to throw a ConfiguredValueCreationException, so either find one or make one.
-      ConfiguredValueCreationException cvce;
-      if (e.getCause() instanceof ConfiguredValueCreationException) {
-        cvce = (ConfiguredValueCreationException) e.getCause();
-      } else {
+      ConfiguredValueCreationException cvce = e.asConfiguredValueCreationException();
+      if (cvce == null) {
         cvce =
             new ConfiguredValueCreationException(e.getMessage(), target.getLabel(), configuration);
       }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index da00c9f..76cdaf3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -138,7 +138,7 @@
       SkyFunctionName.createHermetic("REGISTERED_TOOLCHAINS");
   static final SkyFunctionName SINGLE_TOOLCHAIN_RESOLUTION =
       SkyFunctionName.createHermetic("SINGLE_TOOLCHAIN_RESOLUTION");
-  static final SkyFunctionName TOOLCHAIN_RESOLUTION =
+  public static final SkyFunctionName TOOLCHAIN_RESOLUTION =
       SkyFunctionName.createHermetic("TOOLCHAIN_RESOLUTION");
   public static final SkyFunctionName REPOSITORY_MAPPING =
       SkyFunctionName.createHermetic("REPOSITORY_MAPPING");
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
index d39d838..d2bf860 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
@@ -93,7 +93,6 @@
       // Determine the actual toolchain implementations to use.
       determineToolchainImplementations(
           env,
-          debug,
           key.configurationKey(),
           key.requiredToolchainTypeLabels(),
           builder,
@@ -275,7 +274,7 @@
             .handle(
                 Event.info(
                     String.format(
-                        "ToolchainResolver: Removed execution platform %s from"
+                        "ToolchainResolution: Removed execution platform %s from"
                             + " available execution platforms, it is missing constraint %s",
                         platformInfo.label(), constraint.label())));
       }
@@ -285,8 +284,7 @@
   }
 
   private void determineToolchainImplementations(
-      SkyFunction.Environment environment,
-      boolean debug,
+      Environment environment,
       BuildConfigurationValue.Key configurationKey,
       ImmutableSet<Label> requiredToolchainTypeLabels,
       UnloadedToolchainContext.Builder builder,
@@ -358,8 +356,6 @@
     if (!requiredToolchainTypeLabels.isEmpty()) {
       selectedExecutionPlatformKey =
           findExecutionPlatformForToolchains(
-              environment,
-              debug,
               requiredToolchainTypes,
               platformKeys.executionPlatformKeys(),
               resolvedToolchains);
@@ -400,7 +396,7 @@
   }
 
   /**
-   * Adds all of toolchain labels from{@code toolchainResolutionValue} to {@code
+   * Adds all of toolchain labels from {@code toolchainResolutionValue} to {@code
    * resolvedToolchains}.
    */
   private static Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> findPlatformsAndLabels(
@@ -421,8 +417,6 @@
    * resolvedToolchains} and has all required toolchain types.
    */
   private static Optional<ConfiguredTargetKey> findExecutionPlatformForToolchains(
-      SkyFunction.Environment environment,
-      boolean debug,
       ImmutableSet<ToolchainTypeInfo> requiredToolchainTypes,
       ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
       Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains) {