Remove "return struct" in rule implementation of some Bazel tests (#2)

This makes the affected tests compatible with --incompatible_disallow_struct_provider_syntax

Progress toward #7347.

RELNOTES: None.
PiperOrigin-RevId: 244210656
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
index a26e17f..08df7c2 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/AspectTest.java
@@ -599,11 +599,11 @@
         "x/extension.bzl",
         "def _aspect_impl(target, ctx):",
         "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
-        "  return struct()",
+        "  return []",
         "aspect1 = aspect(_aspect_impl, attr_aspects=['deps'])",
         "aspect2 = aspect(_aspect_impl, attr_aspects=['extra_deps'])",
         "def _rule_impl(ctx):",
-        "  return struct()",
+        "  return []",
         "injector1 = rule(_rule_impl, attrs = { 'deps' : attr.label_list(aspects = [aspect1]) })",
         "null_rule = rule(_rule_impl, attrs = { 'deps' : attr.label_list() })",
         "injector2 = rule(",
@@ -664,17 +664,16 @@
         "x/extension.bzl",
         "def _aspect_impl(target, ctx):",
         "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
-        "  return struct()",
+        "  return []",
         "aspect1 = aspect(_aspect_impl, attr_aspects=['deps'], attrs =",
         "    {'param': attr.string(values = ['a', 'b'])})",
         "aspect2 = aspect(_aspect_impl, attr_aspects=['deps'])",
         "def _rule_impl(ctx):",
-        "  return struct()",
+        "  return []",
         "injector1 = rule(_rule_impl, attrs =",
         "    { 'deps' : attr.label_list(aspects = [aspect1]), 'param' : attr.string() })",
         "injector2 = rule(_rule_impl, attrs = { 'deps' : attr.label_list(aspects = [aspect2]) })",
-        "null_rule = rule(_rule_impl, attrs = { 'deps' : attr.label_list() })"
-    );
+        "null_rule = rule(_rule_impl, attrs = { 'deps' : attr.label_list() })");
 
     scratch.file(
         "pkg1/BUILD",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
index bfc6810..4a61ad2 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BuildViewTest.java
@@ -1200,18 +1200,18 @@
         "x/extension.bzl",
         "def _aspect1_impl(target, ctx):",
         "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
-        "  return struct()",
+        "  return []",
         "aspect1 = aspect(_aspect1_impl, attr_aspects=['deps'])",
         "",
         "def _injecting_rule_impl(ctx):",
-        "  return struct()",
+        "  return []",
         "injecting_rule = rule(_injecting_rule_impl, ",
         "    attrs = { 'deps' : attr.label_list(aspects = [aspect1]) })",
         "",
         "def _action_rule_impl(ctx):",
         "  out = ctx.actions.declare_file(ctx.label.name)",
         "  ctx.actions.run_shell(outputs = [out], command = 'dontcare', mnemonic='Mnemonic')",
-        "  return struct()",
+        "  return []",
         "action_rule = rule(_action_rule_impl, attrs = { 'deps' : attr.label_list() })");
 
     scratch.file(
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java b/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java
index 1e179b2..c87b315 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/CircularDependencyTest.java
@@ -213,9 +213,10 @@
         "plain(name = 'c')",
         "plain(name = 'aspectdep', aspect_deps = ['a'])");
 
