diff --git a/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java index 70e72d3fd3d0a0..3c47036b901008 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java +++ b/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java @@ -215,7 +215,7 @@ private ConfigKeyAndValue resolveSelector(String attributeName, Selector< } } - if (matchingConditions.size() > 1) { + if (matchingConditions.values().stream().map(s -> s.value).distinct().count() > 1) { throw new ValidationException( "Illegal ambiguous match on configurable attribute \"" + attributeName @@ -223,9 +223,10 @@ private ConfigKeyAndValue resolveSelector(String attributeName, Selector< + getLabel() + ":\n" + Joiner.on("\n").join(matchingConditions.keySet()) - + "\nMultiple matches are not allowed unless one is unambiguously more specialized."); - } else if (matchingConditions.size() == 1) { - return Iterables.getOnlyElement(matchingConditions.values()); + + "\nMultiple matches are not allowed unless one is unambiguously " + + "more specialized or they resolve to the same value."); + } else if (matchingConditions.size() > 0) { + return Iterables.getFirst(matchingConditions.values(), null); } // If nothing matched, choose the default condition. diff --git a/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java b/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java index 3a174ad6c09eae..4cf678fee49c56 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/ConfigurableAttributesTest.java @@ -635,7 +635,8 @@ public void multipleMatches() throws Exception { "Illegal ambiguous match on configurable attribute \"srcs\" in //a:gen:\n" + "//conditions:dup1\n" + "//conditions:dup2\n" - + "Multiple matches are not allowed unless one is unambiguously more specialized."); + + "Multiple matches are not allowed unless one is unambiguously more specialized " + + "or they resolve to the same value."); } /** @@ -681,6 +682,37 @@ public void multipleMatchesConditionAndSubcondition() throws Exception { "bin java/a/libgeneric.jar", "bin java/a/libprecise.jar")); } + /** + * Tests that multiple matches are allowed for conditions where the value is the same. + */ + @Test + public void multipleMatchesSameValue() throws Exception { + reporter.removeHandler(failFastHandler); // Expect errors. + scratch.file("conditions/BUILD", + "config_setting(", + " name = 'dup1',", + " values = {'compilation_mode': 'opt'})", + "config_setting(", + " name = 'dup2',", + " values = {'define': 'foo=bar'})"); + scratch.file("a/BUILD", + "genrule(", + " name = 'gen',", + " cmd = '',", + " outs = ['gen.out'],", + " srcs = select({", + " '//conditions:dup1': ['a.in'],", + " '//conditions:dup2': ['a.in'],", + " '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [':default.in'],", + " }))"); + checkRule( + "//a:gen", + "srcs", + ImmutableList.of("-c", "opt", "--define", "foo=bar"), + /*expected:*/ ImmutableList.of("src a/a.in"), + /*not expected:*/ ImmutableList.of("src a/default.in")); + } + /** * Tests that when multiple conditions match but one condition is more specialized than the * others, it is chosen and there is no error.