Skylark rules can no longer overwrite built-in attributes.

--
MOS_MIGRATED_REVID=103931317
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 8429617..9e84f0b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -770,13 +770,16 @@
 
     /**
      * Adds or overrides the attribute in the rule class. Meant for Skylark usage.
+     *
+     * @throws IllegalArgumentException if the attribute overrides an existing attribute (will be
+     * legal in the future).
      */
     public void addOrOverrideAttribute(Attribute attribute) {
-      if (attributes.containsKey(attribute.getName())) {
-        overrideAttribute(attribute);
-      } else {
-        addAttribute(attribute);
-      }
+      String name = attribute.getName();
+      // Attributes may be overridden in the future.
+      Preconditions.checkArgument(!attributes.containsKey(name),
+          "There is already a built-in attribute '%s' which cannot be overridden", name);
+      addAttribute(attribute);
     }
 
     /** True if the rule class contains an attribute named {@code name}. */
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index f2a3733..88f61ec 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -264,11 +264,12 @@
           Attribute.Builder<?> attrBuilder = (Attribute.Builder<?>) attr.getValue();
           String attrName =
               attributeToNative(attr.getKey(), ast.getLocation(), attrBuilder.hasLateBoundValue());
-          builder.addOrOverrideAttribute(attrBuilder.build(attrName));
+          addAttribute(builder, attrBuilder.build(attrName));
         }
       }
       if (executable || test) {
-        builder.addOrOverrideAttribute(
+        addAttribute(
+            builder,
             attr("$is_executable", BOOLEAN)
                 .value(true)
                 .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
@@ -297,12 +298,19 @@
       }
 
       registerRequiredFragments(fragments, hostFragments, builder);
-
       builder.setConfiguredTargetFunction(implementation);
       builder.setRuleDefinitionEnvironment(funcallEnv);
       return new RuleFunction(builder, type);
     }
 
+    private void addAttribute(RuleClass.Builder builder, Attribute attribute) throws EvalException {
+      try {
+        builder.addOrOverrideAttribute(attribute);
+      } catch (IllegalArgumentException ex) {
+        throw new EvalException(location, ex);
+      }
+    }
+
     private void registerRequiredFragments(
         SkylarkList fragments, SkylarkList hostFragments, RuleClass.Builder builder) {
       Map<ConfigurationTransition, ImmutableSet<String>> map = new HashMap<>();
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 c7ea692..cce9b97 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
@@ -66,6 +66,13 @@
         ")");
   }
 
+  public void testCannotOverrideBuiltInAttribute() throws Exception {
+    checkEvalError(
+        "There is already a built-in attribute 'tags' which cannot be overridden",
+        "def impl(ctx): return",
+        "r = rule(impl, attrs = {'tags': attr.string_list()})");
+  }
+
   public void testImplicitArgsAttribute() throws Exception {
     eval(
         "def _impl(ctx):",