-    scratch.file("x/x.bzl",
+    scratch.file(
+        "x/x.bzl",
         "def _impl(ctx):",
-        "    return struct()",
+        "    return []",
         "",
         "rule_aspect = aspect(",
         "    implementation = _impl,",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java
index e6e6e12..ce33de9 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkAttrTransitionProviderTest.java
@@ -22,9 +22,13 @@
 import com.google.common.collect.ListMultimap;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
+import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.packages.util.BazelMockAndroidSupport;
 import java.util.List;
 import java.util.Map;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -33,6 +37,20 @@
 @RunWith(JUnit4.class)
 public class StarlarkAttrTransitionProviderTest extends BuildViewTestCase {
 
+  @Before
+  public void setupMyInfo() throws Exception {
+    scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");
+
+    scratch.file("myinfo/BUILD");
+  }
+
+  private StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget) throws Exception {
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.parseAbsolute("//myinfo:myinfo.bzl", ImmutableMap.of()), "MyInfo");
+    return (StructImpl) configuredTarget.get(key);
+  }
+
   private void writeWhitelistFile() throws Exception {
     scratch.file(
         "tools/whitelists/function_transition_whitelist/BUILD",
@@ -50,6 +68,7 @@
     getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a");
     scratch.file(
         "test/skylark/my_rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def transition_func(settings, attr):",
         "  return {",
         "      't0': {'//command_line_option:cpu': 'k8'},",
@@ -58,7 +77,7 @@
         "my_transition = transition(implementation = transition_func, inputs = [],",
         "  outputs = ['//command_line_option:cpu'])",
         "def impl(ctx): ",
-        "  return struct(",
+        "  return MyInfo(",
         "    split_attr_deps = ctx.split_attr.deps,",
         "    split_attr_dep = ctx.split_attr.dep,",
         "    k8_deps = ctx.split_attr.deps.get('k8', None),",
@@ -119,6 +138,7 @@
     getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a");
     scratch.file(
         "test/not_whitelisted/my_rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def transition_func(settings, attr):",
         "  return {",
         "      't0': {'//command_line_option:cpu': 'k8'},",
@@ -127,7 +147,7 @@
         "my_transition = transition(implementation = transition_func, inputs = [],",
         "  outputs = ['//command_line_option:cpu'])",
         "def impl(ctx): ",
-        "  return struct(",
+        "  return MyInfo(",
         "    split_attr_deps = ctx.split_attr.deps,",
         "    split_attr_dep = ctx.split_attr.dep,",
         "    k8_deps = ctx.split_attr.deps.get('k8', None),",
@@ -161,7 +181,8 @@
     // }
     @SuppressWarnings("unchecked")
     Map<String, List<ConfiguredTarget>> splitDeps =
-        (Map<String, List<ConfiguredTarget>>) target.get("split_attr_deps");
+        (Map<String, List<ConfiguredTarget>>)
+            getMyInfoFromTarget(target).getValue("split_attr_deps");
     assertThat(splitDeps).containsKey("k8");
     assertThat(splitDeps).containsKey("armeabi-v7a");
     assertThat(splitDeps.get("k8")).hasSize(2);
@@ -182,7 +203,7 @@
     // }
     @SuppressWarnings("unchecked")
     Map<String, ConfiguredTarget> splitDep =
-        (Map<String, ConfiguredTarget>) target.get("split_attr_dep");
+        (Map<String, ConfiguredTarget>) getMyInfoFromTarget(target).getValue("split_attr_dep");
     assertThat(splitDep).containsKey("k8");
     assertThat(splitDep).containsKey("armeabi-v7a");
     assertThat(getConfiguration(splitDep.get("k8")).getCpu()).isEqualTo("k8");
@@ -193,7 +214,8 @@
     // The regular ctx.attr.deps should be a single list with all the branches of the split merged
     // together (i.e. for aspects).
     @SuppressWarnings("unchecked")
-    List<ConfiguredTarget> attrDeps = (List<ConfiguredTarget>) target.get("attr_deps");
+    List<ConfiguredTarget> attrDeps =
+        (List<ConfiguredTarget>) getMyInfoFromTarget(target).getValue("attr_deps");
     assertThat(attrDeps).hasSize(4);
     ListMultimap<String, Object> attrDepsMap = ArrayListMultimap.create();
     for (ConfiguredTarget ct : attrDeps) {
@@ -207,7 +229,8 @@
     // Check that even though my_rule.dep is defined as a single label, ctx.attr.dep is still a list
     // with multiple ConfiguredTarget objects because of the two different CPUs.
     @SuppressWarnings("unchecked")
-    List<ConfiguredTarget> attrDep = (List<ConfiguredTarget>) target.get("attr_dep");
+    List<ConfiguredTarget> attrDep =
+        (List<ConfiguredTarget>) getMyInfoFromTarget(target).getValue("attr_dep");
     assertThat(attrDep).hasSize(2);
     ListMultimap<String, Object> attrDepMap = ArrayListMultimap.create();
     for (ConfiguredTarget ct : attrDep) {
@@ -220,7 +243,8 @@
   private void testSplitTransitionCheckK8Deps(ConfiguredTarget target) throws Exception {
     // Check that the deps were correctly accessed from within Skylark.
     @SuppressWarnings("unchecked")
-    List<ConfiguredTarget> k8Deps = (List<ConfiguredTarget>) target.get("k8_deps");
+    List<ConfiguredTarget> k8Deps =
+        (List<ConfiguredTarget>) getMyInfoFromTarget(target).getValue("k8_deps");
     assertThat(k8Deps).hasSize(2);
     assertThat(getConfiguration(k8Deps.get(0)).getCpu()).isEqualTo("k8");
     assertThat(getConfiguration(k8Deps.get(1)).getCpu()).isEqualTo("k8");
@@ -232,6 +256,7 @@
 
     scratch.file(
         "test/skylark/my_rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def transition_func(settings, attr):",
         "  transitions = {}",
         "  for cpu in settings['//command_line_option:fat_apk_cpu']:",
@@ -243,7 +268,7 @@
         "  inputs = ['//command_line_option:fat_apk_cpu'],",
         "  outputs = ['//command_line_option:cpu'])",
         "def impl(ctx): ",
-        "  return struct(split_attr_dep = ctx.split_attr.dep)",
+        "  return MyInfo(split_attr_dep = ctx.split_attr.dep)",
         "my_rule = rule(",
         "  implementation = impl,",
         "  attrs = {",
@@ -275,7 +300,7 @@
 
     @SuppressWarnings("unchecked")
     Map<String, ConfiguredTarget> splitDep =
-        (Map<String, ConfiguredTarget>) target.get("split_attr_dep");
+        (Map<String, ConfiguredTarget>) getMyInfoFromTarget(target).getValue("split_attr_dep");
     assertThat(splitDep).containsKey("k8");
     assertThat(splitDep).containsKey("armeabi-v7a");
     assertThat(getConfiguration(splitDep.get("k8")).getCpu()).isEqualTo("k8");
@@ -288,6 +313,7 @@
 
     scratch.file(
         "test/skylark/my_rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def transition_func(settings, attr):",
         "  return {",
         "    '//command_line_option:cpu': 'armeabi-v7a',",
@@ -299,7 +325,7 @@
         "            '//command_line_option:dynamic_mode',",
         "            '//command_line_option:crosstool_top'])",
         "def impl(ctx): ",
-        "  return struct(split_attr_dep = ctx.split_attr.dep)",
+        "  return MyInfo(split_attr_dep = ctx.split_attr.dep)",
         "my_rule = rule(",
         "  implementation = impl,",
         "  attrs = {",
@@ -325,7 +351,7 @@
 
     @SuppressWarnings("unchecked")
     Map<String, ConfiguredTarget> splitDep =
-        (Map<String, ConfiguredTarget>) target.get("split_attr_dep");
+        (Map<String, ConfiguredTarget>) getMyInfoFromTarget(target).getValue("split_attr_dep");
     assertThat(splitDep).containsKey("armeabi-v7a");
     assertThat(getConfiguration(splitDep.get("armeabi-v7a")).getCpu()).isEqualTo("armeabi-v7a");
   }
@@ -726,6 +752,7 @@
   private void writeRulesWithAttrTransitionBzl() throws Exception {
     scratch.file(
         "test/skylark/rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "load('//test/skylark:build_settings.bzl', 'BuildSettingInfo')",
         "def _transition_impl(settings, attr):",
         "  return {'//test/skylark:the-answer': 42}",
@@ -735,7 +762,7 @@
         "  outputs = ['//test/skylark:the-answer']",
         ")",
         "def _rule_impl(ctx):",
-        "  return struct(dep = ctx.attr.dep)",
+        "  return MyInfo(dep = ctx.attr.dep)",
         "my_rule = rule(",
         "  implementation = _rule_impl,",
         "  attrs = {",
@@ -769,9 +796,11 @@
         "my_rule(name = 'dep')",
         "int_flag(name = 'the-answer', build_setting_default = 0)");
 
+    @SuppressWarnings("unchecked")
     ConfiguredTarget dep =
         Iterables.getOnlyElement(
-            (List<ConfiguredTarget>) getConfiguredTarget("//test/skylark:test").get("dep"));
+            (List<ConfiguredTarget>)
+                getMyInfoFromTarget(getConfiguredTarget("//test/skylark:test")).getValue("dep"));
     assertThat(
             getConfiguration(dep)
                 .getOptions()
@@ -804,7 +833,10 @@
                 .get(Label.parseAbsoluteUnchecked("//test/skylark:the-answer")))
         .isEqualTo(7);
 
-    ConfiguredTarget dep = Iterables.getOnlyElement((List<ConfiguredTarget>) test.get("dep"));
+    @SuppressWarnings("unchecked")
+    ConfiguredTarget dep =
+        Iterables.getOnlyElement(
+            (List<ConfiguredTarget>) getMyInfoFromTarget(test).getValue("dep"));
     assertThat(
             getConfiguration(dep)
                 .getOptions()
@@ -821,6 +853,7 @@
     writeBuildSettingsBzl();
     scratch.file(
         "test/skylark/rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "load('//test/skylark:build_settings.bzl', 'BuildSettingInfo')",
         "def _transition_impl(settings, attr):",
         "  return {'//test/skylark:the-answer': 'What do you get if you multiply six by nine?'}",
@@ -830,7 +863,7 @@
         "  outputs = ['//test/skylark:the-answer']",
         ")",
         "def _rule_impl(ctx):",
-        "  return struct(dep = ctx.attr.dep)",
+        "  return MyInfo(dep = ctx.attr.dep)",
         "my_rule = rule(",
         "  implementation = _rule_impl,",
         "  attrs = {",
diff --git a/src/test/java/com/google/devtools/build/lib/rules/apple/BUILD b/src/test/java/com/google/devtools/build/lib/rules/apple/BUILD
index badd79c..42fc759 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/apple/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/rules/apple/BUILD
@@ -17,6 +17,7 @@
         "//src/main/java/com/google/devtools/build/lib:build-base",
         "//src/main/java/com/google/devtools/build/lib:packages-internal",
         "//src/main/java/com/google/devtools/build/lib:syntax",
+        "//src/main/java/com/google/devtools/build/lib/cmdline",
         "//src/main/java/com/google/devtools/build/lib/rules/apple",
         "//src/test/java/com/google/devtools/build/lib:analysis_testutil",
         "//third_party:guava",
diff --git a/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java b/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java
index 5bf2d40..36fe9b2 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/apple/XcodeConfigTest.java
@@ -19,7 +19,11 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
+import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
 import com.google.devtools.build.lib.syntax.Type;
 import org.junit.Test;
@@ -69,11 +73,12 @@
   @Test
   public void testConfigAlias_configSetting() throws Exception {
     scratch.file("skylark/BUILD");
-    scratch.file("skylark/version_retriever.bzl",
+    scratch.file(
+        "skylark/version_retriever.bzl",
         "def _version_retriever_impl(ctx):",
         "  xcode_properties = ctx.attr.dep[apple_common.XcodeProperties]",
         "  version = xcode_properties.xcode_version",
-        "  return struct(providers = [config_common.FeatureFlagInfo(value=version)])",
+        "  return [config_common.FeatureFlagInfo(value=version)]",
         "",
         "version_retriever = rule(",
         "  implementation = _version_retriever_impl,",
@@ -143,11 +148,12 @@
   @Test
   public void testDefaultVersion_configSetting() throws Exception {
     scratch.file("skylark/BUILD");
-    scratch.file("skylark/version_retriever.bzl",
+    scratch.file(
+        "skylark/version_retriever.bzl",
         "def _version_retriever_impl(ctx):",
         "  xcode_properties = ctx.attr.dep[apple_common.XcodeProperties]",
         "  version = xcode_properties.xcode_version",
-        "  return struct(providers = [config_common.FeatureFlagInfo(value=version)])",
+        "  return [config_common.FeatureFlagInfo(value=version)]",
         "",
         "version_retriever = rule(",
         "  implementation = _version_retriever_impl,",
@@ -595,12 +601,14 @@
         "    default_watchos_sdk_version = '4.0',",
         ")",
         "r(name='r')");
-    scratch.file("x/r.bzl",
+    scratch.file(
+        "x/r.bzl",
+        "MyInfo = provider()",
         "def _impl(ctx):",
         "  conf = ctx.attr._xcode[apple_common.XcodeVersionConfig]",
         "  ios = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)",
         "  tvos = ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.tvos)",
-        "  return struct(",
+        "  return MyInfo(",
         "    xcode = conf.xcode_version(),",
         "    ios_sdk = conf.sdk_version_for_platform(ios),",
         "    tvos_sdk = conf.sdk_version_for_platform(tvos),",
@@ -617,11 +625,16 @@
         "--tvos_sdk_version=2.5",
         "--watchos_minimum_os=4.5");
     ConfiguredTarget r = getConfiguredTarget("//x:r");
-    assertThat(r.get("xcode").toString()).isEqualTo("0.0");
-    assertThat(r.get("ios_sdk").toString()).isEqualTo("1.0");
-    assertThat(r.get("tvos_sdk").toString()).isEqualTo("2.5");
-    assertThat(r.get("macos_min").toString()).isEqualTo("3.0");
-    assertThat(r.get("watchos_min").toString()).isEqualTo("4.5");
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.parseAbsolute("//x:r.bzl", ImmutableMap.of()), "MyInfo");
+    StructImpl info = (StructImpl) r.get(key);
+
+    assertThat(info.getValue("xcode").toString()).isEqualTo("0.0");
+    assertThat(info.getValue("ios_sdk").toString()).isEqualTo("1.0");
+    assertThat(info.getValue("tvos_sdk").toString()).isEqualTo("2.5");
+    assertThat(info.getValue("macos_min").toString()).isEqualTo("3.0");
+    assertThat(info.getValue("watchos_min").toString()).isEqualTo("4.5");
   }
 
   @Test
@@ -694,13 +707,11 @@
   // configuration_field() skylark method and used in a skylark rule.
   @Test
   public void testConfigurationFieldForRule() throws Exception {
-    scratch.file("x/provider_grabber.bzl",
+    scratch.file(
+        "x/provider_grabber.bzl",
         "def _impl(ctx):",
         "  conf = ctx.attr._xcode_dep[apple_common.XcodeVersionConfig]",
-        "  return struct(",
-        "    providers = [conf],",
-        "  )",
-
+        "  return [conf]",
         "provider_grabber = rule(implementation = _impl,",
         "    attrs = { '_xcode_dep': attr.label(",
         "        default = configuration_field(",
@@ -728,12 +739,11 @@
   // configuration_field() skylark method and used in a skylark aspect.
   @Test
   public void testConfigurationFieldForAspect() throws Exception {
-    scratch.file("x/provider_grabber.bzl",
+    scratch.file(
+        "x/provider_grabber.bzl",
         "def _aspect_impl(target, ctx):",
         "  conf = ctx.attr._xcode_dep[apple_common.XcodeVersionConfig]",
-        "  return struct(",
-        "    providers = [conf],",
-        "  )",
+        "  return [conf]",
         "",
         "MyAspect = aspect(implementation = _aspect_impl,",
         "    attrs = { '_xcode_dep': attr.label(",
@@ -745,9 +755,7 @@
         "",
         "def _rule_impl(ctx):",
         "  conf = ctx.attr.dep[0][apple_common.XcodeVersionConfig]",
-        "  return struct(",
-        "    providers = [conf],",
-        "  )",
+        "  return [conf]",
         "",
         "provider_grabber = rule(implementation = _rule_impl,",
         "    attrs = { 'dep' : ",
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagTest.java b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagTest.java
index e44e1e1..64206bc 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagTest.java
@@ -116,7 +116,7 @@
         "  attrs = {'flag': attr.label()},",
         ")",
         "def _flag_propagating_wrapper_impl(ctx):",
-        "  return struct(providers = [config_common.FeatureFlagInfo(value='hello')])",
+        "  return [config_common.FeatureFlagInfo(value='hello')]",
         "flag_propagating_wrapper = rule(",
         "  implementation = _flag_propagating_wrapper_impl,",
         ")");
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java
index 23876c3..e84df9c 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderTest.java
@@ -21,6 +21,10 @@
 import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
 import com.google.devtools.build.lib.analysis.util.AnalysisMock;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
+import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.packages.util.Crosstool.CcToolchainConfig;
 import com.google.devtools.build.lib.packages.util.MockCcSupport;
 import com.google.devtools.build.lib.packages.util.ResourceLoader;
@@ -43,10 +47,11 @@
     useConfiguration("--cpu=k8", "--force_pic");
     scratch.file(
         "test/rule.bzl",
+        "MyInfo = provider()",
         "def _impl(ctx):",
         "  provider = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
         "  feature_configuration = cc_common.configure_features(cc_toolchain = provider)",
-        "  return struct(",
+        "  return MyInfo(",
         "    dirs = provider.built_in_include_directories,",
         "    sysroot = provider.sysroot,",
         "    cpu = provider.cpu,",
@@ -67,15 +72,19 @@
         "my_rule(name = 'target')");
 
     ConfiguredTarget ct = getConfiguredTarget("//test:target");
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.parseAbsolute("//test:rule.bzl", ImmutableMap.of()), "MyInfo");
+    StructImpl info = (StructImpl) ct.get(key);
 
-    assertThat((String) ct.get("ar_executable")).endsWith("/usr/bin/mock-ar");
+    assertThat((String) info.getValue("ar_executable")).endsWith("/usr/bin/mock-ar");
 
-    assertThat(ct.get("cpu")).isEqualTo("k8");
+    assertThat(info.getValue("cpu")).isEqualTo("k8");
 
-    assertThat(ct.get("sysroot")).isEqualTo("/usr/grte/v1");
+    assertThat(info.getValue("sysroot")).isEqualTo("/usr/grte/v1");
 
     @SuppressWarnings("unchecked")
-    boolean usePicForDynamicLibraries = (boolean) ct.get("use_pic_for_dynamic_libraries");
+    boolean usePicForDynamicLibraries = (boolean) info.getValue("use_pic_for_dynamic_libraries");
     assertThat(usePicForDynamicLibraries).isTrue();
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
index 49caa9e..41f37db 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
@@ -25,6 +25,8 @@
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
 import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
 import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar;
@@ -37,6 +39,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -47,6 +50,20 @@
   private static final String HOST_JAVA_RUNTIME_LABEL =
       TestConstants.TOOLS_REPOSITORY + "//tools/jdk:current_host_java_runtime";
 
+  @Before
+  public void setupMyInfo() throws Exception {
+    scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");
+
+    scratch.file("myinfo/BUILD");
+  }
+
+  private StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget) throws Exception {
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.parseAbsolute("//myinfo:myinfo.bzl", ImmutableMap.of()), "MyInfo");
+    return (StructImpl) configuredTarget.get(key);
+  }
+
   @Test
   public void testJavaRuntimeProviderJavaAbsolute() throws Exception {
     scratch.file(
@@ -77,9 +94,10 @@
 
     scratch.file(
         "a/rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _impl(ctx):",
         "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
-        "  return struct(",
+        "  return MyInfo(",
         "    java_home_exec_path = provider.java_home,",
         "    java_executable_exec_path = provider.java_executable_exec_path,",
         "    java_home_runfiles_path = provider.java_home_runfiles_path,",
@@ -90,17 +108,20 @@
     useConfiguration(
         "--javabase=//a:jvm", "--extra_toolchains=//a:all", "--platforms=//a:platform");
     ConfiguredTarget ct = getConfiguredTarget("//a:r");
+    StructImpl myInfo = getMyInfoFromTarget(ct);
     @SuppressWarnings("unchecked")
-    PathFragment javaHomeExecPath = (PathFragment) ct.get("java_home_exec_path");
+    PathFragment javaHomeExecPath = (PathFragment) myInfo.getValue("java_home_exec_path");
     assertThat(javaHomeExecPath.getPathString()).isEqualTo("/foo/bar");
     @SuppressWarnings("unchecked")
-    PathFragment javaExecutableExecPath = (PathFragment) ct.get("java_executable_exec_path");
+    PathFragment javaExecutableExecPath =
+        (PathFragment) myInfo.getValue("java_executable_exec_path");
     assertThat(javaExecutableExecPath.getPathString()).startsWith("/foo/bar/bin/java");
     @SuppressWarnings("unchecked")
-    PathFragment javaHomeRunfilesPath = (PathFragment) ct.get("java_home_runfiles_path");
+    PathFragment javaHomeRunfilesPath = (PathFragment) myInfo.getValue("java_home_runfiles_path");
     assertThat(javaHomeRunfilesPath.getPathString()).isEqualTo("/foo/bar");
     @SuppressWarnings("unchecked")
-    PathFragment javaExecutableRunfiles = (PathFragment) ct.get("java_executable_runfiles_path");
+    PathFragment javaExecutableRunfiles =
+        (PathFragment) myInfo.getValue("java_executable_runfiles_path");
     assertThat(javaExecutableRunfiles.getPathString()).startsWith("/foo/bar/bin/java");
   }
 
@@ -134,9 +155,10 @@
 
     scratch.file(
         "a/rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _impl(ctx):",
         "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
-        "  return struct(",
+        "  return MyInfo(",
         "    java_home_exec_path = provider.java_home,",
         "    java_executable_exec_path = provider.java_executable_exec_path,",
         "    java_home_runfiles_path = provider.java_home_runfiles_path,",
@@ -147,17 +169,20 @@
     useConfiguration(
         "--javabase=//a:jvm", "--extra_toolchains=//a:all", "--platforms=//a:platform");
     ConfiguredTarget ct = getConfiguredTarget("//a:r");
+    StructImpl myInfo = getMyInfoFromTarget(ct);
     @SuppressWarnings("unchecked")
-    PathFragment javaHomeExecPath = (PathFragment) ct.get("java_home_exec_path");
+    PathFragment javaHomeExecPath = (PathFragment) myInfo.getValue("java_home_exec_path");
     assertThat(javaHomeExecPath.getPathString()).isEqualTo("a/foo/bar");
     @SuppressWarnings("unchecked")
-    PathFragment javaExecutableExecPath = (PathFragment) ct.get("java_executable_exec_path");
+    PathFragment javaExecutableExecPath =
+        (PathFragment) myInfo.getValue("java_executable_exec_path");
     assertThat(javaExecutableExecPath.getPathString()).startsWith("a/foo/bar/bin/java");
     @SuppressWarnings("unchecked")
-    PathFragment javaHomeRunfilesPath = (PathFragment) ct.get("java_home_runfiles_path");
+    PathFragment javaHomeRunfilesPath = (PathFragment) myInfo.getValue("java_home_runfiles_path");
     assertThat(javaHomeRunfilesPath.getPathString()).isEqualTo("a/foo/bar");
     @SuppressWarnings("unchecked")
-    PathFragment javaExecutableRunfiles = (PathFragment) ct.get("java_executable_runfiles_path");
+    PathFragment javaExecutableRunfiles =
+        (PathFragment) myInfo.getValue("java_executable_runfiles_path");
     assertThat(javaExecutableRunfiles.getPathString()).startsWith("a/foo/bar/bin/java");
   }
 
@@ -192,9 +217,10 @@
 
     scratch.file(
         "a/rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _impl(ctx):",
         "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
-        "  return struct(",
+        "  return MyInfo(",
         "    java_home_exec_path = provider.java_home,",
         "    java_executable_exec_path = provider.java_executable_exec_path,",
         "    java_home_runfiles_path = provider.java_home_runfiles_path,",
@@ -207,19 +233,22 @@
     // TODO(b/129637690): the runtime shouldn't be resolved in the host config
     ConfiguredTarget genrule = getHostConfiguredTarget("//a:gen");
     ConfiguredTarget ct = getConfiguredTarget("//a:r");
+    StructImpl myInfo = getMyInfoFromTarget(ct);
     @SuppressWarnings("unchecked")
-    PathFragment javaHomeExecPath = (PathFragment) ct.get("java_home_exec_path");
+    PathFragment javaHomeExecPath = (PathFragment) myInfo.getValue("java_home_exec_path");
     assertThat(javaHomeExecPath.getPathString())
         .isEqualTo(getGenfilesArtifact("foo/bar", genrule).getExecPathString());
     @SuppressWarnings("unchecked")
-    PathFragment javaExecutableExecPath = (PathFragment) ct.get("java_executable_exec_path");
+    PathFragment javaExecutableExecPath =
+        (PathFragment) myInfo.getValue("java_executable_exec_path");
     assertThat(javaExecutableExecPath.getPathString())
         .startsWith(getGenfilesArtifact("foo/bar/bin/java", genrule).getExecPathString());
     @SuppressWarnings("unchecked")
-    PathFragment javaHomeRunfilesPath = (PathFragment) ct.get("java_home_runfiles_path");
+    PathFragment javaHomeRunfilesPath = (PathFragment) myInfo.getValue("java_home_runfiles_path");
     assertThat(javaHomeRunfilesPath.getPathString()).isEqualTo("a/foo/bar");
     @SuppressWarnings("unchecked")
-    PathFragment javaExecutableRunfiles = (PathFragment) ct.get("java_executable_runfiles_path");
+    PathFragment javaExecutableRunfiles =
+        (PathFragment) myInfo.getValue("java_executable_runfiles_path");
     assertThat(javaExecutableRunfiles.getPathString()).startsWith("a/foo/bar/bin/java");
   }
 
@@ -244,7 +273,7 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase",
         "  )",
-        "  return struct()",
+        "  return []",
         "jrule = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -369,10 +398,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar]),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar]),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -482,10 +513,12 @@
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo],",
         "    javac_opts = ['-XDone -XDtwo'],",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar] + compilation_provider.source_jars),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar] + compilation_provider.source_jars)",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -542,10 +575,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar] + compilation_provider.source_jars),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar] + compilation_provider.source_jars),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -611,10 +646,12 @@
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
         "  result_provider = java_common.merge([compilation_provider, other_compilation_provider])",
-        "  return struct(",
-        "    files = depset([output_jar]),",
-        "    providers = [result_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar])",
+        "      ),",
+        "      result_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -662,10 +699,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar]),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar]),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -714,10 +753,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar]),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar]),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -768,10 +809,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_source_jar]),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_source_jar]),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -818,10 +861,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar]),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar]),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -918,7 +963,7 @@
         "      use_ijar = False,",
         "  )",
         "  java_info = java_common.merge([old, new])",
-        "  return struct(providers = [java_info])",
+        "  return [java_info]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  attrs = {",
@@ -1463,7 +1508,7 @@
         "foo/extension.bzl",
         "def _impl(ctx):",
         "  dep_params = ctx.attr.dep[JavaInfo]",
-        "  return struct(providers = [dep_params])",
+        "  return [dep_params]",
         "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
     scratch.file(
         "foo/BUILD",
@@ -1504,7 +1549,7 @@
         "foo/extension.bzl",
         "def _impl(ctx):",
         "  dep_params = ctx.attr.dep[JavaInfo]",
-        "  return struct(providers = [dep_params])",
+        "  return [dep_params]",
         "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
     scratch.file(
         "foo/BUILD",
@@ -1531,7 +1576,7 @@
         "foo/extension.bzl",
         "def _impl(ctx):",
         "  dep_params = ctx.attr.dep[JavaInfo]",
-        "  return struct(providers = [dep_params])",
+        "  return [dep_params]",
         "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
     scratch.file(
         "foo/BUILD",
@@ -1803,10 +1848,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar]),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar]),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -2203,10 +2250,12 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    files = depset([output_jar]),",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [",
+        "      DefaultInfo(",
+        "          files = depset([output_jar]),",
+        "      ),",
+        "      compilation_provider",
+        "  ]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -2246,9 +2295,7 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [compilation_provider]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  attrs = {",
@@ -2288,9 +2335,7 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [compilation_provider]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  attrs = {",
@@ -2334,9 +2379,7 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct(",
-        "    providers = [compilation_provider]",
-        "  )",
+        "  return [compilation_provider]",
         "java_custom_library = rule(",
         "  implementation = _impl,",
         "  attrs = {",
@@ -2413,7 +2456,7 @@
         "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
         "    host_javabase = ctx.attr._host_javabase",
         "  )",
-        "  return struct()",
+        "  return []",
         "jrule = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -2452,7 +2495,7 @@
         "    java_toolchain = ctx.attr._java_toolchain,",
         "    host_javabase = ctx.attr._host_javabase[java_common.JavaRuntimeInfo]",
         "  )",
-        "  return struct()",
+        "  return []",
         "jrule = rule(",
         "  implementation = _impl,",
         "  outputs = {",
@@ -2476,8 +2519,9 @@
     writeBuildFileForJavaToolchain();
     scratch.file(
         "a/rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _impl(ctx):",
-        "  return struct(",
+        "  return MyInfo(",
         "    javac_opts = java_common.default_javac_opts(",
         "        java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo])",
         "    )",
@@ -2492,7 +2536,8 @@
 
     ConfiguredTarget r = getConfiguredTarget("//a:r");
     @SuppressWarnings("unchecked") // Use an extra variable in order to suppress the warning.
-    SkylarkList<String> javacopts = (SkylarkList<String>) r.get("javac_opts");
+    SkylarkList<String> javacopts =
+        (SkylarkList<String>) getMyInfoFromTarget(r).getValue("javac_opts");
     assertThat(String.join(" ", javacopts)).contains("-source 6 -target 6");
   }
 
@@ -2501,8 +2546,9 @@
     writeBuildFileForJavaToolchain();
     scratch.file(
         "a/rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _impl(ctx):",
-        "  return struct(",
+        "  return MyInfo(",
         "    javac_opts = java_common.default_javac_opts(",
         "        java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo])",
         "    )",
@@ -2517,18 +2563,20 @@
 
     ConfiguredTarget r = getConfiguredTarget("//a:r");
     @SuppressWarnings("unchecked") // Use an extra variable in order to suppress the warning.
-    SkylarkList<String> javacopts = (SkylarkList<String>) r.get("javac_opts");
+    SkylarkList<String> javacopts =
+        (SkylarkList<String>) getMyInfoFromTarget(r).getValue("javac_opts");
     assertThat(String.join(" ", javacopts)).contains("-source 6 -target 6");
   }
 
   private boolean toolchainResolutionEnabled() throws Exception {
     scratch.file(
         "a/rule.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _impl(ctx):",
         "  toolchain_resolution_enabled ="
             + " java_common.is_java_toolchain_resolution_enabled_do_not_use(",
         "      ctx = ctx)",
-        "  return struct(",
+        "  return MyInfo(",
         "    toolchain_resolution_enabled = toolchain_resolution_enabled)",
         "toolchain_resolution_enabled = rule(",
         "  _impl,",
@@ -2541,7 +2589,8 @@
 
     ConfiguredTarget r = getConfiguredTarget("//a:r");
     @SuppressWarnings("unchecked") // Use an extra variable in order to suppress the warning.
-    boolean toolchainResolutionEnabled = (boolean) r.get("toolchain_resolution_enabled");
+    boolean toolchainResolutionEnabled =
+        (boolean) getMyInfoFromTarget(r).getValue("toolchain_resolution_enabled");
     return toolchainResolutionEnabled;
   }
 
@@ -2592,7 +2641,7 @@
         "a/rule.bzl",
         "def _impl(ctx):",
         "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
-        "  return struct(",
+        "  return DefaultInfo(",
         "    files = provider.files,",
         "  )",
         "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java
index 42a021e..5a68ab6 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/AppleBinaryTest.java
@@ -19,6 +19,7 @@
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Action;
@@ -29,7 +30,11 @@
 import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
 import com.google.devtools.build.lib.analysis.config.CompilationMode;
 import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
+import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.cmdline.RepositoryName;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
+import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
@@ -45,6 +50,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -85,6 +91,20 @@
   private static final ImmutableSet<String> COCOA_FEATURE_FLAGS =
       ImmutableSet.of(COCOA_FRAMEWORK_FLAG);
 
+  @Before
+  public void setupMyInfo() throws Exception {
+    scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");
+
+    scratch.file("myinfo/BUILD");
+  }
+
+  private StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget) throws Exception {
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.parseAbsolute("//myinfo:myinfo.bzl", ImmutableMap.of()), "MyInfo");
+    return (StructImpl) configuredTarget.get(key);
+  }
+
   @Test
   public void testOutputDirectoryWithMandatoryMinimumVersion() throws Exception {
     scratch.file("a/BUILD",
@@ -627,10 +647,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   provider = dep[apple_common.AppleDylibBinary]",
-        "   return struct(",
+        "   return MyInfo(",
         "      binary = provider.binary,",
         "      objc = provider.objc,",
         "      dep_dir = dir(dep),",
@@ -661,11 +682,12 @@
 
     useConfiguration("--ios_multi_cpus=armv7,arm64");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
-    assertThat(skylarkTarget.get("binary")).isInstanceOf(Artifact.class);
-    assertThat(skylarkTarget.get("objc")).isInstanceOf(ObjcProvider.class);
+    assertThat(myInfo.getValue("binary")).isInstanceOf(Artifact.class);
+    assertThat(myInfo.getValue("objc")).isInstanceOf(ObjcProvider.class);
 
-    List<String> depProviders = (List<String>) skylarkTarget.getValue("dep_dir");
+    List<String> depProviders = (List<String>) myInfo.getValue("dep_dir");
     assertThat(depProviders).doesNotContain("AppleExecutableBinary");
     assertThat(depProviders).doesNotContain("AppleLoadableBundleBinary");
   }
@@ -676,10 +698,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   provider = dep[apple_common.AppleExecutableBinary]",
-        "   return struct(",
+        "   return MyInfo(",
         "      binary = provider.binary,",
         "      objc = provider.objc,",
         "      dep_dir = dir(dep),",
@@ -710,11 +733,12 @@
 
     useConfiguration("--ios_multi_cpus=armv7,arm64");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
-    assertThat(skylarkTarget.get("binary")).isInstanceOf(Artifact.class);
-    assertThat(skylarkTarget.get("objc")).isInstanceOf(ObjcProvider.class);
+    assertThat(myInfo.getValue("binary")).isInstanceOf(Artifact.class);
+    assertThat(myInfo.getValue("objc")).isInstanceOf(ObjcProvider.class);
 
-    List<String> depProviders = (List<String>) skylarkTarget.get("dep_dir");
+    List<String> depProviders = (List<String>) myInfo.getValue("dep_dir");
     assertThat(depProviders).doesNotContain("AppleDylibBinary");
     assertThat(depProviders).doesNotContain("AppleLoadableBundleBinary");
   }
@@ -725,10 +749,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   provider = dep[apple_common.AppleLoadableBundleBinary]",
-        "   return struct(",
+        "   return MyInfo(",
         "      binary = provider.binary,",
         "      dep_dir = dir(dep),",
         "   )",
@@ -758,10 +783,11 @@
 
     useConfiguration("--ios_multi_cpus=armv7,arm64");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
-    assertThat((Artifact) skylarkTarget.get("binary")).isNotNull();
+    assertThat((Artifact) myInfo.getValue("binary")).isNotNull();
 
-    List<String> depProviders = (List<String>) skylarkTarget.get("dep_dir");
+    List<String> depProviders = (List<String>) myInfo.getValue("dep_dir");
     assertThat(depProviders).doesNotContain("AppleExecutableBinary");
     assertThat(depProviders).doesNotContain("AppleDylibBinary");
   }
@@ -1160,10 +1186,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   provider = dep[apple_common.AppleDebugOutputs]",
-        "   return struct(",
+        "   return MyInfo(",
         "      outputs_map=provider.outputs_map,",
         "   )",
         "test_rule = rule(implementation = _test_rule_impl,",
@@ -1198,7 +1225,7 @@
     @SuppressWarnings("unchecked")
     SkylarkDict<String, SkylarkDict<String, Artifact>> outputMap =
         (SkylarkDict<String, SkylarkDict<String, Artifact>>)
-            skylarkTarget.get("outputs_map");
+            getMyInfoFromTarget(skylarkTarget).getValue("outputs_map");
     return outputMap;
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java
index 1197016..46e2d71 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspectTest.java
@@ -16,10 +16,14 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
+import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.packages.util.MockObjcSupport;
 import com.google.devtools.build.lib.packages.util.MockProtoSupport;
 import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher;
@@ -210,9 +214,10 @@
     scratch.file("test_skylark/BUILD");
     scratch.file(
         "test_skylark/top_level_stub.bzl",
+        "MyInfo = provider()",
         "def top_level_stub_impl(ctx):",
         "  deps = hasattr(ctx.attr.deps[0], 'ObjcProto')",
-        "  return struct(dep = ctx.attr.deps[0])",
+        "  return MyInfo(dep = ctx.attr.deps[0])",
         "top_level_stub = rule(",
         "    top_level_stub_impl,",
         "    attrs = {",
@@ -245,7 +250,12 @@
 
     ConfiguredTarget topTarget = getConfiguredTarget("//bin:link_target");
 
-    ConfiguredTarget depTarget = (ConfiguredTarget) topTarget.get("dep");
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.parseAbsolute("//test_skylark:top_level_stub.bzl", ImmutableMap.of()), "MyInfo");
+    StructImpl info = (StructImpl) topTarget.get(key);
+
+    ConfiguredTarget depTarget = (ConfiguredTarget) info.getValue("dep");
     ObjcProtoProvider objcProtoProvider = depTarget.get(ObjcProtoProvider.SKYLARK_CONSTRUCTOR);
 
     assertThat(objcProtoProvider).isNotNull();
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
index 3ec56a8..9658534 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
@@ -17,12 +17,17 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.fail;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.ObjectArrays;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.SkylarkInfo;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
+import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.rules.apple.AppleToolchain;
 import com.google.devtools.build.lib.rules.apple.DottedVersion;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
@@ -30,6 +35,7 @@
 import com.google.devtools.build.lib.syntax.StarlarkSemantics;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.List;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -43,14 +49,29 @@
     return new ObjcProvider.Builder(StarlarkSemantics.DEFAULT_SEMANTICS);
   }
 
+  @Before
+  public void setupMyInfo() throws Exception {
+    scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");
+
+    scratch.file("myinfo/BUILD");
+  }
+
+  private StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget) throws Exception {
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.parseAbsolute("//myinfo:myinfo.bzl", ImmutableMap.of()), "MyInfo");
+    return (StructImpl) configuredTarget.get(key);
+  }
+
   @Test
   public void testSkylarkRuleCanDependOnNativeAppleRule() throws Exception {
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def my_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
-        "   return struct(",
+        "   return MyInfo(",
         "      found_libs = dep.objc.library,",
         "      found_hdrs = dep.objc.header,",
         "    )",
@@ -74,10 +95,9 @@
         ")");
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
-    SkylarkNestedSet skylarkLibraries =
-        (SkylarkNestedSet) skylarkTarget.get("found_libs");
-    SkylarkNestedSet skylarkHdrs =
-        (SkylarkNestedSet) skylarkTarget.get("found_hdrs");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
+    SkylarkNestedSet skylarkLibraries = (SkylarkNestedSet) myInfo.getValue("found_libs");
+    SkylarkNestedSet skylarkHdrs = (SkylarkNestedSet) myInfo.getValue("found_hdrs");
 
     assertThat(ActionsTestUtil.baseArtifactNames(skylarkLibraries.getSet(Artifact.class)))
         .contains("liblib.a");
@@ -93,7 +113,7 @@
         "def my_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   objc_provider = dep.objc",
-        "   return struct()",
+        "   return []",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {",
         "   'deps': attr.label_list(allow_files = False, mandatory = False),",
@@ -136,10 +156,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def my_rule_impl(ctx):",
         "   cc_has_provider = hasattr(ctx.attr.deps[0], 'objc')",
         "   objc_has_provider = hasattr(ctx.attr.deps[1], 'objc')",
-        "   return struct(cc_has_provider=cc_has_provider, objc_has_provider=objc_has_provider)",
+        "   return MyInfo(cc_has_provider=cc_has_provider, objc_has_provider=objc_has_provider)",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {",
         "   'deps': attr.label_list(allow_files = False, mandatory = False),",
@@ -163,10 +184,9 @@
         "    srcs = ['a.cc'],",
         ")");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
-    boolean ccResult =
-        (boolean) skylarkTarget.get("cc_has_provider");
-    boolean objcResult =
-        (boolean) skylarkTarget.get("objc_has_provider");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
+    boolean ccResult = (boolean) myInfo.getValue("cc_has_provider");
+    boolean objcResult = (boolean) myInfo.getValue("objc_has_provider");
     assertThat(ccResult).isFalse();
     assertThat(objcResult).isTrue();
   }
@@ -179,7 +199,7 @@
         "def my_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   objc_provider = dep.objc",
-        "   return struct(objc=objc_provider)",
+        "   return [objc_provider]",
         "swift_library = rule(implementation = my_rule_impl,",
         "   attrs = {",
         "   'deps': attr.label_list(allow_files = False, mandatory = False, providers = ['objc'])",
@@ -222,7 +242,7 @@
         "examples/rule/apple_rules.bzl",
         "def my_rule_impl(ctx):",
         "   objc_provider = apple_common.new_objc_provider(define=depset(['mock_define']))",
-        "   return struct(objc=objc_provider)",
+        "   return [objc_provider]",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {})");
 
@@ -258,6 +278,7 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def swift_binary_impl(ctx):",
         "   xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]",
         "   cpu = ctx.fragments.apple.ios_cpu()",
@@ -271,7 +292,7 @@
         "   single_arch_cpu = ctx.fragments.apple.single_arch_cpu",
         "   platform_type = single_arch_platform.platform_type",
         "   bitcode_mode = ctx.fragments.apple.bitcode_mode",
-        "   return struct(",
+        "   return MyInfo(",
         "      cpu=cpu,",
         "      env=env,",
         "      xcode_version=str(xcode_version),",
@@ -306,24 +327,23 @@
 
     useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386", "--xcode_version=7.3");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
-
-    Object iosCpu = skylarkTarget.get("cpu");
+    Object iosCpu = myInfo.getValue("cpu");
     @SuppressWarnings("unchecked")
-    SkylarkDict<String, String> env =
-        (SkylarkDict<String, String>) skylarkTarget.get("env");
-    Object sdkVersion = skylarkTarget.get("sdk_version");
+    SkylarkDict<String, String> env = (SkylarkDict<String, String>) myInfo.getValue("env");
+    Object sdkVersion = myInfo.getValue("sdk_version");
 
     assertThat(iosCpu).isEqualTo("i386");
     assertThat(env).containsEntry("APPLE_SDK_PLATFORM", "iPhoneSimulator");
     assertThat(env).containsEntry("APPLE_SDK_VERSION_OVERRIDE", "8.4");
     assertThat(sdkVersion).isEqualTo("8.4");
-    assertThat(skylarkTarget.get("xcode_version")).isEqualTo("7.3");
-    assertThat(skylarkTarget.get("single_arch_platform")).isEqualTo("IOS_SIMULATOR");
-    assertThat(skylarkTarget.get("single_arch_cpu")).isEqualTo("i386");
-    assertThat(skylarkTarget.get("platform_type")).isEqualTo("ios");
-    assertThat(skylarkTarget.get("bitcode_mode")).isEqualTo("none");
-    assertThat(skylarkTarget.get("dead_code_report")).isEqualTo("None");
+    assertThat(myInfo.getValue("xcode_version")).isEqualTo("7.3");
+    assertThat(myInfo.getValue("single_arch_platform")).isEqualTo("IOS_SIMULATOR");
+    assertThat(myInfo.getValue("single_arch_cpu")).isEqualTo("i386");
+    assertThat(myInfo.getValue("platform_type")).isEqualTo("ios");
+    assertThat(myInfo.getValue("bitcode_mode")).isEqualTo("none");
+    assertThat(myInfo.getValue("dead_code_report")).isEqualTo("None");
   }
 
   @Test
@@ -331,9 +351,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def swift_binary_impl(ctx):",
         "   dead_code_report = ctx.attr._dead_code_report",
-        "   return struct(",
+        "   return MyInfo(",
         "      dead_code_report=str(dead_code_report),",
         "   )",
         "swift_binary = rule(",
@@ -358,7 +379,7 @@
     useConfiguration();
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    assertThat(skylarkTarget.get("dead_code_report")).isEqualTo("None");
+    assertThat(getMyInfoFromTarget(skylarkTarget).getValue("dead_code_report")).isEqualTo("None");
   }
 
   @Test
@@ -366,11 +387,12 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def dead_code_report_impl(ctx):",
-        "   return struct(foo='bar')",
+        "   return MyInfo(foo='bar')",
         "def swift_binary_impl(ctx):",
-        "   dead_code_report = ctx.attr._dead_code_report.foo",
-        "   return struct(",
+        "   dead_code_report = ctx.attr._dead_code_report[MyInfo].foo",
+        "   return MyInfo(",
         "      dead_code_report=dead_code_report,",
         "   )",
         "dead_code_report = rule(",
@@ -399,7 +421,7 @@
     useConfiguration("--j2objc_dead_code_report=//examples/apple_skylark:dead_code_report");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    assertThat(skylarkTarget.get("dead_code_report")).isEqualTo("bar");
+    assertThat(getMyInfoFromTarget(skylarkTarget).getValue("dead_code_report")).isEqualTo("bar");
   }
 
   @Test
@@ -407,9 +429,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def swift_binary_impl(ctx):",
         "   j2objc_flags = ctx.fragments.j2objc.translation_flags",
-        "   return struct(",
+        "   return MyInfo(",
         "      j2objc_flags=j2objc_flags,",
         "   )",
         "swift_binary = rule(",
@@ -430,7 +453,7 @@
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
     @SuppressWarnings("unchecked")
-    List<String> flags = (List<String>) skylarkTarget.get("j2objc_flags");
+    List<String> flags = (List<String>) getMyInfoFromTarget(skylarkTarget).getValue("j2objc_flags");
     assertThat(flags).contains("-DTestJ2ObjcFlag");
     assertThat(flags).doesNotContain("-unspecifiedFlag");
   }
@@ -440,9 +463,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   platform = ctx.fragments.apple.ios_cpu_platform()",
-        "   return struct(",
+        "   return MyInfo(",
         "      name=platform.name_in_plist,",
         "   )",
         "test_rule = rule(",
@@ -461,7 +485,7 @@
     useConfiguration("--cpu=ios_i386");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    Object name = skylarkTarget.get("name");
+    Object name = getMyInfoFromTarget(skylarkTarget).getValue("name");
     assertThat(name).isEqualTo("iPhoneSimulator");
   }
 
@@ -470,12 +494,13 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def swift_binary_impl(ctx):",
         "   apple_toolchain = apple_common.apple_toolchain()",
         "   sdk_dir = apple_toolchain.sdk_dir()",
         "   platform_developer_framework_dir = \\",
         "       apple_toolchain.platform_developer_framework_dir(ctx.fragments.apple)",
-        "   return struct(",
+        "   return MyInfo(",
         "      platform_developer_framework_dir=platform_developer_framework_dir,",
         "      sdk_dir=sdk_dir,",
         "   )",
@@ -495,11 +520,10 @@
 
     useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
-    String platformDevFrameworksDir =
-        (String)
-            skylarkTarget.get("platform_developer_framework_dir");
-    String sdkDir = (String) skylarkTarget.get("sdk_dir");
+    String platformDevFrameworksDir = (String) myInfo.getValue("platform_developer_framework_dir");
+    String sdkDir = (String) myInfo.getValue("sdk_dir");
 
     assertThat(platformDevFrameworksDir)
         .isEqualTo(
@@ -513,6 +537,7 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def swift_binary_impl(ctx):",
         "   xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]",
         "   ios_sdk_version = xcode_config.sdk_version_for_platform\\",
@@ -529,7 +554,7 @@
         "(apple_common.platform_type.watchos)",
         "   tvos_minimum_os = xcode_config.minimum_os_for_platform_type\\",
         "(apple_common.platform_type.tvos)",
-        "   return struct(",
+        "   return MyInfo(",
         "      ios_sdk_version=str(ios_sdk_version),",
         "      watchos_sdk_version=str(watchos_sdk_version),",
         "      tvos_sdk_version=str(tvos_sdk_version),",
@@ -560,29 +585,30 @@
         "--tvos_sdk_version=3.1", "--tvos_minimum_os=3.0",
         "--macos_sdk_version=4.1");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
+    assertThat(myInfo.getValue("ios_sdk_version")).isEqualTo("1.1");
+    assertThat(myInfo.getValue("ios_minimum_os")).isEqualTo("1.0");
+    assertThat(myInfo.getValue("watchos_sdk_version")).isEqualTo("2.1");
+    assertThat(myInfo.getValue("watchos_minimum_os")).isEqualTo("2.0");
+    assertThat(myInfo.getValue("tvos_sdk_version")).isEqualTo("3.1");
+    assertThat(myInfo.getValue("tvos_minimum_os")).isEqualTo("3.0");
+    assertThat(myInfo.getValue("macos_sdk_version")).isEqualTo("4.1");
 
-    assertThat(skylarkTarget.get("ios_sdk_version")).isEqualTo("1.1");
-    assertThat(skylarkTarget.get("ios_minimum_os")).isEqualTo("1.0");
-    assertThat(skylarkTarget.get("watchos_sdk_version")).isEqualTo("2.1");
-    assertThat(skylarkTarget.get("watchos_minimum_os")).isEqualTo("2.0");
-    assertThat(skylarkTarget.get("tvos_sdk_version")).isEqualTo("3.1");
-    assertThat(skylarkTarget.get("tvos_minimum_os")).isEqualTo("3.0");
-    assertThat(skylarkTarget.get("macos_sdk_version")).isEqualTo("4.1");
-    
     useConfiguration("--ios_sdk_version=1.1",
         "--watchos_sdk_version=2.1",
         "--tvos_sdk_version=3.1",
         "--macos_sdk_version=4.1");
     skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    myInfo = getMyInfoFromTarget(skylarkTarget);
 
-    assertThat(skylarkTarget.get("ios_sdk_version")).isEqualTo("1.1");
-    assertThat(skylarkTarget.get("ios_minimum_os")).isEqualTo("1.1");
-    assertThat(skylarkTarget.get("watchos_sdk_version")).isEqualTo("2.1");
-    assertThat(skylarkTarget.get("watchos_minimum_os")).isEqualTo("2.1");
-    assertThat(skylarkTarget.get("tvos_sdk_version")).isEqualTo("3.1");
-    assertThat(skylarkTarget.get("tvos_minimum_os")).isEqualTo("3.1");
-    assertThat(skylarkTarget.get("macos_sdk_version")).isEqualTo("4.1");
+    assertThat(myInfo.getValue("ios_sdk_version")).isEqualTo("1.1");
+    assertThat(myInfo.getValue("ios_minimum_os")).isEqualTo("1.1");
+    assertThat(myInfo.getValue("watchos_sdk_version")).isEqualTo("2.1");
+    assertThat(myInfo.getValue("watchos_minimum_os")).isEqualTo("2.1");
+    assertThat(myInfo.getValue("tvos_sdk_version")).isEqualTo("3.1");
+    assertThat(myInfo.getValue("tvos_minimum_os")).isEqualTo("3.1");
+    assertThat(myInfo.getValue("macos_sdk_version")).isEqualTo("4.1");
   }
 
   @Test
@@ -590,6 +616,7 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/objc_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def swift_binary_impl(ctx):",
         "   copts = ctx.fragments.objc.copts",
         "   compilation_mode_copts = ctx.fragments.objc.copts_for_current_compilation_mode",
@@ -597,7 +624,7 @@
         "   ios_simulator_version = ctx.fragments.objc.ios_simulator_version",
         "   signing_certificate_name = ctx.fragments.objc.signing_certificate_name",
         "   generate_dsym = ctx.fragments.objc.generate_dsym",
-        "   return struct(",
+        "   return MyInfo(",
         "      copts=copts,",
         "      compilation_mode_copts=compilation_mode_copts,",
         "      ios_simulator_device=ios_simulator_device,",
@@ -627,15 +654,16 @@
         "--ios_signing_cert_name='Apple Developer'",
         "--apple_generate_dsym");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/objc_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
     @SuppressWarnings("unchecked")
-    List<String> copts = (List<String>) skylarkTarget.get("copts");
+    List<String> copts = (List<String>) myInfo.getValue("copts");
     @SuppressWarnings("unchecked")
-    List<String> compilationModeCopts = (List<String>) skylarkTarget.get("compilation_mode_copts");
-    Object iosSimulatorDevice = skylarkTarget.get("ios_simulator_device");
-    Object iosSimulatorVersion = skylarkTarget.get("ios_simulator_version");
-    Object signingCertificateName = skylarkTarget.get("signing_certificate_name");
-    Boolean generateDsym = (Boolean) skylarkTarget.get("generate_dsym");
+    List<String> compilationModeCopts = (List<String>) myInfo.getValue("compilation_mode_copts");
+    Object iosSimulatorDevice = myInfo.getValue("ios_simulator_device");
+    Object iosSimulatorVersion = myInfo.getValue("ios_simulator_version");
+    Object signingCertificateName = myInfo.getValue("signing_certificate_name");
+    Boolean generateDsym = (Boolean) myInfo.getValue("generate_dsym");
 
     assertThat(copts).contains("-DTestObjcCopt");
     assertThat(compilationModeCopts).containsExactlyElementsIn(ObjcConfiguration.OPT_COPTS);
@@ -650,9 +678,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/objc_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def my_rule_impl(ctx):",
         "   signing_certificate_name = ctx.fragments.objc.signing_certificate_name",
-        "   return struct(",
+        "   return MyInfo(",
         "      signing_certificate_name=str(signing_certificate_name),",
         "   )",
         "my_rule = rule(",
@@ -671,7 +700,8 @@
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/objc_skylark:my_target");
 
-    Object signingCertificateName = skylarkTarget.get("signing_certificate_name");
+    Object signingCertificateName =
+        getMyInfoFromTarget(skylarkTarget).getValue("signing_certificate_name");
     assertThat(signingCertificateName).isEqualTo("None");
   }
 
@@ -680,9 +710,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/objc_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def test_rule_impl(ctx):",
         "   uses_device_debug_entitlements = ctx.fragments.objc.uses_device_debug_entitlements",
-        "   return struct(",
+        "   return MyInfo(",
         "      uses_device_debug_entitlements=uses_device_debug_entitlements,",
         "   )",
         "test_rule = rule(",
@@ -702,8 +733,8 @@
     useConfiguration("--compilation_mode=dbg");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/objc_skylark:my_target");
 
-    boolean usesDeviceDebugEntitlements = (boolean) skylarkTarget
-        .get("uses_device_debug_entitlements");
+    boolean usesDeviceDebugEntitlements =
+        (boolean) getMyInfoFromTarget(skylarkTarget).getValue("uses_device_debug_entitlements");
     assertThat(usesDeviceDebugEntitlements).isTrue();
   }
 
