Use Object for what instead of String

The string is only used for error messaging on failure. Instead of constructing
lots of strings allow passing in a generic Object whos toString is used for the
error message. This allows us to bypass a lot of garbage string generation, at
th expense of a little indirection.

Chose Object over some specialized type, since we use inline strings frequently
as well.

--
MOS_MIGRATED_REVID=133741724
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 cba10a7..53aabfa 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
@@ -1727,9 +1727,11 @@
    */
   private static Object convertFromBuildLangType(Rule rule, Attribute attr, Object buildLangValue)
       throws ConversionException {
-    String what = "attribute '" + attr.getName() + "' in '" + rule.getRuleClass() + "' rule";
-    Object converted =
-        BuildType.selectableConvert(attr.getType(), buildLangValue, what, rule.getLabel());
+    Object converted = BuildType.selectableConvert(
+        attr.getType(),
+        buildLangValue,
+        new AttributeConversionContext(attr.getName(), rule.getRuleClass()),
+        rule.getLabel());
 
     if ((converted instanceof SelectorList<?>) && !attr.isConfigurable()) {
       throw new ConversionException(
@@ -1749,6 +1751,28 @@
   }
 
   /**
+   * Provides a {@link #toString()} description of the attribute being converted for
+   * {@link BuildType#selectableConvert}. This is preferred over a raw string to avoid uselessly
+   * constructing strings which are never used. A separate class instead of inline to avoid
+   * accidental memory leaks.
+   */
+  private static class AttributeConversionContext {
+    private final String attrName;
+    private final String ruleClass;
+
+    AttributeConversionContext(String attrName, String ruleClass) {
+      this.attrName = attrName;
+      this.ruleClass = ruleClass;
+    }
+
+    @Override
+    public String toString() {
+      return "attribute '" + attrName + "' in '" + ruleClass + "' rule";
+    }
+  }
+
+
+  /**
    * Verifies that the rule has a valid value for the attribute according to its allowed values.
    *
    * <p>If the value for the given attribute on the given rule is invalid, an error will be recorded