Rollback of commit 0218320f1316b4d25e35abaaa80206237468824d.

*** Reason for rollback ***

Breaks skylark macros that call skylark rules that declare an 'args'
attribute.

--
MOS_MIGRATED_REVID=101118137
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 d051892..67cc935 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
@@ -751,19 +751,9 @@
 
     /**
      * 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) {
-      String name = attribute.getName();
-      boolean override = attributes.containsKey(name);
-      // Attributes may be overridden in the future, thus we keep the code for overriding right
-      // now.
-      Preconditions.checkArgument(
-          !override, "There is already a built-in attribute '%s' which cannot be overridden", name);
-
-      if (override) {
+      if (attributes.containsKey(attribute.getName())) {
         overrideAttribute(attribute);
       } else {
         addAttribute(attribute);
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 fc4c222..2f12950 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
@@ -160,10 +160,8 @@
           .build();
 
   /**
-   * Translates Skylark attribute names to native names.
-   *
-   * <p> In native code, private values start with "$".In Skylark, private values start with "_",
-   * because of the grammar.
+   * In native code, private values start with $.
+   * In Skylark, private values start with _, because of the grammar.
    */
   private static String attributeToNative(String oldName, Location loc, boolean isLateBound)
       throws EvalException {
@@ -230,76 +228,68 @@
            doc = "List of names of configuration fragments that the rule requires.")},
       useAst = true, useEnvironment = true)
   private static final BuiltinFunction rule = new BuiltinFunction("rule") {
-    @SuppressWarnings({"rawtypes", "unchecked"}) // castMap produces
-    // an Attribute.Builder instead of a Attribute.Builder<?> but it's OK.
-    public BaseFunction invoke(BaseFunction implementation, Boolean test, Object attrs,
-        Object implicitOutputs, Boolean executable, Boolean outputToGenfiles, SkylarkList fragments,
-        FuncallExpression ast, Environment funcallEnv) throws EvalException, ConversionException {
-      Preconditions.checkState(funcallEnv instanceof SkylarkEnvironment);
-      RuleClassType type = test ? RuleClassType.TEST : RuleClassType.NORMAL;
+      @SuppressWarnings({"rawtypes", "unchecked"}) // castMap produces
+      // an Attribute.Builder instead of a Attribute.Builder<?> but it's OK.
+      public BaseFunction invoke(BaseFunction implementation, Boolean test, Object attrs,
+          Object implicitOutputs, Boolean executable, Boolean outputToGenfiles,
+          SkylarkList fragments, FuncallExpression ast, Environment funcallEnv)
+          throws EvalException, ConversionException {
 
-      // We'll set the name later, pass the empty string for now.
-      RuleClass.Builder builder =
-          test ? new RuleClass.Builder("", type, true, testBaseRule)
-               : new RuleClass.Builder("", type, true, baseRule);
+        Preconditions.checkState(funcallEnv instanceof SkylarkEnvironment);
+        RuleClassType type = test ? RuleClassType.TEST : RuleClassType.NORMAL;
 
-      if (attrs != Environment.NONE) {
-        for (Map.Entry<String, Attribute.Builder> attr :
-            castMap(attrs, String.class, Attribute.Builder.class, "attrs").entrySet()) {
-          Attribute.Builder<?> attrBuilder = (Attribute.Builder<?>) attr.getValue();
-          String attrName =
-              attributeToNative(attr.getKey(), ast.getLocation(), attrBuilder.hasLateBoundValue());
-          addAttribute(builder, attrBuilder.build(attrName));
+        // We'll set the name later, pass the empty string for now.
+        RuleClass.Builder builder = test
+            ? new RuleClass.Builder("", type, true, testBaseRule)
+            : new RuleClass.Builder("", type, true, baseRule);
+
+        if (attrs != Environment.NONE) {
+          for (Map.Entry<String, Attribute.Builder> attr : castMap(
+              attrs, String.class, Attribute.Builder.class, "attrs").entrySet()) {
+            Attribute.Builder<?> attrBuilder = (Attribute.Builder<?>) attr.getValue();
+            String attrName = attributeToNative(attr.getKey(), ast.getLocation(),
+                attrBuilder.hasLateBoundValue());
+            builder.addOrOverrideAttribute(attrBuilder.build(attrName));
+          }
         }
-      }
-      if (executable || test) {
-        addAttribute(
-            builder,
-            attr("$is_executable", BOOLEAN)
-                .value(true)
-                .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
-                .build());
-        builder.setOutputsDefaultExecutable();
-      }
-
-      if (implicitOutputs != Environment.NONE) {
-        if (implicitOutputs instanceof BaseFunction) {
-          BaseFunction func = (BaseFunction) implicitOutputs;
-          final SkylarkCallbackFunction callback =
-              new SkylarkCallbackFunction(func, ast, (SkylarkEnvironment) funcallEnv);
-          builder.setImplicitOutputsFunction(
-              new SkylarkImplicitOutputsFunctionWithCallback(callback, ast.getLocation()));
-        } else {
-          builder.setImplicitOutputsFunction(
-              new SkylarkImplicitOutputsFunctionWithMap(ImmutableMap.copyOf(castMap(implicitOutputs,
-                  String.class, String.class, "implicit outputs of the rule class"))));
+        if (executable || test) {
+          builder.addOrOverrideAttribute(
+              attr("$is_executable", BOOLEAN).value(true)
+              .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
+              .build());
+          builder.setOutputsDefaultExecutable();
         }
-      }
 
-      if (outputToGenfiles) {
-        builder.setOutputToGenfiles();
-      }
+        if (implicitOutputs != Environment.NONE) {
+          if (implicitOutputs instanceof BaseFunction) {
+            BaseFunction func = (BaseFunction) implicitOutputs;
+            final SkylarkCallbackFunction callback =
+                new SkylarkCallbackFunction(func, ast, (SkylarkEnvironment) funcallEnv);
+            builder.setImplicitOutputsFunction(
+                new SkylarkImplicitOutputsFunctionWithCallback(callback, ast.getLocation()));
+          } else {
+            builder.setImplicitOutputsFunction(new SkylarkImplicitOutputsFunctionWithMap(
+                ImmutableMap.copyOf(castMap(implicitOutputs, String.class, String.class,
+                        "implicit outputs of the rule class"))));
+            }
+        }
 
-      if (!fragments.isEmpty()) {
-        builder.requiresConfigurationFragments(
-            new SkylarkModuleNameResolver(),
-            Iterables.toArray(castList(fragments, String.class), String.class));
-      }
+        if (outputToGenfiles) {
+          builder.setOutputToGenfiles();
+        }
 
-      builder.setConfiguredTargetFunction(implementation);
-      builder.setRuleDefinitionEnvironment(
-          ((SkylarkEnvironment) funcallEnv).getGlobalEnvironment());
-      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);
-      }
-    }
-  };
+        if (!fragments.isEmpty()) {
+          builder.requiresConfigurationFragments(
+              new SkylarkModuleNameResolver(),
+              Iterables.toArray(castList(fragments, String.class), String.class));
+        }
+
+        builder.setConfiguredTargetFunction(implementation);
+        builder.setRuleDefinitionEnvironment(
+            ((SkylarkEnvironment) funcallEnv).getGlobalEnvironment());
+        return new RuleFunction(builder, type);
+        }
+      };
 
   // This class is needed for testing
   static final class RuleFunction extends BaseFunction {