@@ -712,9 +743,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/objc_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def test_rule_impl(ctx):",
         "   uses_device_debug_entitlements = ctx.fragments.objc.uses_device_debug_entitlements",
-        "   return struct(",
+        "   return MyInfo(",
         "      uses_device_debug_entitlements=uses_device_debug_entitlements,",
         "   )",
         "test_rule = rule(",
@@ -736,8 +768,8 @@
         "--nodevice_debug_entitlements");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/objc_skylark:my_target");
 
-    boolean usesDeviceDebugEntitlements = (boolean) skylarkTarget
-        .get("uses_device_debug_entitlements");
+    boolean usesDeviceDebugEntitlements =
+        (boolean) getMyInfoFromTarget(skylarkTarget).getValue("uses_device_debug_entitlements");
     assertThat(usesDeviceDebugEntitlements).isFalse();
   }
 
@@ -746,9 +778,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/objc_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def test_rule_impl(ctx):",
         "   uses_device_debug_entitlements = ctx.fragments.objc.uses_device_debug_entitlements",
-        "   return struct(",
+        "   return MyInfo(",
         "      uses_device_debug_entitlements=uses_device_debug_entitlements,",
         "   )",
         "test_rule = rule(",
@@ -768,8 +801,8 @@
     useConfiguration("--compilation_mode=opt");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/objc_skylark:my_target");
 
