BEP reports analysis failure for targets with artifact conflicts.
Artifact conflicts are detected through a non-skyframe evaluation that is not
capable of identifying a top-level target or aspect that failed as a result of the
artifact conflict. We do perform a skyframe evaluation to identify which targets
and aspects to actually evaluate however, and *this* evaluation is now used to
report artifact conflicts in BEP.
A previous implementation of this change was rolled back due to a crash that
occurred if a --keep_going build included both action conflicts and other analysis
failures. A new regression test is included for this case.
RELNOTES: None.
PiperOrigin-RevId: 368017860
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ArtifactPrefixConflictException.java b/src/main/java/com/google/devtools/build/lib/actions/ArtifactPrefixConflictException.java
index d6fb317..a908db5 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ArtifactPrefixConflictException.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ArtifactPrefixConflictException.java
@@ -27,6 +27,8 @@
* lead to an error if both actions were executed in the same build.
*/
public class ArtifactPrefixConflictException extends Exception implements DetailedException {
+ private final Label firstOwner;
+
public ArtifactPrefixConflictException(
PathFragment firstPath, PathFragment secondPath, Label firstOwner, Label secondOwner) {
super(
@@ -35,6 +37,11 @@
+ "These actions cannot be simultaneously present; please rename one of the output "
+ "files or build just one of them",
firstPath, firstOwner, secondPath, secondOwner));
+ this.firstOwner = firstOwner;
+ }
+
+ public Label getFirstOwner() {
+ return firstOwner;
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
index 02c37bf..1e8a0ef 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisFailureEvent.java
@@ -16,8 +16,10 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.buildeventstream.BuildEvent;
import com.google.devtools.build.lib.buildeventstream.BuildEventContext;
import com.google.devtools.build.lib.buildeventstream.BuildEventIdUtil;
@@ -28,6 +30,7 @@
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.skyframe.AspectValueKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import java.util.Collection;
import javax.annotation.Nullable;
@@ -37,13 +40,34 @@
* target cannot be completed because of an error in one of its dependencies.
*/
public class AnalysisFailureEvent implements BuildEvent {
+ @Nullable private final AspectValueKey failedAspect;
private final ConfiguredTargetKey failedTarget;
private final BuildEventId configuration;
private final NestedSet<Cause> rootCauses;
public AnalysisFailureEvent(
- ConfiguredTargetKey failedTarget, BuildEventId configuration, NestedSet<Cause> rootCauses) {
- this.failedTarget = failedTarget;
+ ActionLookupKey failedTarget, BuildEventId configuration, NestedSet<Cause> rootCauses) {
+ Preconditions.checkArgument(
+ failedTarget instanceof ConfiguredTargetKey || failedTarget instanceof AspectValueKey);
+ if (failedTarget instanceof ConfiguredTargetKey) {
+ this.failedAspect = null;
+ this.failedTarget = (ConfiguredTargetKey) failedTarget;
+ } else {
+ this.failedAspect = (AspectValueKey) failedTarget;
+ this.failedTarget = failedAspect.getBaseConfiguredTargetKey();
+ }
+ if (configuration != null) {
+ this.configuration = configuration;
+ } else {
+ this.configuration = NullConfiguration.INSTANCE.getEventId();
+ }
+ this.rootCauses = rootCauses;
+ }
+
+ public AnalysisFailureEvent(
+ AspectValueKey failedAspect, BuildEventId configuration, NestedSet<Cause> rootCauses) {
+ this.failedAspect = failedAspect;
+ this.failedTarget = failedAspect.getBaseConfiguredTargetKey();
if (configuration != null) {
this.configuration = configuration;
} else {
@@ -55,6 +79,7 @@
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
+ .add("failedAspect", failedAspect)
.add("failedTarget", failedTarget)
.add("configuration", configuration)
.add("legacyFailureReason", getLegacyFailureReason())
@@ -86,7 +111,12 @@
@Override
public BuildEventId getEventId() {
- return BuildEventIdUtil.targetCompleted(failedTarget.getLabel(), configuration);
+ if (failedAspect == null) {
+ return BuildEventIdUtil.targetCompleted(failedTarget.getLabel(), configuration);
+ } else {
+ return BuildEventIdUtil.aspectCompleted(
+ failedTarget.getLabel(), configuration, failedAspect.getAspectName());
+ }
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionLookupConflictFindingFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionLookupConflictFindingFunction.java
index c5a542f..eede394 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionLookupConflictFindingFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionLookupConflictFindingFunction.java
@@ -80,7 +80,7 @@
return Label.print(((ConfiguredTargetKey) skyKey.argument()).getLabel());
}
- private static class ActionConflictFunctionException extends SkyFunctionException {
+ static class ActionConflictFunctionException extends SkyFunctionException {
ActionConflictFunctionException(ConflictException e) {
super(e, Transience.PERSISTENT);
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactConflictFinder.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactConflictFinder.java
index 15fb842..8eb9a8f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactConflictFinder.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactConflictFinder.java
@@ -199,14 +199,15 @@
this.apce = e;
}
- void rethrowTyped() throws ActionConflictException, ArtifactPrefixConflictException {
+ IllegalStateException rethrowTyped()
+ throws ActionConflictException, ArtifactPrefixConflictException {
if (ace == null) {
throw Preconditions.checkNotNull(apce);
}
if (apce == null) {
throw Preconditions.checkNotNull(ace);
}
- throw new IllegalStateException();
+ throw new IllegalStateException("malformed ConflictException has no well-typed cause");
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java
index d123290..63f284d 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectValueKey.java
@@ -35,8 +35,22 @@
private static final Interner<StarlarkAspectLoadingKey> starlarkAspectKeyInterner =
BlazeInterners.newWeakInterner();
+ /**
+ * Gets the name of the aspect that would be returned by the corresponding value's {@code
+ * aspectValue.getAspect().getAspectClass().getName()}, if the value could be produced.
+ *
+ * <p>Only needed for reporting errors in BEP when the key's AspectValue fails evaluation.
+ */
+ public abstract String getAspectName();
+
public abstract String getDescription();
+ @Nullable
+ abstract BuildConfigurationValue.Key getAspectConfigurationKey();
+
+ /** Returns the key for the base configured target for this aspect. */
+ public abstract ConfiguredTargetKey getBaseConfiguredTargetKey();
+
public static AspectKey createAspectKey(
Label label,
@Nullable BuildConfiguration baseConfiguration,
@@ -121,6 +135,10 @@
return SkyFunctions.ASPECT;
}
+ @Override
+ public String getAspectName() {
+ return aspectDescriptor.getDescription();
+ }
@Override
public Label getLabel() {
@@ -174,11 +192,13 @@
* base target's configuration.
*/
@Nullable
+ @Override
BuildConfigurationValue.Key getAspectConfigurationKey() {
return aspectConfigurationKey;
}
/** Returns the key for the base configured target for this aspect. */
+ @Override
public ConfiguredTargetKey getBaseConfiguredTargetKey() {
return baseConfiguredTargetKey;
}
@@ -312,6 +332,11 @@
}
@Override
+ public String getAspectName() {
+ return String.format("%s%%%s", starlarkFileLabel, starlarkValueName);
+ }
+
+ @Override
public Label getLabel() {
return targetLabel;
}
@@ -322,6 +347,18 @@
return String.format("%s%%%s of %s", starlarkFileLabel, starlarkValueName, targetLabel);
}
+ @Nullable
+ @Override
+ BuildConfigurationValue.Key getAspectConfigurationKey() {
+ return aspectConfigurationKey;
+ }
+
+ /** Returns the key for the base configured target for this aspect. */
+ @Override
+ public ConfiguredTargetKey getBaseConfiguredTargetKey() {
+ return baseConfiguredTargetKey;
+ }
+
@Override
public int hashCode() {
// We use the hash code caching strategy employed by java.lang.String. There are three subtle
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
index a44dbb8..1a90a8a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
@@ -85,6 +85,7 @@
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.skyframe.ArtifactConflictFinder.ConflictException;
import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
+import com.google.devtools.build.lib.skyframe.SkyframeExecutor.TopLevelActionConflictReport;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
import com.google.devtools.build.lib.util.Pair;
@@ -104,9 +105,9 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import javax.annotation.Nullable;
@@ -315,7 +316,7 @@
eventHandler.handle(
Event.info(
"--discard_analysis_cache was used in the previous build, "
- + "discarding analysis cache."));
+ + "discarding analysis cache."));
skyframeExecutor.handleAnalysisInvalidatingChange();
} else {
String diff = describeConfigurationDifference(configurations, maxDifferencesToShow);
@@ -479,12 +480,12 @@
keepGoing,
eventBus);
Collection<Exception> reportedExceptions = Sets.newHashSet();
+ ViewCreationFailedException noKeepGoingException = null;
for (Map.Entry<ActionAnalysisMetadata, ConflictException> bad : actionConflicts.entrySet()) {
ConflictException ex = bad.getValue();
DetailedExitCode detailedExitCode;
try {
- ex.rethrowTyped();
- throw new IllegalStateException("ConflictException.rethrowTyped must throw");
+ throw ex.rethrowTyped();
} catch (ActionConflictException ace) {
detailedExitCode = ace.getDetailedExitCode();
ace.reportTo(eventHandler);
@@ -503,24 +504,32 @@
}
// TODO(ulfjack): Don't throw here in the nokeep_going case, but report all known issues.
if (!keepGoing) {
- throw new ViewCreationFailedException(detailedExitCode.getFailureDetail(), ex);
+ noKeepGoingException =
+ new ViewCreationFailedException(detailedExitCode.getFailureDetail(), ex);
+ if (errors.second != null) {
+ throw noKeepGoingException;
+ }
}
}
// This is here for backwards compatibility. The keep_going and nokeep_going code paths were
// checking action conflicts and analysis errors in different orders, so we only throw the
// analysis error here after first throwing action conflicts.
- if (!keepGoing) {
+ //
+ // If there is no other analysis error, we will have not thrown for action conflicts because we
+ // have not yet reported a root cause for the action conflict. Finding that root cause requires
+ // a skyframe evaluation.
+ if (!keepGoing && errors.second != null) {
throw errors.second;
}
if (foundActionConflict) {
// In order to determine the set of configured targets transitively error free from action
// conflict issues, we run a post-processing update() that uses the bad action map.
- Predicate<ActionLookupKey> errorFreePredicate;
+ TopLevelActionConflictReport topLevelActionConflictReport;
enableAnalysis(true);
try {
- errorFreePredicate =
+ topLevelActionConflictReport =
skyframeExecutor.filterActionConflictsForConfiguredTargetsAndAspects(
eventHandler,
Iterables.concat(ctKeys, aspectKeys),
@@ -529,10 +538,48 @@
} finally {
enableAnalysis(false);
}
+ // Report an AnalysisFailureEvent to BEP for the top-level targets with discoverable action
+ // conflicts, then finally throw if evaluation is --nokeep_going.
+ for (ActionLookupKey ctKey : Iterables.concat(ctKeys, aspectKeys)) {
+ if (!topLevelActionConflictReport.isErrorFree(ctKey)) {
+ Optional<ConflictException> e = topLevelActionConflictReport.getConflictException(ctKey);
+ if (!e.isPresent()) {
+ continue;
+ }
+ AnalysisFailedCause failedCause =
+ makeArtifactConflictAnalysisFailedCause(configurationLookupSupplier, e.get());
+ BuildConfigurationValue.Key configKey =
+ ctKey instanceof ConfiguredTargetKey
+ ? ((ConfiguredTargetKey) ctKey).getConfigurationKey()
+ : ((AspectValueKey) ctKey).getAspectConfigurationKey();
+ eventBus.post(
+ new AnalysisFailureEvent(
+ ctKey,
+ configurationLookupSupplier.get().get(configKey).toBuildEvent().getEventId(),
+ NestedSetBuilder.create(Order.STABLE_ORDER, failedCause)));
+ if (!keepGoing) {
+ noKeepGoingException =
+ new ViewCreationFailedException(
+ failedCause.getDetailedExitCode().getFailureDetail(), e.get());
+ }
+ }
+ }
+ // If we're here and we're --nokeep_going, then there was a conflict due to actions not
+ // discoverable by TopLevelActionLookupConflictFindingFunction. This includes extra actions,
+ // coverage artifacts, and artifacts produced by aspects in output groups not present in
+ // --output_groups. Throw the exception produced by the ArtifactConflictFinder which cannot
+ // identify root-cause top-level keys but does catch all possible conflicts.
+ if (!keepGoing) {
+ skyframeExecutor.resetActionConflictsStoredInSkyframe();
+ throw noKeepGoingException;
+ }
+
+ // Filter cts and aspects to only error-free keys. Note that any analysis failure - not just
+ // action conflicts - will be observed here and lead to a key's exclusion.
cts =
ctKeys.stream()
- .filter(errorFreePredicate)
+ .filter(topLevelActionConflictReport::isErrorFree)
.map(
k ->
Preconditions.checkNotNull((ConfiguredTargetValue) result.get(k), k)
@@ -541,7 +588,7 @@
aspects =
aspectKeys.stream()
- .filter(errorFreePredicate)
+ .filter(topLevelActionConflictReport::isErrorFree)
.map(result::get)
.map(AspectValue.class::cast)
.collect(
@@ -559,6 +606,36 @@
packageRoots);
}
+ private static AnalysisFailedCause makeArtifactConflictAnalysisFailedCause(
+ Supplier<Map<BuildConfigurationValue.Key, BuildConfiguration>> configurationLookupSupplier,
+ ConflictException e) {
+ try {
+ throw e.rethrowTyped();
+ } catch (ActionConflictException ace) {
+ return makeArtifactConflictAnalysisFailedCause(configurationLookupSupplier, ace);
+ } catch (ArtifactPrefixConflictException apce) {
+ return new AnalysisFailedCause(apce.getFirstOwner(), null, apce.getDetailedExitCode());
+ }
+ }
+
+ private static AnalysisFailedCause makeArtifactConflictAnalysisFailedCause(
+ Supplier<Map<BuildConfigurationValue.Key, BuildConfiguration>> configurationLookupSupplier,
+ ActionConflictException ace) {
+ DetailedExitCode detailedExitCode = ace.getDetailedExitCode();
+ Label causeLabel = ace.getArtifact().getArtifactOwner().getLabel();
+ BuildConfigurationValue.Key causeConfigKey = null;
+ if (ace.getArtifact().getArtifactOwner() instanceof ConfiguredTargetKey) {
+ causeConfigKey =
+ ((ConfiguredTargetKey) ace.getArtifact().getArtifactOwner()).getConfigurationKey();
+ }
+ BuildConfiguration causeConfig =
+ causeConfigKey == null ? null : configurationLookupSupplier.get().get(causeConfigKey);
+ return new AnalysisFailedCause(
+ causeLabel,
+ causeConfig == null ? null : causeConfig.toBuildEvent().getEventId().getConfiguration(),
+ detailedExitCode);
+ }
+
private boolean shouldCheckForConflicts(ImmutableSet<SkyKey> newKeys) {
if (someActionLookupValueEvaluated) {
// A top-level target was added and may introduce a conflict, or a top-level target was
@@ -653,7 +730,8 @@
ErrorInfo errorInfo = errorEntry.getValue();
assertValidAnalysisException(errorInfo, errorKey, result.getWalkableGraph());
skyframeExecutor
- .getCyclesReporter().reportCycles(errorInfo.getCycleInfo(), errorKey, eventHandler);
+ .getCyclesReporter()
+ .reportCycles(errorInfo.getCycleInfo(), errorKey, eventHandler);
Exception cause = errorInfo.getException();
Preconditions.checkState(cause != null || !errorInfo.getCycleInfo().isEmpty(), errorInfo);
@@ -726,7 +804,6 @@
: NestedSetBuilder.emptySet(Order.STABLE_ORDER);
} else if (cause instanceof ActionConflictException) {
((ActionConflictException) cause).reportTo(eventHandler);
- // TODO(ulfjack): Report the action conflict.
rootCauses = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
} else if (cause instanceof NoSuchPackageException) {
// This branch is only taken in --nokeep_going builds. In a --keep_going build, the
@@ -953,11 +1030,11 @@
}
/**
- * Returns the host configuration trimmed to the same fragments as the input configuration. If
- * the input is null, returns the top-level host configuration.
+ * Returns the host configuration trimmed to the same fragments as the input configuration. If the
+ * input is null, returns the top-level host configuration.
*
- * <p>This may only be called after {@link #setTopLevelHostConfiguration} has set the
- * correct host configuration at the top-level.
+ * <p>This may only be called after {@link #setTopLevelHostConfiguration} has set the correct host
+ * configuration at the top-level.
*/
public BuildConfiguration getHostConfiguration(BuildConfiguration config) {
if (config == null) {
@@ -1013,9 +1090,8 @@
}
/**
- * Workaround to clear all legacy data, like the artifact factory. We need
- * to clear them to avoid conflicts.
- * TODO(bazel-team): Remove this workaround. [skyframe-execution]
+ * Workaround to clear all legacy data, like the artifact factory. We need to clear them to avoid
+ * conflicts. TODO(bazel-team): Remove this workaround. [skyframe-execution]
*/
void clearLegacyData() {
artifactFactory.clear();
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 5d99e1d..cd6ffe0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -153,6 +153,7 @@
import com.google.devtools.build.lib.server.FailureDetails.BuildConfiguration.Code;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns;
+import com.google.devtools.build.lib.skyframe.ArtifactConflictFinder.ConflictException;
import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
import com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
@@ -2429,14 +2430,11 @@
/**
* Checks the given action lookup values for action conflicts. Values satisfying the returned
- * predicate are known to be transitively error-free from action conflicts. {@link
- * #filterActionConflictsForTopLevelArtifacts} must be called after this to free memory coming
- * from this call.
- *
- * <p>This method is only called in keep-going mode, since otherwise any known action conflicts
- * will immediately fail the build.
+ * predicate are known to be transitively error-free from action conflicts or other analysis
+ * failures. {@link #resetActionConflictsStoredInSkyframe} must be called after this to free
+ * memory coming from this call.
*/
- Predicate<ActionLookupKey> filterActionConflictsForConfiguredTargetsAndAspects(
+ TopLevelActionConflictReport filterActionConflictsForConfiguredTargetsAndAspects(
ExtendedEventHandler eventHandler,
Iterable<ActionLookupKey> keys,
ImmutableMap<ActionAnalysisMetadata, ArtifactConflictFinder.ConflictException>
@@ -2458,11 +2456,57 @@
// of action conflict is rare.
memoizingEvaluator.delete(
SkyFunctionName.functionIs(SkyFunctions.TOP_LEVEL_ACTION_LOOKUP_CONFLICT_FINDING));
+ return new TopLevelActionConflictReport(result, topLevelArtifactContext);
+ }
- return k ->
- result.get(
- TopLevelActionLookupConflictFindingFunction.Key.create(k, topLevelArtifactContext))
- != null;
+ /**
+ * Encapsulation of the result of #filterActionConflictsForConfiguredTargetsAndAspects() allowing
+ * callers to determine which top-level keys did not have analysis errors and retrieve the
+ * ConflictException for those that keys that specifically have conflicts.
+ */
+ static final class TopLevelActionConflictReport {
+
+ private final EvaluationResult<ActionLookupConflictFindingValue> result;
+ private final TopLevelArtifactContext topLevelArtifactContext;
+
+ TopLevelActionConflictReport(
+ EvaluationResult<ActionLookupConflictFindingValue> result,
+ TopLevelArtifactContext topLevelArtifactContext) {
+ this.result = result;
+ this.topLevelArtifactContext = topLevelArtifactContext;
+ }
+
+ boolean isErrorFree(ActionLookupKey k) {
+ return result.get(
+ TopLevelActionLookupConflictFindingFunction.Key.create(k, topLevelArtifactContext))
+ != null;
+ }
+
+ /**
+ * Get the ConflictException produced for the given ActionLookupKey. Will throw if the given key
+ * {@link #isErrorFree is error-free}.
+ */
+ Optional<ConflictException> getConflictException(ActionLookupKey k) {
+ ErrorInfo errorInfo =
+ result.getError(
+ TopLevelActionLookupConflictFindingFunction.Key.create(k, topLevelArtifactContext));
+ Exception e = errorInfo.getException();
+ return Optional.ofNullable(e instanceof ConflictException ? (ConflictException) e : null);
+ }
+ }
+
+ /**
+ * Clears all action conflicts stored in skyframe that were discovered by a call to {@link
+ * #filterActionConflictsForConfiguredTargetsAndAspects}.
+ *
+ * <p>This function must be called after a call to {@link
+ * #filterActionConflictsForConfiguredTargetsAndAspects}, either directly (in the case of
+ * no-keep_going evaluations) or indirectly by {@link #filterActionConflictsForTopLevelArtifacts}
+ * in keep_going evaluations.
+ */
+ public void resetActionConflictsStoredInSkyframe() {
+ memoizingEvaluator.delete(
+ SkyFunctionName.functionIs(SkyFunctions.ACTION_LOOKUP_CONFLICT_FINDING));
}
/**
@@ -2487,8 +2531,7 @@
eventHandler);
// Remove remaining action-conflict detection values immediately for memory efficiency.
- memoizingEvaluator.delete(
- SkyFunctionName.functionIs(SkyFunctions.ACTION_LOOKUP_CONFLICT_FINDING));
+ resetActionConflictsStoredInSkyframe();
return a -> result.get(ActionLookupConflictFindingValue.key(a)) != null;
}