Add type checking to select() keys.

Aside from making error messaging clearer, this stops Bazel from
crashing on select({None: ...}) (a pretty anti-social error message).

--
PiperOrigin-RevId: 146173043
MOS_MIGRATED_REVID=146173043
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
index c55e607..b943e4a 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
@@ -172,11 +172,19 @@
         defaultValue = "''",
         doc = "Optional custom error to report if no condition matches."
       )
-    }
+    },
+    useLocation = true
   )
   private static final BuiltinFunction select =
       new BuiltinFunction("select") {
-        public Object invoke(SkylarkDict<?, ?> dict, String noMatchError) throws EvalException {
+        public Object invoke(SkylarkDict<?, ?> dict, String noMatchError, Location loc)
+            throws EvalException {
+          for (Object key : dict.keySet()) {
+            if (!(key instanceof String)) {
+              throw new EvalException(loc,
+                  String.format("Invalid key: %s. select keys must be label references", key));
+            }
+          }
           return SelectorList.of(new SelectorValue(dict, noMatchError));
         }
       };
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 3121bfc..b303d00 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -322,6 +322,25 @@
     return getPackageManager().getTarget(reporter, label);
   }
 
+  /**
+   * Checks that loading the given target fails with the expected error message.
+   *
+   * <p>Fails with an assertion error if this doesn't happen.
+   *
+   * <p>This method is useful for checking loading phase errors. Analysis phase errors can be
+   * checked with {@link #getConfiguredTarget} and related methods.
+   */
+  protected void assertTargetError(String label, String expectedError)
+      throws InterruptedException {
+    try {
+      getTarget(label);
+      fail("Expected loading phase failure for target " + label);
+    } catch (NoSuchPackageException | NoSuchTargetException | LabelSyntaxException e) {
+      // Target loading failed as expected.
+    }
+    assertContainsEvent(expectedError);
+  }
+
   private void setUpSkyframe() {
     PathPackageLocator pkgLocator = PathPackageLocator.create(
         outputBase, packageCacheOptions.packagePath, reporter, rootDirectory, rootDirectory);