-    boolean usesDeviceDebugEntitlements = (boolean) skylarkTarget
-        .get("uses_device_debug_entitlements");
+    boolean usesDeviceDebugEntitlements =
+        (boolean) getMyInfoFromTarget(skylarkTarget).getValue("uses_device_debug_entitlements");
     assertThat(usesDeviceDebugEntitlements).isFalse();
   }
 
@@ -786,7 +819,7 @@
               "})"
             },
             String.class);
-    
+
     scratch.file("examples/rule/BUILD");
     scratch.file("examples/rule/objc_rules.bzl", impl);
     scratch.file(
@@ -814,7 +847,7 @@
             "   linkopts = depset(['somelinkopt'])",
             "   created_provider = apple_common.new_objc_provider\\",
             "(define=defines, linkopt=linkopts)",
-            "   return struct(objc=created_provider)");
+            "   return [created_provider]");
 
     Iterable<String> foundLinkopts =
         skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.LINKOPT);
@@ -837,7 +870,7 @@
             "   link_inputs = depset([file])",
             "   created_provider = apple_common.new_objc_provider\\",
             "(link_inputs=link_inputs)",
-            "   return struct(objc=created_provider)");
+            "   return [created_provider]");
 
     Iterable<Artifact> foundLinkInputs =
         skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.LINK_INPUTS);
