Add incompatible_disallow_rule_execution_platform_constraints_allowed flag.

Part of #8136 and #8134.

RELNOTES: Adds
incompatible_disallow_rule_execution_platform_constraints_allowed, which
disallows the use of the "execution_platform_constraints_allowed"
attribute when defining new rules.

Closes #8145.

PiperOrigin-RevId: 245405049
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index 1c23c1e..d465c70 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -286,7 +286,7 @@
       FuncallExpression ast,
       Environment funcallEnv,
       StarlarkContext context)
-      throws EvalException, ConversionException {
+      throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(funcallEnv, "rule", ast.getLocation());
 
     BazelStarlarkContext bazelContext = (BazelStarlarkContext) context;
@@ -398,8 +398,11 @@
               execCompatibleWith.getContents(String.class, "exec_compatile_with"),
               ast.getLocation()));
     }
+
     if (executionPlatformConstraintsAllowed) {
       builder.executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_TARGET);
+    } else {
+      builder.executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_RULE);
     }
 
     return new SkylarkRuleFunction(builder, type, attributes, ast.getLocation());
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
index 24a1699..deb1d5f 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
@@ -330,6 +330,20 @@
   public boolean incompatibleDisallowNativeInBuildFile;
 
   @Option(
+      name = "incompatible_disallow_rule_execution_platform_constraints_allowed",
+      defaultValue = "False",
+      documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS,
+      effectTags = {OptionEffectTag.BUILD_FILE_SEMANTICS},
+      metadataTags = {
+        OptionMetadataTag.INCOMPATIBLE_CHANGE,
+        OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
+      },
+      help =
+          "If set to true, disallow the use of the execution_platform_constraints_allowed "
+              + "attribute on rule().")
+  public boolean incompatibleDisallowRuleExecutionPlatformConstraintsAllowed;
+
+  @Option(
       name = "incompatible_string_join_requires_strings",
       defaultValue = "false",
       documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS,
@@ -623,6 +637,8 @@
         .incompatibleDisallowOldOctalNotation(incompatibleDisallowOldOctalNotation)
         .incompatibleDisallowOldStyleArgsAdd(incompatibleDisallowOldStyleArgsAdd)
         .incompatibleDisallowStructProviderSyntax(incompatibleDisallowStructProviderSyntax)
+        .incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(
+            incompatibleDisallowRuleExecutionPlatformConstraintsAllowed)
         .incompatibleExpandDirectories(incompatibleExpandDirectories)
         .incompatibleNewActionsApi(incompatibleNewActionsApi)
         .incompatibleNoAttrLicense(incompatibleNoAttrLicense)
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
index 247300a..a35c698 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
@@ -282,12 +282,17 @@
             named = true,
             positional = false,
             defaultValue = "False",
+            disableWithFlag =
+                FlagIdentifier.INCOMPATIBLE_DISALLOW_RULE_EXECUTION_PLATFORM_CONSTRAINTS_ALLOWED,
+            valueWhenDisabled = "True",
             doc =
                 "If true, a special attribute named <code>exec_compatible_with</code> of "
                     + "label-list type is added, which must not already exist in "
                     + "<code>attrs</code>. Targets may use this attribute to specify additional "
                     + "constraints on the execution platform beyond those given in the "
-                    + "<code>exec_compatible_with</code> argument to <code>rule()</code>."),
+                    + "<code>exec_compatible_with</code> argument to <code>rule()</code>. "
+                    + "This will be deprecated and removed in the near future, and all rules will "
+                    + "be able to use <code>exec_compatible_with</code>."),
         @Param(
             name = "exec_compatible_with",
             type = SkylarkList.class,
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
index bc025a3..7aa8453 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
@@ -54,6 +54,8 @@
     INCOMPATIBLE_NO_TARGET_OUTPUT_GROUP(StarlarkSemantics::incompatibleNoTargetOutputGroup),
     INCOMPATIBLE_NO_ATTR_LICENSE(StarlarkSemantics::incompatibleNoAttrLicense),
     INCOMPATIBLE_OBJC_FRAMEWORK_CLEANUP(StarlarkSemantics::incompatibleObjcFrameworkCleanup),
+    INCOMPATIBLE_DISALLOW_RULE_EXECUTION_PLATFORM_CONSTRAINTS_ALLOWED(
+        StarlarkSemantics::incompatibleDisallowRuleExecutionPlatformConstraintsAllowed),
     NONE(null);
 
     // Using a Function here makes the enum definitions far cleaner, and, since this is
@@ -162,6 +164,8 @@
 
   public abstract boolean incompatibleDisallowOldStyleArgsAdd();
 
+  public abstract boolean incompatibleDisallowRuleExecutionPlatformConstraintsAllowed();
+
   public abstract boolean incompatibleDisallowStructProviderSyntax();
 
   public abstract boolean incompatibleExpandDirectories();
@@ -234,6 +238,7 @@
           .incompatibleDisallowNativeInBuildFile(false)
           .incompatibleDisallowOldOctalNotation(false)
           .incompatibleDisallowOldStyleArgsAdd(true)
+          .incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(false)
           .incompatibleDisallowStructProviderSyntax(false)
           .incompatibleExpandDirectories(true)
           .incompatibleNewActionsApi(false)
@@ -304,6 +309,9 @@
 
     public abstract Builder incompatibleDisallowNativeInBuildFile(boolean value);
 
+    public abstract Builder incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(
+        boolean value);
+
     public abstract Builder incompatibleDisallowStructProviderSyntax(boolean value);
 
     public abstract Builder incompatibleExpandDirectories(boolean value);
diff --git a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
index 7e2df6f..7b5c18a 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
@@ -148,6 +148,7 @@
         "--incompatible_disallow_old_octal_notation=" + rand.nextBoolean(),
         "--incompatible_disallow_old_style_args_add=" + rand.nextBoolean(),
         "--incompatible_disallow_struct_provider_syntax=" + rand.nextBoolean(),
+        "--incompatible_disallow_rule_execution_platform_constraints_allowed=" + rand.nextBoolean(),
         "--incompatible_expand_directories=" + rand.nextBoolean(),
         "--incompatible_new_actions_api=" + rand.nextBoolean(),
         "--incompatible_no_attr_license=" + rand.nextBoolean(),
@@ -199,6 +200,7 @@
         .incompatibleDisallowOldOctalNotation(rand.nextBoolean())
         .incompatibleDisallowOldStyleArgsAdd(rand.nextBoolean())
         .incompatibleDisallowStructProviderSyntax(rand.nextBoolean())
+        .incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(rand.nextBoolean())
         .incompatibleExpandDirectories(rand.nextBoolean())
         .incompatibleNewActionsApi(rand.nextBoolean())
         .incompatibleNoAttrLicense(rand.nextBoolean())
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index 8c70a04..7bda34c 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -137,7 +137,7 @@
   }
 
   private void registerDummyUserDefinedFunction() throws Exception {
-    eval("def impl():\n" + "  return 0\n");
+    eval("def impl():", "  pass");
   }
 
   @Test
