Let Skylark rules take part in MakeVariableExpandingRule expansions using the
toolchains attribute.

PiperOrigin-RevId: 199133235
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index b8c7471..b93f357 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -36,6 +36,7 @@
 import com.google.devtools.build.lib.analysis.ActionsProvider;
 import com.google.devtools.build.lib.analysis.BaseRuleClasses;
 import com.google.devtools.build.lib.analysis.DefaultInfo;
+import com.google.devtools.build.lib.analysis.TemplateVariableInfo;
 import com.google.devtools.build.lib.analysis.config.ConfigAwareRuleClassBuilder;
 import com.google.devtools.build.lib.analysis.config.HostTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
@@ -88,6 +89,7 @@
 import com.google.devtools.build.lib.syntax.SkylarkUtils;
 import com.google.devtools.build.lib.syntax.Type;
 import com.google.devtools.build.lib.syntax.Type.ConversionException;
+import com.google.devtools.build.lib.util.FileTypeSet;
 import com.google.devtools.build.lib.util.Pair;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
@@ -120,6 +122,11 @@
               BaseRuleClasses.nameAttribute(
                       new RuleClass.Builder("$base_rule", RuleClassType.ABSTRACT, true))
                   .add(attr("expect_failure", STRING)))
+          // TODO(skylark-team): Allow Skylark rules to extend native rules and remove duplication.
+          .add(
+              attr("toolchains", LABEL_LIST)
+                  .allowedFileTypes(FileTypeSet.NO_FILE)
+                  .mandatoryProviders(ImmutableList.of(TemplateVariableInfo.PROVIDER.id())))
           .build();
 
   /** Parent rule class for executable non-test Skylark rules. */
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
index 55a386b..2634773 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
@@ -759,11 +759,10 @@
     checkMutable("expand_make_variables");
     ConfigurationMakeVariableContext makeVariableContext =
         new ConfigurationMakeVariableContext(
-            // TODO(lberki): This should be removed. But only after either verifying that no one
-            // uses it or providing an alternative.
-            ruleContext.getMakeVariables(ImmutableList.of(":cc_toolchain")),
+            this.getRuleContext(),
             ruleContext.getRule().getPackage(),
-            ruleContext.getConfiguration()) {
+            ruleContext.getConfiguration(),
+            ImmutableList.of()) {
           @Override
           public String lookupVariable(String variableName) throws ExpansionException {
             if (additionalSubstitutions.containsKey(variableName)) {
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
index 4d86a34..fbd3760 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
@@ -760,6 +760,61 @@
     assertThat(result).isEqualTo("$ABC");
   }
 
+  private void setUpMakeVarToolchain() throws Exception {
+    scratch.file(
+        "vars/vars.bzl",
+        "def _make_var_supplier_impl(ctx):",
+        "  val = ctx.attr.value",
+        "  return [platform_common.TemplateVariableInfo({'MAKE_VAR_VALUE': val})]",
+        "make_var_supplier = rule(",
+        "    implementation = _make_var_supplier_impl,",
+        "    attrs = {",
+        "        'value': attr.string(mandatory = True),",
+        "    })",
+        "def _make_var_user_impl(ctx):",
+        "  return []",
+        "make_var_user = rule(",
+        "    implementation = _make_var_user_impl,",
+        ")");
+    scratch.file(
+        "vars/BUILD",
+        "load(':vars.bzl', 'make_var_supplier', 'make_var_user')",
+        "make_var_supplier(name = 'supplier', value = 'foo')",
+        "make_var_user(",
+        "    name = 'vars',",
+        "    toolchains = [':supplier'],",
+        ")");
+  }
+
+  @Test
+  public void testExpandMakeVariables_cc() throws Exception {
+    setUpMakeVarToolchain();
+    SkylarkRuleContext ruleContext = createRuleContext("//vars:vars");
+    String result =
+        (String)
+            evalRuleContextCode(
+                ruleContext, "ruleContext.expand_make_variables('cmd', '$(CC)', {})");
+    assertThat(result).isNotEmpty();
+  }
+
+  @Test
+  public void testExpandMakeVariables_toolchain() throws Exception {
+    setUpMakeVarToolchain();
+    SkylarkRuleContext ruleContext = createRuleContext("//vars:vars");
+    Object result =
+        evalRuleContextCode(
+            ruleContext, "ruleContext.expand_make_variables('cmd', '$(MAKE_VAR_VALUE)', {})");
+    assertThat(result).isEqualTo("foo");
+  }
+
+  @Test
+  public void testVar_toolchain() throws Exception {
+    setUpMakeVarToolchain();
+    SkylarkRuleContext ruleContext = createRuleContext("//vars:vars");
+    Object result = evalRuleContextCode(ruleContext, "ruleContext.var['MAKE_VAR_VALUE']");
+    assertThat(result).isEqualTo("foo");
+  }
+
   @Test
   public void testConfiguration() throws Exception {
     SkylarkRuleContext ruleContext = createRuleContext("//foo:foo");