Disallow rule implementation functions to return a struct

Such functions should return a list of providers instead.
This change represents a deprecation of the "old" syntax.

This is an incompatible change attached to new flag --incompatible_disallow_struct_provider_syntax.

See https://docs.google.com/document/d/14A9HK8Jn2jErMayLEE3nrNJIxNfZWN_slFbhgtS6-aM for details.

Migration tracker: #7347
Progress toward #6241

RELNOTES: New incompatible flag --incompatible_disallow_struct_provider_syntax removes the ability for rule implementation functions to return struct. Such functions should return a list of providers instead. Migration tracking: https://github.com/bazelbuild/bazel/issues/7347
PiperOrigin-RevId: 232547460
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java
index 54eb63f..b652357 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java
@@ -318,6 +318,16 @@
       // Use the creation location of this struct as a better reference in error messages
       loc = info.getCreationLoc();
       if (info.getProvider().getKey().equals(StructProvider.STRUCT.getKey())) {
+
+        if (context.getSkylarkSemantics().incompatibleDisallowStructProviderSyntax()) {
+          throw new EvalException(
+              loc,
+              "Returning a struct from a rule implementation function is deprecated and will "
+                  + "be removed soon. It may be temporarily re-enabled by setting "
+                  + "--incompatible_disallow_struct_provider_syntax=false . See "
+                  + "https://github.com/bazelbuild/bazel/issues/7347 for details.");
+        }
+
         // Old-style struct, but it may contain declared providers
         StructImpl struct = (StructImpl) target;
         oldStyleProviders = struct;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
index 695a2e7..30ea540 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
@@ -326,6 +326,20 @@
   public boolean incompatibleDisallowLoadLabelsToCrossPackageBoundaries;
 
   @Option(
+      name = "incompatible_disallow_struct_provider_syntax",
+      defaultValue = "false",
+      documentationCategory = OptionDocumentationCategory.SKYLARK_SEMANTICS,
+      effectTags = {OptionEffectTag.BUILD_FILE_SEMANTICS},
+      metadataTags = {
+        OptionMetadataTag.INCOMPATIBLE_CHANGE,
+        OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
+      },
+      help =
+          "If set to true, rule implementation functions may not return a struct. They must "
+              + "instead return a list of provider instances.")
+  public boolean incompatibleDisallowStructProviderSyntax;
+
+  @Option(
       name = "incompatible_generate_javacommon_source_jar",
       defaultValue = "true",
       documentationCategory = OptionDocumentationCategory.SKYLARK_SEMANTICS,
@@ -555,6 +569,7 @@
         .incompatibleDisallowLoadLabelsToCrossPackageBoundaries(
             incompatibleDisallowLoadLabelsToCrossPackageBoundaries)
         .incompatibleDisallowOldStyleArgsAdd(incompatibleDisallowOldStyleArgsAdd)
+        .incompatibleDisallowStructProviderSyntax(incompatibleDisallowStructProviderSyntax)
         .incompatibleExpandDirectories(incompatibleExpandDirectories)
         .incompatibleGenerateJavaCommonSourceJar(incompatibleGenerateJavaCommonSourceJar)
         .incompatibleNewActionsApi(incompatibleNewActionsApi)
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
index 0396007..3a7882a 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
@@ -158,6 +158,8 @@
 
   public abstract boolean incompatibleDisallowOldStyleArgsAdd();
 
+  public abstract boolean incompatibleDisallowStructProviderSyntax();
+
   public abstract boolean incompatibleExpandDirectories();
 
   public abstract boolean incompatibleGenerateJavaCommonSourceJar();
@@ -225,6 +227,7 @@
           .incompatibleDisallowLegacyJavaInfo(false)
           .incompatibleDisallowLoadLabelsToCrossPackageBoundaries(false)
           .incompatibleDisallowOldStyleArgsAdd(false)
+          .incompatibleDisallowStructProviderSyntax(false)
           .incompatibleExpandDirectories(true)
           .incompatibleGenerateJavaCommonSourceJar(true)
           .incompatibleNewActionsApi(false)
@@ -290,6 +293,8 @@
 
     public abstract Builder incompatibleDisallowOldStyleArgsAdd(boolean value);
 
+    public abstract Builder incompatibleDisallowStructProviderSyntax(boolean value);
+
     public abstract Builder incompatibleExpandDirectories(boolean value);
 
     public abstract Builder incompatibleGenerateJavaCommonSourceJar(boolean value);