Correctly merge empty runfiles w/ non-empty runfiles

Since an empty runfiles object doesn't have a valid suffix, we cannot create a correct Runfiles.Builder from it.

PiperOrigin-RevId: 233641175
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java b/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java
index 4ca156a..50a325f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java
@@ -1165,10 +1165,16 @@
 
   @Override
   public Runfiles merge(RunfilesApi other) {
-    Runfiles.Builder builder = new Runfiles.Builder(suffix, false);
-    builder.merge(this);
-    builder.merge((Runfiles) other);
-    return builder.build();
+    Runfiles o = (Runfiles) other;
+    if (isEmpty()) {
+      // This is not just a memory / performance optimization. The Builder requires a valid suffix,
+      // but the {@code Runfiles.EMPTY} singleton has an invalid one, which must not be used to
+      // construct a Runfiles.Builder.
+      return o;
+    } else if (o.isEmpty()) {
+      return this;
+    }
+    return new Runfiles.Builder(suffix, false).merge(this).merge(o).build();
   }
 
   /**
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java b/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java
index 5a7cb89..26a6dbc 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/RunfilesTest.java
@@ -411,6 +411,15 @@
   }
 
   @Test
+  public void testMergeEmptyWithNonEmpty() {
+    ArtifactRoot root = ArtifactRoot.asSourceRoot(Root.fromPath(scratch.resolve("/workspace")));
+    Artifact artifactA = new Artifact(PathFragment.create("a/target"), root);
+    Runfiles runfilesB = new Runfiles.Builder("TESTING").addArtifact(artifactA).build();
+    assertThat(Runfiles.EMPTY.merge(runfilesB)).isSameAs(runfilesB);
+    assertThat(runfilesB.merge(Runfiles.EMPTY)).isSameAs(runfilesB);
+  }
+
+  @Test
   public void testOnlyExtraMiddlemenNotConsideredEmpty() {
     ArtifactRoot root =
         ArtifactRoot.middlemanRoot(scratch.resolve("execroot"), scratch.resolve("execroot/out"));