Allow fail() function to accept any argument

e.g.  fail(3)

This is mostly useful for debugging (typical error messages will continue
to use strings).

--
MOS_MIGRATED_REVID=123008379
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index f576b75..0f25172 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -2151,30 +2151,46 @@
     }
   };
 
-  @SkylarkSignature(name = "fail",
-      doc = "Raises an error that cannot be intercepted. It can be used anywhere, "
-          + "both in the loading phase and in the analysis phase.",
-      returnType = Runtime.NoneType.class,
-      mandatoryPositionals = {
-        @Param(name = "msg", type = String.class, doc = "Error message to display for the user")},
-      optionalPositionals = {
-        @Param(name = "attr", type = String.class, noneable = true,
-            defaultValue = "None",
-            doc = "The name of the attribute that caused the error. This is used only for "
-               + "error reporting.")},
-      useLocation = true)
-  private static final BuiltinFunction fail = new BuiltinFunction("fail") {
-    public Runtime.NoneType invoke(String msg, Object attr,
-        Location loc) throws EvalException, ConversionException {
-      if (attr != Runtime.NONE) {
-        msg = String.format("attribute %s: %s", attr, msg);
-      }
-      throw new EvalException(loc, msg);
-    }
-  };
+  @SkylarkSignature(
+    name = "fail",
+    doc =
+        "Raises an error that cannot be intercepted. It can be used anywhere, "
+            + "both in the loading phase and in the analysis phase.",
+    returnType = Runtime.NoneType.class,
+    mandatoryPositionals = {
+      @Param(
+        name = "msg",
+        type = Object.class,
+        doc = "Error to display for the user. The object is converted to a string."
+      )
+    },
+    optionalPositionals = {
+      @Param(
+        name = "attr",
+        type = String.class,
+        noneable = true,
+        defaultValue = "None",
+        doc =
+            "The name of the attribute that caused the error. This is used only for "
+                + "error reporting."
+      )
+    },
+    useLocation = true
+  )
+  private static final BuiltinFunction fail =
+      new BuiltinFunction("fail") {
+        public Runtime.NoneType invoke(Object msg, Object attr, Location loc)
+            throws EvalException, ConversionException {
+          String str = Printer.str(msg);
+          if (attr != Runtime.NONE) {
+            str = String.format("attribute %s: %s", attr, str);
+          }
+          throw new EvalException(loc, str);
+        }
+      };
 
   @SkylarkSignature(name = "print", returnType = Runtime.NoneType.class,
-      doc = "Prints a warning with the text <code>msg</code>. It can be used for debugging or "
+      doc = "Prints <code>args</code> as a warning. It can be used for debugging or "
           + "for transition (before changing to an error). In other cases, warnings are "
           + "discouraged.",
       optionalNamedOnly = {
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
index 9f1285c..307164d 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
@@ -1784,4 +1784,11 @@
         .testStatement("' \\t\\n\\ra b c \\t\\n\\r'.strip()", "a b c")
         .testStatement("' a b c '.strip('')", " a b c ");
   }
+
+  @Test
+  public void testFail() throws Exception {
+    new SkylarkTest()
+        .testIfErrorContains("abc", "fail('abc')")
+        .testIfErrorContains("18", "fail(18)");
+  }
 }