diff --git a/src/main/java/com/google/devtools/build/lib/collect/nestedset/Depset.java b/src/main/java/com/google/devtools/build/lib/collect/nestedset/Depset.java index 332092a04e0b39..6bf3cd504a43df 100644 --- a/src/main/java/com/google/devtools/build/lib/collect/nestedset/Depset.java +++ b/src/main/java/com/google/devtools/build/lib/collect/nestedset/Depset.java @@ -392,7 +392,16 @@ static Depset fromDirectAndTransitive( if (builder.isEmpty()) { return builder.getOrder().emptyDepset(); } - return new Depset(type, builder.build()); + NestedSet set = builder.build(); + // If the nested set was optimized to one of the transitive elements, reuse the corresponding + // depset. + for (Depset x : transitive) { + if (x.getSet() == set) { + return x; + } + } + + return new Depset(type, set); } /** An exception thrown when validation fails on the type of elements of a nested set. */ diff --git a/src/test/java/com/google/devtools/build/lib/collect/nestedset/DepsetTest.java b/src/test/java/com/google/devtools/build/lib/collect/nestedset/DepsetTest.java index a2139858beb8f6..3905f90951a970 100644 --- a/src/test/java/com/google/devtools/build/lib/collect/nestedset/DepsetTest.java +++ b/src/test/java/com/google/devtools/build/lib/collect/nestedset/DepsetTest.java @@ -417,4 +417,17 @@ public void testEmptyDepsetInternedPerOrder() throws Exception { assertThat(ev.lookup("stable1")).isNotSameInstanceAs(ev.lookup("preorder1")); assertThat(ev.lookup("stable2")).isNotSameInstanceAs(ev.lookup("preorder2")); } + + @Test + public void testSingleNonEmptyTransitiveAndNoDirectsUnwrapped() throws Exception { + ev.exec( + "inner = depset([1, 2, 3])", "outer = depset(transitive = [depset(), inner, depset()])"); + assertThat(ev.lookup("outer")).isSameInstanceAs(ev.lookup("inner")); + } + + @Test + public void testSingleNonEmptyTransitiveAndMatchingDirectUnwrapped() throws Exception { + ev.exec("inner = depset([1])", "outer = depset([1], transitive = [depset(), inner, depset()])"); + assertThat(ev.lookup("outer")).isSameInstanceAs(ev.lookup("inner")); + } }