Add checks for list parameters of cc_common.create_cc_toolchain_config_info() to prevent bazel crashing when a struct is expected but something else is passed instead.

Fixes #8435

RELNOTES: None.
PiperOrigin-RevId: 253212600
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index 49970a7..ba16c83 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -653,6 +653,7 @@
 
     ImmutableList.Builder<Feature> featureBuilder = ImmutableList.builder();
     for (Object feature : features) {
+      checkRightSkylarkInfoProvider(feature, "features", "FeatureInfo");
       featureBuilder.add(featureFromSkylark((SkylarkInfo) feature));
     }
     ImmutableList<Feature> featureList = featureBuilder.build();
@@ -668,6 +669,7 @@
 
     ImmutableList.Builder<ActionConfig> actionConfigBuilder = ImmutableList.builder();
     for (Object actionConfig : actionConfigs) {
+      checkRightSkylarkInfoProvider(actionConfig, "action_configs", "ActionConfigInfo");
       actionConfigBuilder.add(actionConfigFromSkylark((SkylarkInfo) actionConfig));
     }
     ImmutableList<ActionConfig> actionConfigList = actionConfigBuilder.build();
@@ -678,6 +680,8 @@
 
     ImmutableList.Builder<ArtifactNamePattern> artifactNamePatternBuilder = ImmutableList.builder();
     for (Object artifactNamePattern : artifactNamePatterns) {
+      checkRightSkylarkInfoProvider(
+          artifactNamePattern, "artifact_name_patterns", "ArtifactNamePatternInfo");
       artifactNamePatternBuilder.add(
           artifactNamePatternFromSkylark((SkylarkInfo) artifactNamePattern));
     }
@@ -697,6 +701,7 @@
     // Pairs (toolName, toolPath)
     ImmutableList.Builder<Pair<String, String>> toolPathPairs = ImmutableList.builder();
     for (Object toolPath : toolPaths) {
+      checkRightSkylarkInfoProvider(toolPath, "tool_paths", "ToolPathInfo");
       Pair<String, String> toolPathPair = toolPathFromSkylark((SkylarkInfo) toolPath);
       toolPathPairs.add(toolPathPair);
       cToolchain.addToolPath(
@@ -803,6 +808,7 @@
 
     ImmutableList.Builder<Pair<String, String>> makeVariablePairs = ImmutableList.builder();
     for (Object makeVariable : makeVariables) {
+      checkRightSkylarkInfoProvider(makeVariable, "make_variables", "MakeVariableInfo");
       Pair<String, String> makeVariablePair = makeVariableFromSkylark((SkylarkInfo) makeVariable);
       makeVariablePairs.add(makeVariablePair);
       cToolchain.addMakeVariable(
@@ -850,6 +856,20 @@
         cToolchain.build().toString());
   }
 
+  private static void checkRightSkylarkInfoProvider(
+      Object o, String parameterName, String expectedProvider) throws EvalException {
+    if (!(o instanceof SkylarkInfo)) {
+      throw new EvalException(
+          Location.BUILTIN,
+          String.format(
+              "'%s' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
+                  + " of type '%s' instead of a '%s' provider. Use the methods provided in"
+                  + " https://source.bazel.build/bazel/+/master:tools/cpp/cc_toolchain_config_lib.bzl"
+                  + " for obtaining the right providers.",
+              parameterName, EvalUtils.getDataTypeName(o), expectedProvider));
+    }
+  }
+
   /** Checks whether the {@link SkylarkInfo} is of the required type. */
   private static void checkRightProviderType(SkylarkInfo provider, String type)
       throws EvalException {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
index b3ad255..ae24710 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/SkylarkCcCommonTest.java
@@ -4789,6 +4789,87 @@
   }
 
   @Test
+  public void testWrongElementTypeInListParameter_features() throws Exception {
+    getBasicCcToolchainConfigInfoWithAdditionalParameter(
+        "features = ['string_instead_of_feature']");
+    reporter.removeHandler(failFastHandler);
+    getConfiguredTarget("//foo:r");
+    assertContainsEvent(
+        "'features' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
+            + " of type 'string' instead of a 'FeatureInfo' provider.");
+  }
+
+  @Test
+  public void testWrongElementTypeInListParameter_actionConfigs() throws Exception {
+    getBasicCcToolchainConfigInfoWithAdditionalParameter("action_configs = [None]");
+    reporter.removeHandler(failFastHandler);
+    getConfiguredTarget("//foo:r");
+    assertContainsEvent(
+        "'action_configs' parameter of cc_common.create_cc_toolchain_config_info() contains an"
+            + " element of type 'NoneType' instead of a 'ActionConfigInfo' provider.");
+  }
+
+  @Test
+  public void testWrongElementTypeInListParameter_artifactNamePatterns() throws Exception {
+    getBasicCcToolchainConfigInfoWithAdditionalParameter("artifact_name_patterns = [1]");
+    reporter.removeHandler(failFastHandler);
+    getConfiguredTarget("//foo:r");
+    assertContainsEvent(
+        "'artifact_name_patterns' parameter of cc_common.create_cc_toolchain_config_info()"
+            + " contains an element of type 'int' instead of a 'ArtifactNamePatternInfo'"
+            + " provider.");
+  }
+
+  @Test
+  public void testWrongElementTypeInListParameter_makeVariables() throws Exception {
+    getBasicCcToolchainConfigInfoWithAdditionalParameter("make_variables = [True]");
+    reporter.removeHandler(failFastHandler);
+    getConfiguredTarget("//foo:r");
+    assertContainsEvent(
+        "'make_variables' parameter of cc_common.create_cc_toolchain_config_info() contains an"
+            + " element of type 'bool' instead of a 'MakeVariableInfo' provider.");
+  }
+
+  @Test
+  public void testWrongElementTypeInListParameter_toolPaths() throws Exception {
+    getBasicCcToolchainConfigInfoWithAdditionalParameter("tool_paths = [{}]");
+    reporter.removeHandler(failFastHandler);
+    getConfiguredTarget("//foo:r");
+    assertContainsEvent(
+        "'tool_paths' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
+            + " of type 'dict' instead of a 'ToolPathInfo' provider.");
+  }
+
+  private void getBasicCcToolchainConfigInfoWithAdditionalParameter(String s) throws Exception {
+    scratch.file(
+        "foo/crosstool.bzl",
+        "def _impl(ctx):",
+        "    return cc_common.create_cc_toolchain_config_info(",
+        "                ctx = ctx,",
+        "                toolchain_identifier = 'toolchain',",
+        "                host_system_name = 'host',",
+        "                target_system_name = 'target',",
+        "                target_cpu = 'cpu',",
+        "                target_libc = 'libc',",
+        "                compiler = 'compiler',",
+        "                abi_libc_version = 'abi_libc',",
+        "                abi_version = 'abi',",
+        "                " + s + ",",
+        "        )",
+        "cc_toolchain_config_rule = rule(",
+        "    implementation = _impl,",
+        "    attrs = {},",
+        "    provides = [CcToolchainConfigInfo], ",
+        ")");
+
+    scratch.file(
+        "foo/BUILD",
+        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
+        "cc_toolchain_alias(name='alias')",
+        "cc_toolchain_config_rule(name='r')");
+  }
+
+  @Test
   public void testGetLegacyCcFlagsMakeVariable() throws Exception {
     AnalysisMock.get()
         .ccSupport()