@@ -849,7 +882,7 @@
     ConfiguredTarget skylarkTarget =
         createObjcProviderSkylarkTarget(
             "   created_provider = apple_common.new_objc_provider(uses_swift=True)",
-            "   return struct(objc=created_provider)");
+            "   return [created_provider]");
 
     boolean usesSwift =
         skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).is(ObjcProvider.Flag.USES_SWIFT);
@@ -864,7 +897,7 @@
             "   includes = depset(['path1', 'path_dir/path2', 'path_dir1/path_dir2/path3'])",
             "   created_provider = apple_common.new_objc_provider\\",
             "(include=includes)",
-            "   return struct(objc=created_provider)");
+            "   return [created_provider]");
 
     Iterable<PathFragment> foundIncludes =
         skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.INCLUDE);
@@ -886,7 +919,7 @@
             "(include=strict_includes)",
             "   created_provider = apple_common.new_objc_provider\\",
             "(include=propagated_includes, direct_dep_providers=[strict_provider])",
-            "   return struct(objc=created_provider)");
+            "   return [created_provider]");
 
     ObjcProvider skylarkProvider = skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
     ObjcProvider skylarkProviderDirectDepender =
@@ -910,54 +943,6 @@
             "   define = depset(['define_from_impl'])",
             "   created_provider = apple_common.new_objc_provider\\",
             "(providers=[dep.objc], define=define)",