@@ -1739,7 +1739,14 @@
   }
 
   @Test
-  public void testTargetsCanAddExecutionPlatformConstraints() throws Exception {
+  public void testTargetsCanAddExecutionPlatformConstraints_enabled() throws Exception {
+    StarlarkSemantics semantics =
+        StarlarkSemantics.DEFAULT_SEMANTICS.toBuilder()
+            .incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(false)
+            .build();
+    ev = createEvaluationTestCase(semantics);
+    ev.initialize();
+
     registerDummyUserDefinedFunction();
     scratch.file("test/BUILD", "toolchain_type(name = 'my_toolchain_type')");
     evalAndExport(
@@ -1753,6 +1760,47 @@
   }
 
   @Test
+  public void testTargetsCanAddExecutionPlatformConstraints_notEnabled() throws Exception {
+    StarlarkSemantics semantics =
+        StarlarkSemantics.DEFAULT_SEMANTICS.toBuilder()
+            .incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(false)
+            .build();
+    ev = createEvaluationTestCase(semantics);
+    ev.initialize();
+
+    registerDummyUserDefinedFunction();
+    scratch.file("test/BUILD", "toolchain_type(name = 'my_toolchain_type')");
+    evalAndExport(
+        "r1 = rule(impl, ",
+        "  toolchains=['//test:my_toolchain_type'],",
+        "  execution_platform_constraints_allowed=False,",
+        ")");
+    RuleClass c = ((SkylarkRuleFunction) lookup("r1")).getRuleClass();
+    assertThat(c.executionPlatformConstraintsAllowed())
+        .isEqualTo(ExecutionPlatformConstraintsAllowed.PER_RULE);
+  }
+
+  @Test
+  public void testTargetsCanAddExecutionPlatformConstraints_disallowed() throws Exception {
+    StarlarkSemantics semantics =
+        StarlarkSemantics.DEFAULT_SEMANTICS.toBuilder()
+            .incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(true)
+            .build();
+    ev = createEvaluationTestCase(semantics);
+    ev.setFailFast(false);
+    ev.initialize();
+
+    registerDummyUserDefinedFunction();
+    scratch.file("test/BUILD", "toolchain_type(name = 'my_toolchain_type')");
+    evalAndExport(
+        "r1 = rule(impl, ",
+        "  toolchains=['//test:my_toolchain_type'],",
+        "  execution_platform_constraints_allowed=True,",
+        ")");
+    ev.assertContainsError("parameter 'execution_platform_constraints_allowed' is deprecated");
+  }
+
+  @Test
   public void testRuleFunctionReturnsNone() throws Exception {
     scratch.file("test/rule.bzl",
         "def _impl(ctx):",