Provide label of the toolchain in `ToolchainAspectsProviders`

PiperOrigin-RevId: 690667496
Change-Id: Ice3cfd5f27ed0f94979cb642dffa56ef2a2dc4a9
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AspectBaseTargetResolvedToolchainContext.java b/src/main/java/com/google/devtools/build/lib/analysis/AspectBaseTargetResolvedToolchainContext.java
index 3fb9985..9a8482c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AspectBaseTargetResolvedToolchainContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AspectBaseTargetResolvedToolchainContext.java
@@ -16,6 +16,7 @@
 
 import com.google.auto.value.AutoValue;
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Iterables;
@@ -32,6 +33,7 @@
 import net.starlark.java.eval.Starlark;
 import net.starlark.java.eval.StarlarkIndexable;
 import net.starlark.java.eval.StarlarkSemantics;
+import net.starlark.java.eval.Structure;
 
 /**
  * A toolchain context for the aspect's base target toolchains. It is used to represent the result
@@ -105,7 +107,7 @@
    * target toolchains.
    */
   public static class ToolchainAspectsProviders
-      implements StarlarkIndexable, ResolvedToolchainData {
+      implements StarlarkIndexable, Structure, ResolvedToolchainData {
 
     private final TransitiveInfoProviderMap aspectsProviders;
     private final Label label;
@@ -155,5 +157,26 @@
     public void repr(Printer printer) {
       printer.append("<ToolchainAspectsProviders for toolchain target: " + label + ">");
     }
+
+    @Nullable
+    @Override
+    public Object getValue(String name) {
+      if (name.equals(MergedConfiguredTarget.LABEL_FIELD)) {
+        return label;
+      }
+      return null;
+    }
+
+    @Override
+    public ImmutableList<String> getFieldNames() {
+      return ImmutableList.of(MergedConfiguredTarget.LABEL_FIELD);
+    }
+
+    @Nullable
+    @Override
+    public String getErrorMessageForUnknownField(String field) {
+      // Use the default error message.
+      return null;
+    }
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkAspectsToolchainPropagationTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkAspectsToolchainPropagationTest.java
index f6cac3a..1d2da7f 100644
--- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkAspectsToolchainPropagationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkAspectsToolchainPropagationTest.java
@@ -2218,6 +2218,56 @@
                 + " exec_platform: //platforms:platform_2");
   }
 
+  @Test
+  public void aspectPropagatesToToolchain_seesToolchainLabel(@TestParameter boolean autoExecGroups)
+      throws Exception {
+    scratch.file(
+        "test/defs.bzl",
+        """
+        AspectProvider = provider()
+        def _impl(target, ctx):
+          if ctx.rule.toolchains and '//rule:toolchain_type_1' in ctx.rule.toolchains:
+              return [
+                AspectProvider(value = str(target.label) + ' has toolchain ' +
+                  str(ctx.rule.toolchains['//rule:toolchain_type_1'].label))]
+          return []
+
+        toolchain_aspect = aspect(
+          implementation = _impl,
+          toolchains_aspects = ['//rule:toolchain_type_1'],
+        )
+
+        def _rule_impl(ctx):
+          pass
+
+        r1 = rule(
+          implementation = _rule_impl,
+          toolchains = ['//rule:toolchain_type_1'],
+        )
+        """);
+    scratch.file(
+        "test/BUILD",
+        """
+        load('//test:defs.bzl', 'r1')
+        r1(name = 't1')
+        """);
+    useConfiguration(
+        "--extra_toolchains=//toolchain:foo_toolchain",
+        "--incompatible_auto_exec_groups=" + autoExecGroups);
+
+    var analysisResult = update(ImmutableList.of("//test:defs.bzl%toolchain_aspect"), "//test:t1");
+
+    ConfiguredAspect configuredAspect =
+        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
+
+    StarlarkProvider.Key providerKey =
+        new StarlarkProvider.Key(
+            keyForBuild(Label.parseCanonical("//test:defs.bzl")), "AspectProvider");
+
+    var value = ((StarlarkInfo) configuredAspect.get(providerKey)).getValue("value");
+    assertThat((String) value).isEqualTo("@@//test:t1 has toolchain @@//toolchain:foo");
+  }
+
   private ImmutableList<ConfiguredTargetKey> getConfiguredTargetKey(String targetLabel) {
     return skyframeExecutor.getEvaluator().getInMemoryGraph().getAllNodeEntries().stream()
         .filter(n -> isConfiguredTarget(n.getKey(), targetLabel))