-            "   return struct(objc=created_provider)");
-
-    Iterable<String> foundStrings =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.DEFINE);
-
-    assertThat(foundStrings).containsExactly("define_from_dep", "define_from_impl");
-  }
-
-  @Test
-  public void testRuleReturnsObjcProviderDirectly() throws Exception {
-    ConfiguredTarget skylarkTarget =
-        createObjcProviderSkylarkTarget(
-            "   dep = ctx.attr.deps[0]",
-            "   define = depset(['define_from_impl'])",
-            "   created_provider = apple_common.new_objc_provider\\",
-            "(providers=[dep.objc], define=define)",
-            "   return created_provider");
-
-    Iterable<String> foundStrings =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.DEFINE);
-
-    assertThat(foundStrings).containsExactly("define_from_dep", "define_from_impl");
-  }
-
-  @Test
-  public void testRuleReturnsObjcProviderUnderProvidersAttribute() throws Exception {
-    ConfiguredTarget skylarkTarget =
-        createObjcProviderSkylarkTarget(
-            "   dep = ctx.attr.deps[0]",
-            "   define = depset(['define_from_impl'])",
-            "   created_provider = apple_common.new_objc_provider\\",
-            "(providers=[dep.objc], define=define)",
-            "   return struct(providers=[created_provider])");
-
-    Iterable<String> foundStrings =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.DEFINE);
-
-    assertThat(foundStrings).containsExactly("define_from_dep", "define_from_impl");
-  }
-
-  @Test
-  public void testRuleReturnsObjcProviderInList() throws Exception {
-    ConfiguredTarget skylarkTarget =
-        createObjcProviderSkylarkTarget(
-            "   dep = ctx.attr.deps[0]",
-            "   define = depset(['define_from_impl'])",
-            "   created_provider = apple_common.new_objc_provider\\",
-            "(providers=[dep.objc], define=define)",
             "   return [created_provider]");
 
     Iterable<String> foundStrings =
@@ -971,7 +956,7 @@
     try {
       createObjcProviderSkylarkTarget(
           "   created_provider = apple_common.new_objc_provider(foo=depset(['bar']))",
-          "   return struct(objc=created_provider)");
+          "   return created_provider");
       fail("Should throw AssertionError");
     } catch (AssertionError e) {
       assertThat(e)
@@ -985,7 +970,7 @@
     try {
       createObjcProviderSkylarkTarget(
           "   created_provider = apple_common.new_objc_provider(library='bar')",
-          "   return struct(objc=created_provider)");
+          "   return created_provider");
       fail("Should throw AssertionError");
     } catch (AssertionError e) {
       assertThat(e)
@@ -999,7 +984,7 @@
     try {
       createObjcProviderSkylarkTarget(
           "   created_provider = apple_common.new_objc_provider(library=depset(['bar']))",
-          "   return struct(objc=created_provider)");
+          "   return created_provider");
       fail("Should throw AssertionError");
     } catch (AssertionError e) {
       assertThat(e)
@@ -1014,7 +999,7 @@
     try {
       createObjcProviderSkylarkTarget(
           "   created_provider = apple_common.new_objc_provider(providers='bar')",
-          "   return struct(objc=created_provider)");
+          "   return created_provider");
       fail("Should throw AssertionError");
     } catch (AssertionError e) {
       assertThat(e)
@@ -1028,7 +1013,7 @@
     try {
       createObjcProviderSkylarkTarget(
           "   created_provider = apple_common.new_objc_provider(providers=['bar'])",
-          "   return struct(objc=created_provider)");
+          "   return created_provider");
       fail("Should throw AssertionError");
     } catch (AssertionError e) {
       assertThat(e)
@@ -1042,9 +1027,10 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def swift_binary_impl(ctx):",
         "   objc_provider = ctx.attr.deps[0].objc",
-        "   return struct(",
+        "   return MyInfo(",
         "      empty_value=objc_provider.include,",
         "   )",
         "swift_binary = rule(",
@@ -1069,8 +1055,7 @@
         ")");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
     SkylarkNestedSet emptyValue =
