Fix StarlarkIndexable.getIndex implementations that return null.

They should return Starlark.NONE instead.

Part of Optional Toolchains (#14726).

Closes #15344.

PiperOrigin-RevId: 444869683
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintCollection.java
index 0ebb273..5c2cabf 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintCollection.java
@@ -233,7 +233,12 @@
 
   @Override
   public Object getIndex(StarlarkSemantics semantics, Object key) throws EvalException {
-    return get(convertKey(key));
+    ConstraintSettingInfo constraintSettingInfo = convertKey(key);
+    Object result = get(constraintSettingInfo);
+    if (result == null) {
+      return Starlark.NONE;
+    }
+    return result;
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkToolchainContext.java b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkToolchainContext.java
index 1e33cff..1e6a355 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkToolchainContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkToolchainContext.java
@@ -30,6 +30,7 @@
 import net.starlark.java.eval.Starlark;
 import net.starlark.java.eval.StarlarkSemantics;
 import net.starlark.java.eval.StarlarkThread;
+import net.starlark.java.eval.StarlarkValue;
 
 /**
  * An implementation of ToolchainContextApi that can better handle converting strings into Labels.
@@ -99,7 +100,7 @@
   }
 
   @Override
-  public ToolchainInfo getIndex(
+  public StarlarkValue getIndex(
       StarlarkThread starlarkThread, StarlarkSemantics semantics, Object key) throws EvalException {
     Label toolchainTypeLabel = transformKey(starlarkThread, key);
 
@@ -116,7 +117,11 @@
               .map(Label::toString)
               .collect(joining(", ")));
     }
-    return toolchainContext().forToolchainType(toolchainTypeLabel);
+    ToolchainInfo toolchainInfo = toolchainContext().forToolchainType(toolchainTypeLabel);
+    if (toolchainInfo == null) {
+      return Starlark.NONE;
+    }
+    return toolchainInfo;
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/platform/ToolchainContextApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/platform/ToolchainContextApi.java
index f98f7d0..25cad74 100644
--- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/platform/ToolchainContextApi.java
+++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/platform/ToolchainContextApi.java
@@ -26,5 +26,6 @@
     doc =
         "Holds toolchains available for a particular exec group. Toolchain targets are accessed by"
             + " indexing with the toolchain type, as in"
-            + " <code>context[\"//pkg:my_toolchain_type\"]</code>.")
+            + " <code>ctx.toolchains[\"//pkg:my_toolchain_type\"]</code>. If the toolchain was"
+            + " optional and no toolchain was resolved, this will return <code>None</code>.")
 public interface ToolchainContextApi extends StarlarkValue, StarlarkIndexable.Threaded {}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java
index 94248b9..10bbd77 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java
@@ -33,7 +33,9 @@
 import com.google.devtools.build.skyframe.EvaluationResult;
 import com.google.devtools.build.skyframe.SkyKey;
 import javax.annotation.Nullable;
+import net.starlark.java.eval.EvalException;
 import net.starlark.java.eval.Printer;
+import net.starlark.java.eval.Starlark;
 import net.starlark.java.eval.StarlarkSemantics;
 import org.junit.Before;
 import org.junit.Test;
@@ -244,7 +246,6 @@
     @Nullable
     @Override
     public Info get(Provider.Key providerKey) {
-
       return null;
     }
 
@@ -252,8 +253,8 @@
     public void repr(Printer printer) {}
 
     @Override
-    public Object getIndex(StarlarkSemantics semantics, Object key) {
-      return null;
+    public Object getIndex(StarlarkSemantics semantics, Object key) throws EvalException {
+      throw Starlark.errorf("Unknown key '%s'", key);
     }
 
     @Override