Move the crash terminating callback to `SerializationContext` instead of passing it in.

I'm guessing there was previously a circular dependency issue that prevented `SerializationContext` from depending on `BugReport`.

PiperOrigin-RevId: 419890256
diff --git a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecWithStore.java b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecWithStore.java
index 2f62287..f903906 100644
--- a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecWithStore.java
+++ b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodecWithStore.java
@@ -15,10 +15,8 @@
 
 import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.Caffeine;
-import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
-import com.google.devtools.build.lib.bugreport.BugReport;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetStore.FingerprintComputationResult;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
@@ -29,7 +27,6 @@
 import com.google.protobuf.CodedOutputStream;
 import java.io.IOException;
 import java.util.concurrent.ExecutionException;
-import javax.annotation.Nullable;
 
 /** Codec for {@link NestedSet} that uses the {@link NestedSetStore}. */
 public class NestedSetCodecWithStore implements ObjectCodec<NestedSet<?>> {
@@ -40,19 +37,6 @@
     NONLEAF // more than one element; size > 1, depth > 1
   }
 
-  private static final FutureCallback<Void> CRASH_TERMINATING_CALLBACK =
-      new FutureCallback<Void>() {
-        @Override
-        public void onSuccess(@Nullable Void result) {
-          // Do nothing.
-        }
-
-        @Override
-        public void onFailure(Throwable t) {
-          BugReport.handleCrash(t);
-        }
-      };
-
   private final NestedSetStore nestedSetStore;
 
   /**
@@ -101,8 +85,7 @@
       codedOut.writeInt32NoTag(obj.getApproxDepth());
       FingerprintComputationResult fingerprintComputationResult =
           nestedSetStore.computeFingerprintAndStore((Object[]) obj.getChildren(), context);
-      context.addFutureToBlockWritingOn(
-          fingerprintComputationResult.writeStatus(), CRASH_TERMINATING_CALLBACK);
+      context.addFutureToBlockWritingOn(fingerprintComputationResult.writeStatus());
       codedOut.writeByteArrayNoTag(fingerprintComputationResult.fingerprint().toByteArray());
     }
     interner.put(new EqualsWrapper(obj), obj);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD
index 2dbaf1e..6848694 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/BUILD
@@ -27,6 +27,7 @@
     ),
     deps = [
         ":codec-scanning-constants",
+        "//src/main/java/com/google/devtools/build/lib/bugreport",
         "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec:registered-singleton",
         "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec:serialization-constant",
         "//src/main/java/com/google/devtools/build/lib/unsafe:string",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
index 9da0ac3..e06e941 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
@@ -16,6 +16,7 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ClassToInstanceMap;
@@ -25,7 +26,7 @@
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
+import com.google.devtools.build.lib.bugreport.BugReport;
 import com.google.devtools.build.lib.skyframe.serialization.Memoizer.Serializer;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec.MemoizationStrategy;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException.NoCodecException;
@@ -181,19 +182,31 @@
         allowFuturesToBlockWritingOn);
   }
 
+  private static final FutureCallback<Object> CRASH_TERMINATING_CALLBACK =
+      new FutureCallback<Object>() {
+        @Override
+        public void onSuccess(@Nullable Object result) {}
+
+        @Override
+        public void onFailure(Throwable t) {
+          BugReport.handleCrash(t);
+        }
+      };
+
   /**
-   * Register a {@link ListenableFuture} that must complete successfully before the serialized bytes
-   * generated using this context can be written remotely. Failure of the future implies a bug or
-   * other unrecoverable error that should crash this JVM, which is done by invoking {@link
-   * FutureCallback#onFailure} on the given {@code crashTerminatingCallback}.
+   * Registers a {@link ListenableFuture} that must complete successfully before the serialized
+   * bytes generated using this context can be written remotely.
+   *
+   * <p>Failure of the given future implies a bug or other unrecoverable error that crashes this
+   * JVM, which this method configures by attaching a callback that calls {@link
+   * BugReport#handleCrash(Throwable, String...)} in {@link FutureCallback#onFailure}.
    */
-  public void addFutureToBlockWritingOn(
-      ListenableFuture<Void> future, FutureCallback<Void> crashTerminatingCallback) {
+  public void addFutureToBlockWritingOn(ListenableFuture<Void> future) {
     checkState(allowFuturesToBlockWritingOn, "This context cannot block on a future");
     if (futuresToBlockWritingOn == null) {
       futuresToBlockWritingOn = new ArrayList<>();
     }
-    Futures.addCallback(future, crashTerminatingCallback, MoreExecutors.directExecutor());
+    Futures.addCallback(future, CRASH_TERMINATING_CALLBACK, directExecutor());
     futuresToBlockWritingOn.add(future);
   }
 
@@ -204,8 +217,7 @@
   @Nullable
   public ListenableFuture<Void> createFutureToBlockWritingOn() {
     return futuresToBlockWritingOn != null
-        ? Futures.whenAllSucceed(futuresToBlockWritingOn)
-            .call(() -> null, MoreExecutors.directExecutor())
+        ? Futures.whenAllSucceed(futuresToBlockWritingOn).call(() -> null, directExecutor())
         : null;
   }