-        (SkylarkNestedSet)
-            skylarkTarget.get("empty_value");
+        (SkylarkNestedSet) getMyInfoFromTarget(skylarkTarget).getValue("empty_value");
     assertThat(emptyValue.toCollection()).isEmpty();
   }
 
@@ -1079,10 +1064,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   objc_provider = dep.objc",
-        "   return struct(",
+        "   return MyInfo(",
         "      sdk_frameworks=objc_provider.sdk_framework,",
         "   )",
         "test_rule = rule(implementation = _test_rule_impl,",
@@ -1106,8 +1092,8 @@
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    SkylarkNestedSet sdkFrameworks = (SkylarkNestedSet)
-        skylarkTarget.get("sdk_frameworks");
+    SkylarkNestedSet sdkFrameworks =
+        (SkylarkNestedSet) getMyInfoFromTarget(skylarkTarget).getValue("sdk_frameworks");
     assertThat(sdkFrameworks.toCollection()).containsAllOf("Accelerate", "GLKit");
   }
 
@@ -1116,12 +1102,13 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   apple = ctx.fragments.apple",
         "   ios_platform = apple.multi_arch_platform(apple_common.platform_type.ios)",
         "   watchos_platform = apple.multi_arch_platform(apple_common.platform_type.watchos)",
         "   tvos_platform = apple.multi_arch_platform(apple_common.platform_type.tvos)",
