From 480f8fbdec3cbd5070385f157bc50b4a2e63039d Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Tue, 7 Jan 2025 19:49:56 +0100 Subject: [PATCH] Mark built-in providers as hashable Built-in providers always have an immutable `hashCode`. Making them hashable makes it easier to deduplicate a list of providers, which is sometimes required as the list of provider instances returned by a rule must not contain two instances for a given provider. --- .../devtools/build/lib/packages/BuiltinProvider.java | 5 +++++ .../starlark/StarlarkRuleImplementationFunctionsTest.java | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuiltinProvider.java b/src/main/java/com/google/devtools/build/lib/packages/BuiltinProvider.java index 26821b0bafecbd..8ba6b4d6a88273 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/BuiltinProvider.java +++ b/src/main/java/com/google/devtools/build/lib/packages/BuiltinProvider.java @@ -65,6 +65,11 @@ public final int hashCode() { return getClass().hashCode(); } + @Override + public void checkHashable() { + // The hash code is based on the class, so it is hashable. + } + @Override public boolean isExported() { return true; diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java index a2c537ba939f38..ee22b7454e12b6 100644 --- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java +++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleImplementationFunctionsTest.java @@ -78,6 +78,7 @@ import java.util.regex.Pattern; import net.starlark.java.annot.Param; import net.starlark.java.annot.StarlarkMethod; +import net.starlark.java.eval.Dict; import net.starlark.java.eval.EvalException; import net.starlark.java.eval.Mutability; import net.starlark.java.eval.Printer; @@ -4025,4 +4026,11 @@ def _impl(ctx): assertThat(a2.getRoot().getExecPathString()) .matches(getRelativeOutputPath() + "/[\\w\\-]+\\-exec/bin"); } + + @Test + public void testHashableProviders() throws Exception { + ev.execAndExport("p = provider()"); + Dict dict = (Dict) ev.eval("{k: None for k in [DefaultInfo, p, DefaultInfo, p]}"); + assertThat(dict.size()).isEqualTo(2); + } }