-        "   return struct(",
+        "   return MyInfo(",
         "      ios_platform=str(ios_platform),",
         "      watchos_platform=str(watchos_platform),",
         "      tvos_platform=str(tvos_platform),",
@@ -1142,13 +1129,11 @@
         "--watchos_cpus=armv7k",
         "--tvos_cpus=arm64");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
 
-    Object iosPlatform =
-        skylarkTarget.get("ios_platform");
-    Object watchosPlatform =
-        skylarkTarget.get("watchos_platform");
-    Object tvosPlatform =
-        skylarkTarget.get("tvos_platform");
+    Object iosPlatform = myInfo.getValue("ios_platform");
+    Object watchosPlatform = myInfo.getValue("watchos_platform");
+    Object tvosPlatform = myInfo.getValue("tvos_platform");
 
     assertThat(iosPlatform).isEqualTo("IOS_DEVICE");
     assertThat(watchosPlatform).isEqualTo("WATCHOS_DEVICE");
@@ -1160,10 +1145,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   apple = ctx.fragments.apple",
         "   platform = apple.multi_arch_platform(apple_common.platform_type.ios)",
-        "   return struct(",
+        "   return MyInfo(",
         "      is_device=platform.is_device,",
         "   )",
         "test_rule = rule(implementation = _test_rule_impl,",
@@ -1181,8 +1167,7 @@
         "--ios_multi_cpus=arm64,armv7");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    Boolean isDevice =
-        (Boolean) skylarkTarget.get("is_device");
+    Boolean isDevice = (Boolean) getMyInfoFromTarget(skylarkTarget).getValue("is_device");
     assertThat(isDevice).isTrue();
   }
 
@@ -1191,10 +1176,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   apple = ctx.fragments.apple",
         "   platform = apple.multi_arch_platform(apple_common.platform_type.ios)",
-        "   return struct(",
+        "   return MyInfo(",
         "      is_device=platform.is_device,",
         "   )",
         "test_rule = rule(implementation = _test_rule_impl,",
@@ -1210,8 +1196,7 @@
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    Boolean isDevice =
-        (Boolean) skylarkTarget.get("is_device");
+    Boolean isDevice = (Boolean) getMyInfoFromTarget(skylarkTarget).getValue("is_device");
     assertThat(isDevice).isFalse();
   }
 
@@ -1232,9 +1217,10 @@
         "exports_files(['test_artifact'])");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   version = apple_common.dotted_version('5.4')",
-        "   return struct(",
+        "   return MyInfo(",
         "       version=version",
         "   )",
         "test_rule = rule(implementation = _test_rule_impl)");
@@ -1249,7 +1235,7 @@
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    DottedVersion version = (DottedVersion) skylarkTarget.get("version");
+    DottedVersion version = (DottedVersion) getMyInfoFromTarget(skylarkTarget).getValue("version");
     assertThat(version).isEqualTo(DottedVersion.fromString("5.4"));
   }
 
@@ -1259,9 +1245,10 @@
         "exports_files(['test_artifact'])");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
         "   version = apple_common.dotted_version('hello')",
-        "   return struct(",
+        "   return MyInfo(",
         "       version=version",
         "   )",
         "test_rule = rule(implementation = _test_rule_impl)");
@@ -1296,7 +1283,7 @@
         "def my_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   objc_provider = dep[apple_common.Objc]",
-        "   return struct(objc=objc_provider)",
+        "   return objc_provider",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {",
         "   'deps': attr.label_list(allow_files = False, mandatory = False),",
@@ -1325,12 +1312,13 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def my_rule_impl(ctx):",
         "   return_kwargs = {}",
         "   for cpu_value in ctx.split_attr.deps:",
         "     for child_target in ctx.split_attr.deps[cpu_value]:",
         "       return_kwargs[cpu_value] = struct(objc=child_target.objc)",
-        "   return struct(**return_kwargs)",
+        "   return MyInfo(**return_kwargs)",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {",
         "       'deps': attr.label_list(cfg=apple_common.multi_arch_split, providers=[['objc']]),",
@@ -1357,10 +1345,11 @@
 
     useConfiguration("--ios_multi_cpus=armv7,arm64");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
-    ObjcProvider armv7Objc = ((SkylarkInfo) skylarkTarget.get("ios_armv7"))
-        .getValue("objc", ObjcProvider.class);
-    ObjcProvider arm64Objc = ((SkylarkInfo) skylarkTarget.get("ios_arm64"))
-        .getValue("objc", ObjcProvider.class);
+    StructImpl myInfo = getMyInfoFromTarget(skylarkTarget);
+    ObjcProvider armv7Objc =
+        ((SkylarkInfo) myInfo.getValue("ios_armv7")).getValue("objc", ObjcProvider.class);
+    ObjcProvider arm64Objc =
+        ((SkylarkInfo) myInfo.getValue("ios_arm64")).getValue("objc", ObjcProvider.class);
     assertThat(armv7Objc).isNotNull();
     assertThat(arm64Objc).isNotNull();
     assertThat(Iterables.getOnlyElement(armv7Objc.getObjcLibraries()).getExecPathString())
@@ -1378,7 +1367,7 @@
         "   file = ctx.actions.declare_file('foo.ast')",
         "   ctx.actions.run_shell(outputs=[file], command='echo')",
         "   objc_provider = apple_common.new_objc_provider(xib=depset([file]))",
-        "   return struct(objc=objc_provider)",
+        "   return objc_provider",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {})");
 
@@ -1409,7 +1398,7 @@
         "   file = ctx.actions.declare_file('foo.ast')",
         "   ctx.actions.run_shell(outputs=[file], command='echo')",
         "   objc_provider = apple_common.new_objc_provider(xib=depset([file]))",
-        "   return struct(objc=objc_provider)",
+        "   return objc_provider",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {})");
 
@@ -1435,10 +1424,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def my_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   objc_provider = dep[apple_common.Objc]",
-        "   return struct(strings=str(objc_provider.strings))",
+        "   return MyInfo(strings=str(objc_provider.strings))",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {",
         "      'deps': attr.label_list(providers = ['objc'])})");
@@ -1470,10 +1460,11 @@
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def my_rule_impl(ctx):",
         "   dep = ctx.attr.deps[0]",
         "   objc_provider = dep[apple_common.Objc]",
-        "   return struct(strings=str(objc_provider.strings))",
+        "   return MyInfo(strings=str(objc_provider.strings))",
         "my_rule = rule(implementation = my_rule_impl,",
         "   attrs = {",
         "      'deps': attr.label_list(providers = ['objc'])})");
@@ -1496,15 +1487,16 @@
     setSkylarkSemanticsOptions("--incompatible_disable_objc_provider_resources=false");
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    assertThat(skylarkTarget.get("strings")).isEqualTo("depset([])");
+    assertThat(getMyInfoFromTarget(skylarkTarget).getValue("strings")).isEqualTo("depset([])");
   }
 
   private void checkSkylarkRunMemleaksWithExpectedValue(boolean expectedValue) throws Exception {
     scratch.file("examples/rule/BUILD");
     scratch.file(
         "examples/rule/apple_rules.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _test_rule_impl(ctx):",
-        "   return struct(run_memleaks = ctx.fragments.objc.run_memleaks)",
+        "   return MyInfo(run_memleaks = ctx.fragments.objc.run_memleaks)",
         "test_rule = rule(implementation = _test_rule_impl,",
         "   fragments = ['objc'],",
         "   attrs = {},",
@@ -1520,16 +1512,17 @@
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    boolean runMemleaks = (boolean) skylarkTarget.get("run_memleaks");
+    boolean runMemleaks = (boolean) getMyInfoFromTarget(skylarkTarget).getValue("run_memleaks");
     assertThat(runMemleaks).isEqualTo(expectedValue);
   }
 
   private void addDummyObjcProviderRule(String name) throws Exception {
     scratch.file(
         "fx/defs.bzl",
+        "load('//myinfo:myinfo.bzl', 'MyInfo')",
         "def _my_rule_impl(ctx):",
         "  objc = apple_common.new_objc_provider()",
-        String.format("  return struct(names=objc.%s)", name),
+        String.format("  return MyInfo(names=objc.%s)", name),
         "my_rule = rule(implementation = _my_rule_impl,",
         "   attrs = {})");
     scratch.file("fx/BUILD", "load(':defs.bzl', 'my_rule')", "my_rule(name = 'lib')");