bazel syntax: abolish Environment.StarlarkContext

The bulk of this change eliminates parameters of type
StarlarkContext in annotated methods, replacing them
by Environment parameters if not already present.
From the Environment, the BazelStarlarkContext can
be retrieved using getThreadLocal.

The only interesting parts are:

Environment: delete {get,set}StarlarkContext;
use {get,set}ThreadLocal instead.
Also, sprinkle 'private' keywords.

Label: store the HasRepoMapping as a thread-local.
Its value is an alias for the BazelStarlarkContext, but
we can't mention that type down here.

BazelStarlarkContext: define and use BSC.from(Environment),
which loads the Bazel info from a Starlark thread,
and BSC.storeInThread(Environment), which stores it,
plus the Label.RepoMapping, so we don't forget it.

ConfiguredRuleClassProvider: inline one flavor of
createSkylarkRuleClassEnvironment into the other.
PiperOrigin-RevId: 271039685
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
index c11d315..0eb63f0 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -881,53 +881,34 @@
     return mapBuilder.build();
   }
 
-  private Environment createSkylarkRuleClassEnvironment(
-      Mutability mutability,
-      GlobalFrame globals,
-      StarlarkSemantics starlarkSemantics,
-      EventHandler eventHandler,
-      String astFileContentHashCode,
-      Map<String, Extension> importMap,
-      ImmutableMap<RepositoryName, RepositoryName> repoMapping,
-      Label callerLabel) {
-    BazelStarlarkContext context =
-        new BazelStarlarkContext(
-            toolsRepository,
-            configurationFragmentMap,
-            repoMapping,
-            new SymbolGenerator<>(callerLabel),
-            /* analysisRuleLabel= */ null);
-    Environment env =
-        Environment.builder(mutability)
-            .setGlobals(globals)
-            .setSemantics(starlarkSemantics)
-            .setEventHandler(eventHandler)
-            .setFileContentHashCode(astFileContentHashCode)
-            .setStarlarkContext(context)
-            .setImportedExtensions(importMap)
-            .build();
-    SkylarkUtils.setPhase(env, Phase.LOADING);
-    return env;
-  }
-
   @Override
   public Environment createSkylarkRuleClassEnvironment(
-      Label extensionLabel,
+      Label fileLabel,
       Mutability mutability,
       StarlarkSemantics starlarkSemantics,
       EventHandler eventHandler,
       String astFileContentHashCode,
       Map<String, Extension> importMap,
       ImmutableMap<RepositoryName, RepositoryName> repoMapping) {
-    return createSkylarkRuleClassEnvironment(
-        mutability,
-        globals.withLabel(extensionLabel),
-        starlarkSemantics,
-        eventHandler,
-        astFileContentHashCode,
-        importMap,
-        repoMapping,
-        extensionLabel);
+    Environment env =
+        Environment.builder(mutability)
+            .setGlobals(globals.withLabel(fileLabel))
+            .setSemantics(starlarkSemantics)
+            .setEventHandler(eventHandler)
+            .setFileContentHashCode(astFileContentHashCode)
+            .setImportedExtensions(importMap)
+            .build();
+
+    new BazelStarlarkContext(
+            toolsRepository,
+            configurationFragmentMap,
+            repoMapping,
+            new SymbolGenerator<>(fileLabel),
+            /* analysisRuleLabel= */ null)
+        .storeInThread(env);
+
+    SkylarkUtils.setPhase(env, Phase.LOADING);
+    return env;
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java
index ff2056d..078a2b6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java
@@ -18,10 +18,10 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.events.StoredEventHandler;
+import com.google.devtools.build.lib.packages.BazelStarlarkContext;
 import com.google.devtools.build.lib.packages.StructImpl;
 import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigurationTransitionApi;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -109,8 +109,8 @@
       List<String> inputs,
       List<String> outputs,
       StarlarkSemantics semantics,
-      StarlarkContext context) {
-    return new RegularTransition(impl, inputs, outputs, semantics, context);
+      Environment env) {
+    return new RegularTransition(impl, inputs, outputs, semantics, BazelStarlarkContext.from(env));
   }
 
   public static StarlarkDefinedConfigTransition newAnalysisTestTransition(
@@ -166,14 +166,14 @@
   public static class RegularTransition extends StarlarkDefinedConfigTransition {
     private final BaseFunction impl;
     private final StarlarkSemantics semantics;
-    private final StarlarkContext starlarkContext;
+    private final BazelStarlarkContext starlarkContext;
 
     RegularTransition(
         BaseFunction impl,
         List<String> inputs,
         List<String> outputs,
         StarlarkSemantics semantics,
-        StarlarkContext context) {
+        BazelStarlarkContext context) {
       super(inputs, outputs, impl.getLocation());
       this.impl = impl;
       this.semantics = semantics;
@@ -277,9 +277,8 @@
             Environment.builder(mutability)
                 .setSemantics(semantics)
                 .setEventHandler(getEventHandler())
-                .setStarlarkContext(starlarkContext)
                 .build();
-
+        starlarkContext.storeInThread(env);
         return function.call(args, ImmutableMap.of(), null, env);
       }
     }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelBuildApiGlobals.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelBuildApiGlobals.java
index c2580f4..c7431d6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelBuildApiGlobals.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelBuildApiGlobals.java
@@ -17,7 +17,7 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.BazelStarlarkContext;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkBuildApiGlobals;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
+import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 
 /**
@@ -28,8 +28,8 @@
 
   @Override
   public SkylarkLateBoundDefault<?> configurationField(
-      String fragment, String name, Location loc, StarlarkContext context) throws EvalException {
-    BazelStarlarkContext bazelContext = (BazelStarlarkContext) context;
+      String fragment, String name, Location loc, Environment env) throws EvalException {
+    BazelStarlarkContext bazelContext = BazelStarlarkContext.from(env);
     Class<?> fragmentClass = bazelContext.getFragmentNameToClass().get(fragment);
 
     if (fragmentClass == null) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
index 323d7f1..b8636b5 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
@@ -43,7 +43,6 @@
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkAttrApi;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
@@ -98,12 +97,11 @@
       String doc,
       SkylarkDict<String, Object> arguments,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     // We use an empty name now so that we can set it later.
     // This trick makes sense only in the context of Skylark (builtin rules should not use it).
-    return createAttributeFactory(type, doc, arguments, ast, env, context, "");
+    return createAttributeFactory(type, doc, arguments, ast, env, "");
   }
 
   private static ImmutableAttributeFactory createAttributeFactory(
@@ -112,10 +110,9 @@
       SkylarkDict<String, Object> arguments,
       FuncallExpression ast,
       Environment env,
-      StarlarkContext context,
       String name)
       throws EvalException {
-    return createAttribute(type, doc, arguments, ast, env, context, name).buildPartial();
+    return createAttribute(type, doc, arguments, ast, env, name).buildPartial();
   }
 
   private static Attribute.Builder<?> createAttribute(
@@ -124,7 +121,6 @@
       SkylarkDict<String, Object> arguments,
       FuncallExpression ast,
       Environment env,
-      StarlarkContext context,
       String name)
       throws EvalException {
     Attribute.Builder<?> builder = Attribute.attr(name, type).setDoc(doc);
@@ -138,7 +134,7 @@
                 (StarlarkFunction) defaultValue,
                 ast,
                 env.getSemantics(),
-                (BazelStarlarkContext) context);
+                BazelStarlarkContext.from(env));
         // SkylarkComputedDefaultTemplate needs to know the names of all attributes that it depends
         // on. However, this method does not know anything about other attributes.
         // We solve this problem by asking the StarlarkCallbackHelper for the parameter names used
@@ -393,11 +389,10 @@
       SkylarkDict<String, Object> kwargs,
       Type<?> type,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     try {
-      return new Descriptor(name, createAttributeFactory(type, null, kwargs, ast, env, context));
+      return new Descriptor(name, createAttributeFactory(type, null, kwargs, ast, env));
     } catch (ConversionException e) {
       throw new EvalException(ast.getLocation(), e.getMessage());
     }
@@ -424,8 +419,7 @@
       SkylarkDict<String, Object> kwargs,
       Type<?> type,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     String whyNotConfigurableReason =
         Preconditions.checkNotNull(maybeGetNonConfigurableReason(type), type);
@@ -434,7 +428,7 @@
       // This trick makes sense only in the context of Skylark (builtin rules should not use it).
       return new Descriptor(
           name,
-          createAttribute(type, null, kwargs, ast, env, context, "")
+          createAttribute(type, null, kwargs, ast, env, "")
               .nonconfigurable(whyNotConfigurableReason)
               .buildPartial());
     } catch (ConversionException e) {
@@ -454,8 +448,7 @@
       Boolean mandatory,
       SkylarkList<?> values,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     // TODO(bazel-team): Replace literal strings with constants.
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.int", ast.getLocation());
@@ -465,8 +458,7 @@
             env, DEFAULT_ARG, defaultInt, MANDATORY_ARG, mandatory, VALUES_ARG, values),
         Type.INTEGER,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
@@ -476,8 +468,7 @@
       Boolean mandatory,
       SkylarkList<?> values,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.string", ast.getLocation());
     return createAttrDescriptor(
@@ -486,8 +477,7 @@
             env, DEFAULT_ARG, defaultString, MANDATORY_ARG, mandatory, VALUES_ARG, values),
         Type.STRING,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
@@ -504,8 +494,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.label", ast.getLocation());
     try {
@@ -537,7 +526,6 @@
                   aspects),
               ast,
               env,
-              context,
               "label");
       return new Descriptor("label", attribute);
     } catch (EvalException e) {
@@ -553,8 +541,7 @@
       SkylarkList<?> defaultList,
       String doc,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.string_list", ast.getLocation());
     return createAttrDescriptor(
@@ -571,8 +558,7 @@
             allowEmpty),
         Type.STRING_LIST,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
@@ -583,8 +569,7 @@
       SkylarkList<?> defaultList,
       String doc,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.int_list", ast.getLocation());
     return createAttrDescriptor(
@@ -601,8 +586,7 @@
             allowEmpty),
         Type.INTEGER_LIST,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
@@ -619,8 +603,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.label_list", ast.getLocation());
     SkylarkDict<String, Object> kwargs =
@@ -648,8 +631,7 @@
             aspects);
     try {
       ImmutableAttributeFactory attribute =
-          createAttributeFactory(
-              BuildType.LABEL_LIST, doc, kwargs, ast, env, context, "label_list");
+          createAttributeFactory(BuildType.LABEL_LIST, doc, kwargs, ast, env, "label_list");
       return new Descriptor("label_list", attribute);
     } catch (EvalException e) {
       throw new EvalException(ast.getLocation(), e.getMessage(), e);
@@ -670,8 +652,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(
         env, "attr.label_keyed_string_dict", ast.getLocation());
@@ -706,7 +687,6 @@
               kwargs,
               ast,
               env,
-              context,
               "label_keyed_string_dict");
       return new Descriptor("label_keyed_string_dict", attribute);
     } catch (EvalException e) {
@@ -716,12 +696,7 @@
 
   @Override
   public Descriptor boolAttribute(
-      Boolean defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Boolean defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.bool", ast.getLocation());
     return createAttrDescriptor(
@@ -729,18 +704,12 @@
         EvalUtils.<String, Object>optionMap(env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
         Type.BOOLEAN,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
   public Descriptor outputAttribute(
-      Object defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.output", ast.getLocation());
 
@@ -749,8 +718,7 @@
         EvalUtils.<String, Object>optionMap(env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
         BuildType.OUTPUT,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
@@ -761,8 +729,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.output_list", ast.getLocation());
 
@@ -780,8 +747,7 @@
             allowEmpty),
         BuildType.OUTPUT_LIST,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
@@ -792,8 +758,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.string_dict", ast.getLocation());
     return createAttrDescriptor(
@@ -810,8 +775,7 @@
             allowEmpty),
         Type.STRING_DICT,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
@@ -822,8 +786,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.string_list_dict", ast.getLocation());
     return createAttrDescriptor(
@@ -840,18 +803,12 @@
             allowEmpty),
         Type.STRING_LIST_DICT,
         ast,
-        env,
-        context);
+        env);
   }
 
   @Override
   public Descriptor licenseAttribute(
-      Object defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException {
     SkylarkUtils.checkLoadingOrWorkspacePhase(env, "attr.license", ast.getLocation());
     return createNonconfigurableAttrDescriptor(
@@ -859,8 +816,7 @@
         EvalUtils.<String, Object>optionMap(env, DEFAULT_ARG, defaultO, MANDATORY_ARG, mandatory),
         BuildType.LICENSE,
         ast,
-        env,
-        context);
+        env);
   }
 
   /** A descriptor of an attribute defined in Skylark. */
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index f42ba93..a37294f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -81,7 +81,6 @@
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkRuleFunctionsApi;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -292,12 +291,11 @@
       Object buildSetting,
       Object cfg,
       FuncallExpression ast,
-      Environment funcallEnv,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
-    SkylarkUtils.checkLoadingOrWorkspacePhase(funcallEnv, "rule", ast.getLocation());
+    SkylarkUtils.checkLoadingOrWorkspacePhase(env, "rule", ast.getLocation());
 
-    BazelStarlarkContext bazelContext = (BazelStarlarkContext) context;
+    BazelStarlarkContext bazelContext = BazelStarlarkContext.from(env);
     // analysis_test=true implies test=true.
     test |= Boolean.TRUE.equals(analysisTest);
 
@@ -332,7 +330,7 @@
       if (implicitOutputs instanceof StarlarkFunction) {
         StarlarkCallbackHelper callback =
             new StarlarkCallbackHelper(
-                (StarlarkFunction) implicitOutputs, ast, funcallEnv.getSemantics(), bazelContext);
+                (StarlarkFunction) implicitOutputs, ast, env.getSemantics(), bazelContext);
         builder.setImplicitOutputsFunction(
             new SkylarkImplicitOutputsFunctionWithCallback(callback, ast.getLocation()));
       } else {
@@ -358,15 +356,13 @@
             hostFragments.getContents(String.class, "host_fragments"));
     builder.setConfiguredTargetFunction(implementation);
     builder.setRuleDefinitionEnvironmentLabelAndHashCode(
-        (Label) funcallEnv.getGlobals().getLabel(), funcallEnv.getTransitiveContentHashCode());
+        (Label) env.getGlobals().getLabel(), env.getTransitiveContentHashCode());
 
-    ImmutableMap<RepositoryName, RepositoryName> repoMapping = ImmutableMap.of();
-    if (context instanceof BazelStarlarkContext) {
-      repoMapping = ((BazelStarlarkContext) context).getRepoMapping();
-    }
     builder.addRequiredToolchains(
         collectToolchainLabels(
-            toolchains.getContents(String.class, "toolchains"), ast.getLocation(), repoMapping));
+            toolchains.getContents(String.class, "toolchains"),
+            ast.getLocation(),
+            bazelContext.getRepoMapping()));
 
     if (!buildSetting.equals(Runtime.NONE) && !cfg.equals(Runtime.NONE)) {
       throw new EvalException(
@@ -408,7 +404,7 @@
           collectConstraintLabels(
               execCompatibleWith.getContents(String.class, "exec_compatile_with"),
               ast.getLocation(),
-              repoMapping));
+              bazelContext.getRepoMapping()));
     }
 
     if (executionPlatformConstraintsAllowed) {
@@ -503,8 +499,7 @@
       String doc,
       Boolean applyToGeneratingRules,
       FuncallExpression ast, // just for getLocation(); TODO(adonovan): simplify
-      Environment funcallEnv,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     Location location = ast.getLocation();
     ImmutableList.Builder<String> attrAspects = ImmutableList.builder();
@@ -581,10 +576,6 @@
                 EvalUtils.getDataTypeName(o, true)));
       }
     }
-    ImmutableMap<RepositoryName, RepositoryName> repoMapping = ImmutableMap.of();
-    if (context instanceof BazelStarlarkContext) {
-      repoMapping = ((BazelStarlarkContext) context).getRepoMapping();
-    }
     return new SkylarkDefinedAspect(
         implementation,
         attrAspects.build(),
@@ -597,7 +588,9 @@
         HostTransition.INSTANCE,
         ImmutableSet.copyOf(hostFragments.getContents(String.class, "host_fragments")),
         collectToolchainLabels(
-            toolchains.getContents(String.class, "toolchains"), ast.getLocation(), repoMapping),
+            toolchains.getContents(String.class, "toolchains"),
+            ast.getLocation(),
+            BazelStarlarkContext.from(env).getRepoMapping()),
         applyToGeneratingRules);
   }
 
@@ -797,13 +790,9 @@
 
   @Override
   public Label label(
-      String labelString,
-      Boolean relativeToCallerRepository,
-      Location loc,
-      Environment env,
-      StarlarkContext context)
+      String labelString, Boolean relativeToCallerRepository, Location loc, Environment env)
       throws EvalException {
-    BazelStarlarkContext bazelStarlarkContext = (BazelStarlarkContext) context;
+    BazelStarlarkContext context = BazelStarlarkContext.from(env);
 
     // This function is surprisingly complex.
     //
@@ -855,7 +844,7 @@
     if (relativeToCallerRepository) {
       // This is the label of the rule, if this is an analysis-phase
       // rule or aspect implementation thread, or null otherwise.
-      parentLabel = bazelStarlarkContext.getAnalysisRuleLabel();
+      parentLabel = context.getAnalysisRuleLabel();
     } else {
       // This is the label of the BUILD/.bzl file on the top of the current call stack.
       // (Function enter/exit changes getGlobals.)
@@ -867,7 +856,7 @@
         LabelValidator.parseAbsoluteLabel(labelString);
         labelString =
             parentLabel
-                .getRelativeWithRemapping(labelString, bazelStarlarkContext.getRepoMapping())
+                .getRelativeWithRemapping(labelString, context.getRepoMapping())
                 .getUnambiguousCanonicalForm();
       }
       return labelCache.get(labelString);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java
index a996750..1019d96 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java
@@ -101,16 +101,17 @@
           Environment.builder(mutability)
               .setSemantics(starlarkSemantics)
               .setEventHandler(ruleContext.getAnalysisEnvironment().getEventHandler())
-              .setStarlarkContext(
-                  new BazelStarlarkContext(
-                      toolsRepository,
-                      /* fragmentNameToClass= */ null,
-                      ruleContext.getTarget().getPackage().getRepositoryMapping(),
-                      ruleContext.getSymbolGenerator(),
-                      ruleContext.getLabel()))
               .build(); // NB: loading phase functions are not available: this is analysis already,
       // so we do *not* setLoadingPhase().
 
+      new BazelStarlarkContext(
+              toolsRepository,
+              /* fragmentNameToClass= */ null,
+              ruleContext.getTarget().getPackage().getRepositoryMapping(),
+              ruleContext.getSymbolGenerator(),
+              ruleContext.getLabel())
+          .storeInThread(env);
+
       RuleClass ruleClass = ruleContext.getRule().getRuleClassObject();
       if (ruleClass.getRuleClassType().equals(RuleClass.Builder.RuleClassType.WORKSPACE)) {
         ruleContext.ruleError(
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
index 968be24..e73380a 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java
@@ -126,16 +126,18 @@
           com.google.devtools.build.lib.syntax.Environment.builder(mutability)
               .setSemantics(starlarkSemantics)
               .setEventHandler(env.getListener())
-              // The fetch phase does not need the tools repository or the fragment map because
-              // it happens before analysis.
-              .setStarlarkContext(
-                  new BazelStarlarkContext(
-                      /* toolsRepository = */ null,
-                      /* fragmentNameToClass = */ null,
-                      rule.getPackage().getRepositoryMapping(),
-                      new SymbolGenerator<>(key),
-                      /* analysisRuleLabel= */ null))
               .build();
+
+      // The fetch phase does not need the tools repository
+      // or the fragment map because it happens before analysis.
+      new BazelStarlarkContext(
+              /* toolsRepository = */ null,
+              /* fragmentNameToClass = */ null,
+              rule.getPackage().getRepositoryMapping(),
+              new SymbolGenerator<>(key),
+              /* analysisRuleLabel= */ null)
+          .storeInThread(buildEnv);
+
       SkylarkRepositoryContext skylarkRepositoryContext =
           new SkylarkRepositoryContext(
               rule,
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
index 8f05560..5e393c8 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
@@ -31,7 +31,6 @@
 import com.google.devtools.build.lib.rules.cpp.FeatureConfigurationForStarlark;
 import com.google.devtools.build.lib.rules.cpp.LibraryToLink;
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.BazelCcModuleApi;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.SkylarkList;
@@ -123,8 +122,7 @@
       boolean linkDepsStatically,
       SkylarkList<Artifact> additionalInputs,
       Location location,
-      Environment environment,
-      StarlarkContext starlarkContext)
+      Environment env)
       throws InterruptedException, EvalException {
     return super.link(
         actions,
@@ -140,8 +138,7 @@
         additionalInputs,
         /* grepIncludes= */ null,
         location,
-        /* environment= */ null,
-        starlarkContext);
+        env);
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
index eedd40e..8ab41a9 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
@@ -503,7 +503,7 @@
    * {@code //wiz:quux} relative to {@code //foo/bar:baz} is {@code //wiz:quux}.
    *
    * @param relName the relative label name; must be non-empty.
-   * @param env the Starlark thread. Its StarlarkContext must implement {@code HasRepoMapping}.
+   * @param env the Starlark thread, which must provide a thread-local {@code HasRepoMapping}.
    */
   @SkylarkCallable(
       name = "relative",
@@ -539,8 +539,8 @@
       },
       useEnvironment = true)
   public Label getRelative(String relName, Environment env) throws LabelSyntaxException {
-    return getRelativeWithRemapping(
-        relName, ((HasRepoMapping) env.getStarlarkContext()).getRepoMapping());
+    HasRepoMapping hrm = env.getThreadLocal(HasRepoMapping.class);
+    return getRelativeWithRemapping(relName, hrm.getRepoMapping());
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkContext.java b/src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkContext.java
index 31f12ae..2cf9109 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkContext.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkContext.java
@@ -19,14 +19,23 @@
 import com.google.devtools.build.lib.analysis.RuleDefinitionContext;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.cmdline.RepositoryName;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
+import com.google.devtools.build.lib.syntax.Environment;
 import javax.annotation.Nullable;
 
-/**
- * Contextual information associated with each Starlark thread created by Bazel.
- */
-public class BazelStarlarkContext
-    implements StarlarkContext, RuleDefinitionContext, Label.HasRepoMapping {
+/** Contextual information associated with each Starlark thread created by Bazel. */
+public class BazelStarlarkContext implements RuleDefinitionContext, Label.HasRepoMapping {
+
+  /** Return the Bazel information associated with the specified Starlark thread. */
+  public static BazelStarlarkContext from(Environment env) {
+    return env.getThreadLocal(BazelStarlarkContext.class);
+  }
+
+  /** Save this BazelStarlarkContext in the specified Starlark thread. */
+  public void storeInThread(Environment env) {
+    env.setThreadLocal(BazelStarlarkContext.class, this);
+    env.setThreadLocal(Label.HasRepoMapping.class, this);
+  }
+
   private final String toolsRepository;
   @Nullable private final ImmutableMap<String, Class<?>> fragmentNameToClass;
   private final ImmutableMap<RepositoryName, RepositoryName> repoMapping;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index f175e7d..b5ef618 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -1665,6 +1665,8 @@
       extension.update(pkgEnv);
     }
 
+    // TODO(adonovan): save this as a field in LOADING-phase BazelSkylarkContext.
+    // It needn't be a separate thread-local.
     pkgEnv.setThreadLocal(PackageContext.class, context);
   }
 
@@ -1712,23 +1714,23 @@
     StoredEventHandler eventHandler = new StoredEventHandler();
 
     try (Mutability mutability = Mutability.create("package %s", packageId)) {
-      BazelStarlarkContext starlarkContext =
-          new BazelStarlarkContext(
-              ruleClassProvider.getToolsRepository(),
-              /*fragmentNameToClass=*/ null,
-              repositoryMapping,
-              new SymbolGenerator<>(packageId),
-              /*analysisRuleLabel=*/ null);
       Environment pkgEnv =
           Environment.builder(mutability)
               .setGlobals(BazelLibrary.GLOBALS)
               .setSemantics(starlarkSemantics)
               .setEventHandler(eventHandler)
               .setImportedExtensions(imports)
-              .setStarlarkContext(starlarkContext)
               .build();
       SkylarkUtils.setPhase(pkgEnv, Phase.LOADING);
 
+      new BazelStarlarkContext(
+              ruleClassProvider.getToolsRepository(),
+              /*fragmentNameToClass=*/ null,
+              repositoryMapping,
+              new SymbolGenerator<>(packageId),
+              /*analysisRuleLabel=*/ null)
+          .storeInThread(pkgEnv);
+
       pkgBuilder.setFilename(buildFilePath)
           .setDefaultVisibility(defaultVisibility)
           // "defaultVisibility" comes from the command line. Let's give the BUILD file a chance to
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkCallbackHelper.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkCallbackHelper.java
index 19eec20..d88edae 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkCallbackHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkCallbackHelper.java
@@ -37,18 +37,29 @@
 
   private final StarlarkFunction callback;
   private final FuncallExpression ast;
+
+  // These fields, parts of the state of the loading-phase
+  // thread that instantiated a rule, must be propagated to
+  // the child threads (implicit outputs, attribute defaults).
+  // This includes any other thread-local state, such as
+  // the Label.HasRepoMapping or PackageFactory.PackageContext.
+  // TODO(adonovan): it would be cleaner and less error prone to
+  // perform these callbacks in the actual loading-phase thread,
+  // at the end of BUILD file execution.
+  // Alternatively (or additionally), we could put PackageContext
+  // into BazelStarlarkContext so there's only a single blob of state.
   private final StarlarkSemantics starlarkSemantics;
-  private final BazelStarlarkContext starlarkContext;
+  private final BazelStarlarkContext context;
 
   public StarlarkCallbackHelper(
       StarlarkFunction callback,
       FuncallExpression ast,
       StarlarkSemantics starlarkSemantics,
-      BazelStarlarkContext starlarkContext) {
+      BazelStarlarkContext context) {
     this.callback = callback;
     this.ast = ast;
     this.starlarkSemantics = starlarkSemantics;
-    this.starlarkContext = starlarkContext;
+    this.context = context;
   }
 
   public ImmutableList<String> getParameterNames() {
@@ -64,8 +75,8 @@
           Environment.builder(mutability)
               .setSemantics(starlarkSemantics)
               .setEventHandler(eventHandler)
-              .setStarlarkContext(starlarkContext)
               .build();
+      context.storeInThread(env);
       return callback.call(buildArgumentList(ctx, arguments), null, ast, env);
     } catch (ClassCastException | IllegalArgumentException e) {
       throw new EvalException(ast.getLocation(), e.getMessage());
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
index 01051a2..6ffdf5b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
@@ -182,20 +182,22 @@
             .setGlobals(BazelLibrary.GLOBALS)
             .setEventHandler(localReporter)
             .setImportedExtensions(importMap)
-            // The workspace environment doesn't need the tools repository or the fragment map
-            // because executing workspace rules happens before analysis and it doesn't need a
-            // repository mapping because calls to the Label constructor in the WORKSPACE file
-            // are, by definition, not in an external repository and so they don't need the mapping
-            .setStarlarkContext(
-                new BazelStarlarkContext(
-                    /* toolsRepository= */ null,
-                    /* fragmentNameToClass= */ null,
-                    /* repoMapping= */ ImmutableMap.of(),
-                    new SymbolGenerator<>(workspaceFileKey),
-                    /* analysisRuleLabel= */ null))
             .build();
     SkylarkUtils.setPhase(workspaceEnv, Phase.WORKSPACE);
     addWorkspaceFunctions(workspaceEnv, localReporter);
+
+    // The workspace environment doesn't need the tools repository or the fragment map
+    // because executing workspace rules happens before analysis and it doesn't need a
+    // repository mapping because calls to the Label constructor in the WORKSPACE file
+    // are, by definition, not in an external repository and so they don't need the mapping
+    new BazelStarlarkContext(
+            /* toolsRepository= */ null,
+            /* fragmentNameToClass= */ null,
+            /* repoMapping= */ ImmutableMap.of(),
+            new SymbolGenerator<>(workspaceFileKey),
+            /* analysisRuleLabel= */ null)
+        .storeInThread(workspaceEnv);
+
     for (Map.Entry<String, Object> binding : parentVariableBindings.entrySet()) {
       try {
         workspaceEnv.update(binding.getKey(), binding.getValue());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
index b00aa8e..cc9ea8f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
@@ -73,7 +73,7 @@
   public AndroidAssetsInfo assetsFromDeps(
       SkylarkList<AndroidAssetsInfo> deps, boolean neverlink, Environment env) {
     // We assume this is an analysis-phase thread.
-    Label label = ((BazelStarlarkContext) env.getStarlarkContext()).getAnalysisRuleLabel();
+    Label label = BazelStarlarkContext.from(env).getAnalysisRuleLabel();
     return AssetDependencies.fromProviders(deps, neverlink).toInfo(label);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigGlobalLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigGlobalLibrary.java
index dabcb40..aaae4ec 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigGlobalLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigGlobalLibrary.java
@@ -23,7 +23,6 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigGlobalLibraryApi;
 import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigurationTransitionApi;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -46,8 +45,7 @@
       List<String> inputs,
       List<String> outputs,
       Location location,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     StarlarkSemantics semantics = env.getSemantics();
     validateBuildSettingKeys(
@@ -55,7 +53,7 @@
     validateBuildSettingKeys(
         outputs, Settings.OUTPUTS, location, semantics.experimentalStarlarkConfigTransitions());
     return StarlarkDefinedConfigTransition.newRegularTransition(
-        implementation, inputs, outputs, semantics, context);
+        implementation, inputs, outputs, semantics, env);
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index 4a6d86e..938ee26 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -57,7 +57,6 @@
 import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode;
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcInfoApi;
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcModuleApi;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
@@ -580,7 +579,7 @@
       Object userLinkFlagsObject,
       SkylarkList<Artifact> nonCodeInputs,
       Location location,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     @SuppressWarnings("unchecked")
     SkylarkList<LibraryToLink> librariesToLink =
@@ -601,7 +600,7 @@
                 ImmutableList.of(
                     CcLinkingContext.LinkOptions.of(
                         userLinkFlags.getImmutableList(),
-                        ((BazelStarlarkContext) context).getSymbolGenerator()))));
+                        BazelStarlarkContext.from(env).getSymbolGenerator()))));
       }
       ccLinkingContextBuilder.addNonCodeInputs(
           NestedSetBuilder.wrap(Order.LINK_ORDER, nonCodeInputs));
@@ -1400,7 +1399,7 @@
       boolean disallowDynamicLibraries,
       Object grepIncludes,
       Location location,
-      StarlarkContext starlarkContext)
+      Environment env)
       throws InterruptedException, EvalException {
     validateLanguage(location, language);
     SkylarkActionFactory actions = skylarkActionFactoryApi;
@@ -1433,7 +1432,7 @@
                     .getActionConstructionContext()
                     .getConfiguration()
                     .getFragment(CppConfiguration.class),
-                ((BazelStarlarkContext) starlarkContext).getSymbolGenerator(),
+                BazelStarlarkContext.from(env).getSymbolGenerator(),
                 TargetUtils.getExecutionInfo(
                     actions.getRuleContext().getRule(),
                     actions.getRuleContext().isAllowTagsPropagation()))
@@ -1629,8 +1628,7 @@
       SkylarkList<Artifact> additionalInputs,
       Object grepIncludes,
       Location location,
-      @Nullable Environment environment,
-      StarlarkContext starlarkContext)
+      Environment env)
       throws InterruptedException, EvalException {
     validateLanguage(location, language);
     validateOutputType(location, outputType);
@@ -1675,7 +1673,7 @@
                 fdoContext,
                 actions.getActionConstructionContext().getConfiguration(),
                 cppConfiguration,
-                ((BazelStarlarkContext) starlarkContext).getSymbolGenerator(),
+                BazelStarlarkContext.from(env).getSymbolGenerator(),
                 TargetUtils.getExecutionInfo(
                     actions.getRuleContext().getRule(),
                     actions.getRuleContext().isAllowTagsPropagation()))
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
index f575aeb..7d5fe13 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
@@ -75,16 +75,18 @@
           Environment.builder(mutability)
               .setSemantics(analysisEnv.getSkylarkSemantics())
               .setEventHandler(analysisEnv.getEventHandler())
-              .setStarlarkContext(
-                  new BazelStarlarkContext(
-                      toolsRepository,
-                      /* fragmentNameToClass=*/ null,
-                      ruleContext.getRule().getPackage().getRepositoryMapping(),
-                      ruleContext.getSymbolGenerator(),
-                      ruleContext.getLabel()))
-              // NB: loading phase functions are not available: this is analysis already, so we do
-              // *not* setLoadingPhase().
               .build();
+      // NB: loading phase functions are not available: this is analysis already, so we do
+      // *not* setLoadingPhase().
+
+      new BazelStarlarkContext(
+              toolsRepository,
+              /* fragmentNameToClass=*/ null,
+              ruleContext.getRule().getPackage().getRepositoryMapping(),
+              ruleContext.getSymbolGenerator(),
+              ruleContext.getLabel())
+          .storeInThread(env);
+
       Object aspectSkylarkObject;
       try {
         aspectSkylarkObject =
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
index a1f8e18..ba97cd3 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
@@ -21,7 +21,6 @@
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
@@ -182,16 +181,14 @@
             positional = false)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   Descriptor intAttribute(
       Integer defaultInt,
       String doc,
       Boolean mandatory,
       SkylarkList<?> values,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -231,16 +228,14 @@
             positional = false)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor stringAttribute(
       String defaultString,
       String doc,
       Boolean mandatory,
       SkylarkList<?> values,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -365,8 +360,7 @@
             doc = ASPECTS_ARG_DOC),
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor labelAttribute(
       Object defaultO,
       String doc,
@@ -380,8 +374,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -425,8 +418,7 @@
             positional = false)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor stringListAttribute(
       Boolean mandatory,
       Boolean nonEmpty,
@@ -434,8 +426,7 @@
       SkylarkList<?> defaultList,
       String doc,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -479,8 +470,7 @@
             positional = false)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor intListAttribute(
       Boolean mandatory,
       Boolean nonEmpty,
@@ -488,8 +478,7 @@
       SkylarkList<?> defaultList,
       String doc,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -589,8 +578,7 @@
             doc = ASPECTS_ARG_DOC),
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor labelListAttribute(
       Boolean allowEmpty,
       Object defaultList,
@@ -604,8 +592,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -707,8 +694,7 @@
             doc = ASPECTS_ARG_DOC)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor labelKeyedStringDictAttribute(
       Boolean allowEmpty,
       Object defaultList,
@@ -722,8 +708,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -756,15 +741,9 @@
             doc = MANDATORY_DOC)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor boolAttribute(
-      Boolean defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Boolean defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -800,15 +779,9 @@
             doc = MANDATORY_DOC)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor outputAttribute(
-      Object defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -857,8 +830,7 @@
             doc = NON_EMPTY_DOC)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor outputListAttribute(
       Boolean allowEmpty,
       Object defaultList,
@@ -866,8 +838,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -915,8 +886,7 @@
             doc = NON_EMPTY_DOC)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor stringDictAttribute(
       Boolean allowEmpty,
       SkylarkDict<?, ?> defaultO,
@@ -924,8 +894,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -973,8 +942,7 @@
             doc = NON_EMPTY_DOC)
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor stringListDictAttribute(
       Boolean allowEmpty,
       SkylarkDict<?, ?> defaultO,
@@ -982,8 +950,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -1016,15 +983,9 @@
       },
       disableWithFlag = FlagIdentifier.INCOMPATIBLE_NO_ATTR_LICENSE,
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public Descriptor licenseAttribute(
-      Object defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException;
 
   /** An attribute descriptor. */
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkBuildApiGlobals.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkBuildApiGlobals.java
index eedb78a..97f035c 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkBuildApiGlobals.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkBuildApiGlobals.java
@@ -18,7 +18,7 @@
 import com.google.devtools.build.lib.skylarkinterface.Param;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
+import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 
 /**
@@ -56,7 +56,7 @@
             doc = "The name of the value to obtain from the configuration fragment."),
       },
       useLocation = true,
-      useContext = true)
+      useEnvironment = true)
   public LateBoundDefaultApi configurationField(
-      String fragment, String name, Location loc, StarlarkContext context) throws EvalException;
+      String fragment, String name, Location loc, Environment env) throws EvalException;
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
index 2f7e67e..96d4571 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
@@ -22,7 +22,6 @@
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -342,8 +341,7 @@
                     + "apply to its own configuration before analysis.")
       },
       useAst = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   public BaseFunction rule(
       StarlarkFunction implementation,
       Boolean test,
@@ -363,8 +361,7 @@
       Object buildSetting,
       Object cfg,
       FuncallExpression ast,
-      Environment funcallEnv,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -503,8 +500,7 @@
                     + "aspect will propagate only to `alpha`. </p><p>False by default.</p>")
       },
       useEnvironment = true,
-      useAst = true,
-      useContext = true)
+      useAst = true)
   public SkylarkAspectApi aspect(
       StarlarkFunction implementation,
       SkylarkList<?> attributeAspects,
@@ -517,8 +513,7 @@
       String doc,
       Boolean applyToGeneratingRules,
       FuncallExpression ast,
-      Environment funcallEnv,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
@@ -550,14 +545,9 @@
                     + "Label() call appears.")
       },
       useLocation = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   @SkylarkConstructor(objectType = Label.class)
   public Label label(
-      String labelString,
-      Boolean relativeToCallerRepository,
-      Location loc,
-      Environment env,
-      StarlarkContext context)
+      String labelString, Boolean relativeToCallerRepository, Location loc, Environment env)
       throws EvalException;
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigGlobalLibraryApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigGlobalLibraryApi.java
index 4c3330c..990839b 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigGlobalLibraryApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/config/ConfigGlobalLibraryApi.java
@@ -19,7 +19,6 @@
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -88,16 +87,14 @@
                     + "a superset of the key set of the dictionary returned by this transition."),
       },
       useLocation = true,
-      useEnvironment = true,
-      useContext = true)
+      useEnvironment = true)
   @SkylarkConstructor(objectType = ConfigurationTransitionApi.class)
   ConfigurationTransitionApi transition(
       BaseFunction implementation,
       List<String> inputs,
       List<String> outputs,
       Location location,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException;
 
   @SkylarkCallable(
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
index 33bebdb..8a2df2d 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
@@ -22,7 +22,6 @@
 import com.google.devtools.build.lib.skylarkinterface.ParamType;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.Runtime.NoneType;
@@ -237,7 +236,6 @@
       doc = "Should be used for C++ transitive linking.",
       useEnvironment = true,
       useLocation = true,
-      useContext = true,
       parameters = {
         @Param(
             name = "actions",
@@ -339,8 +337,7 @@
       boolean linkDepsStatically,
       SkylarkList<FileT> additionalInputs,
       Location location,
-      Environment environment,
-      StarlarkContext starlarkContext)
+      Environment env)
       throws InterruptedException, EvalException;
 
   @SkylarkCallable(
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
index 97196b1..ffd1ca4 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
@@ -23,7 +23,6 @@
 import com.google.devtools.build.lib.skylarkinterface.ParamType;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.Runtime.NoneType;
@@ -604,7 +603,7 @@
       name = "create_linking_context",
       doc = "Creates a <code>LinkingContext</code>.",
       useLocation = true,
-      useContext = true,
+      useEnvironment = true,
       parameters = {
         @Param(
             name = "libraries_to_link",
@@ -635,7 +634,7 @@
       Object userLinkFlagsObject,
       SkylarkList<FileT> nonCodeInputs,
       Location location,
-      StarlarkContext context)
+      Environment env)
       throws EvalException, InterruptedException;
 
   @SkylarkCallable(
@@ -926,7 +925,7 @@
               + " order to be linked later by a top level rule that does transitive linking to"
               + " create an executable or dynamic library.",
       useLocation = true,
-      useContext = true,
+      useEnvironment = true,
       parameters = {
         @Param(
             name = "actions",
@@ -1038,6 +1037,6 @@
       boolean disallowDynamicLibraries,
       Object grepIncludes,
       Location location,
-      StarlarkContext bazelStarlarkContext)
+      Environment env)
       throws InterruptedException, EvalException;
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkCallable.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkCallable.java
index 1fb433a..8ea3602 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkCallable.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkCallable.java
@@ -46,7 +46,7 @@
  *   <li>If structField=true, there must be zero user-supplied parameters.
  *   <li>The underlying java method's parameters must be supplied in the following order:
  *       <pre>method([positionals]*[named args]*(extra positionals list)(extra kwargs)
- *       (Location)(FuncallExpression)(Envrionment)(StarlarkSemantics)(StarlarkContext))</pre>
+ *       (Location)(FuncallExpression)(Envrionment)(StarlarkSemantics))</pre>
  *       where (extra positionals list) is a SkylarkList if extraPositionals is defined, (extra
  *       kwargs) is a SkylarkDict if extraKeywords is defined, and Location, FuncallExpression,
  *       Environment, and StarlarkSemantics are supplied by the interpreter if and only if
@@ -170,13 +170,6 @@
   boolean useStarlarkSemantics() default false;
 
   /**
-   * If true, StarlarkContext will be passed as an argument of the annotated function. (Thus, the
-   * annotated method signature must contain StarlarkContext as a parameter. See the interface-level
-   * javadoc for details.)
-   */
-  boolean useContext() default false;
-
-  /**
    * If not NONE, the annotated method will only be callable if the given semantic flag is true.
    * Note that at most one of {@link #enableOnlyWithFlag} and {@link #disableWithFlag} can be
    * non-NONE.
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/StarlarkContext.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/StarlarkContext.java
deleted file mode 100644
index a220431..0000000
--- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/StarlarkContext.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.skylarkinterface;
-
-/**
- * A container of application-specific context which may be passed to Starlark callable functions.
- *
- * <p>An application using the Starlark interpreter can provide a custom context implementation to a
- * Starlark environment using {@link Environment#setStarlarkContext}. The context object will then
- * be passed to any {@link SkylarkCallable} method with {@link SkylarkCallable#useContext} set to
- * true.
- *
- * <p>Note that the interpreter passes a StarlarkContext to a callable method which requests it, and
- * does no casting to an application-specific context object. The application's implementation of
- * the callable method must cast a context object to the application-specific context itself.
- */
-public interface StarlarkContext {}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessor.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessor.java
index 39a6632..b0904a0 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessor.java
@@ -85,8 +85,6 @@
   private static final String ENVIRONMENT = "com.google.devtools.build.lib.syntax.Environment";
   private static final String STARLARK_SEMANTICS =
       "com.google.devtools.build.lib.syntax.StarlarkSemantics";
-  private static final String STARLARK_CONTEXT =
-      "com.google.devtools.build.lib.skylarkinterface.StarlarkContext";
 
   @Override
   public SourceVersion getSupportedSourceVersion() {
@@ -452,16 +450,6 @@
       }
       currentIndex++;
     }
-    if (annotation.useContext()) {
-      if (!STARLARK_CONTEXT.equals(methodSignatureParams.get(currentIndex).asType().toString())) {
-        throw new SkylarkCallableProcessorException(
-            methodElement,
-            String.format(
-                "Expected parameter index %d to be the %s type, matching useContext, "
-                    + "but was %s",
-                currentIndex, STARLARK_CONTEXT, methodSignatureParams.get(currentIndex).asType()));
-      }
-    }
   }
 
   private int numExpectedExtraInterpreterParams(SkylarkCallable annotation) {
@@ -472,7 +460,6 @@
     numExtraInterpreterParams += annotation.useAst() ? 1 : 0;
     numExtraInterpreterParams += annotation.useEnvironment() ? 1 : 0;
     numExtraInterpreterParams += annotation.useStarlarkSemantics() ? 1 : 0;
-    numExtraInterpreterParams += annotation.useContext() ? 1 : 0;
     return numExtraInterpreterParams;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
index 1d041c3..1e5e6be 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
@@ -389,8 +389,7 @@
     Preconditions.checkArgument(
         !methodDescriptor.isUseEnvironment()
             || !methodDescriptor.isUseStarlarkSemantics()
-            || !methodDescriptor.isUseLocation()
-            || !methodDescriptor.isUseContext(),
+            || !methodDescriptor.isUseLocation(),
         "Cannot be invoked on structField callables with extra interpreter params");
     return methodDescriptor.call(obj, new Object[0], Location.BUILTIN, null);
   }
@@ -675,9 +674,6 @@
     if (method.isUseStarlarkSemantics()) {
       builder.add(env.getSemantics());
     }
-    if (method.isUseContext()) {
-      builder.add(env.getStarlarkContext());
-    }
   }
 
   private static String formatMethod(Class<?> objClass, MethodDescriptor methodDescriptor) {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
index ae07fde..fbbbef2 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
@@ -27,7 +27,6 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Mutability.Freezable;
 import com.google.devtools.build.lib.syntax.Mutability.MutabilityException;
 import com.google.devtools.build.lib.util.Fingerprint;
@@ -322,7 +321,7 @@
       this.exportedBindings = new HashSet<>();
     }
 
-    public GlobalFrame(
+    GlobalFrame(
         Mutability mutability,
         @Nullable GlobalFrame universe,
         @Nullable Object label,
@@ -375,7 +374,7 @@
      * Constructs a global frame based on the given parent frame, filtering out flag-restricted
      * global objects.
      */
-    public static GlobalFrame filterOutRestrictedBindings(
+    private static GlobalFrame filterOutRestrictedBindings(
         Mutability mutability, GlobalFrame parent, StarlarkSemantics semantics) {
       if (parent == null) {
         return new GlobalFrame(mutability);
@@ -648,7 +647,7 @@
           env.getTransitiveContentHashCode());
     }
 
-    public String getTransitiveContentHashCode() {
+    private String getTransitiveContentHashCode() {
       return transitiveContentHashCode;
     }
 
@@ -794,8 +793,6 @@
   /** The semantics options that affect how Skylark code is evaluated. */
   private final StarlarkSemantics semantics;
 
-  private final StarlarkContext starlarkContext;
-
   /**
    * An EventHandler for errors and warnings. This is not used in the BUILD language, however it
    * might be used in Skylark code called from the BUILD language, so shouldn't be null.
@@ -867,6 +864,8 @@
    *
    * @return an EventHandler
    */
+  // TODO(adonovan): turn this into a print handler and break dependency on EventHandler.
+  // First, we must report scan/parse/validation errors using an exception containing events.
   public EventHandler getEventHandler() {
     return eventHandler;
   }
@@ -893,6 +892,7 @@
   }
 
   /** Returns the FuncallExpression and the BaseFunction for the top-level call being evaluated. */
+  // TODO(adonovan): replace this by an API for walking the call stack.
   public Pair<FuncallExpression, BaseFunction> getTopCall() {
     Continuation continuation = this.continuation;
     if (continuation == null) {
@@ -915,7 +915,6 @@
   private Environment(
       GlobalFrame globalFrame,
       StarlarkSemantics semantics,
-      StarlarkContext starlarkContext,
       EventHandler eventHandler,
       Map<String, Extension> importedExtensions,
       @Nullable String fileContentHashCode) {
@@ -924,7 +923,6 @@
     this.mutability = globalFrame.mutability();
     Preconditions.checkArgument(!globalFrame.mutability().isFrozen());
     this.semantics = semantics;
-    this.starlarkContext = starlarkContext;
     this.eventHandler = eventHandler;
     this.importedExtensions = importedExtensions;
     this.transitiveHashCode =
@@ -941,15 +939,12 @@
     private final Mutability mutability;
     @Nullable private GlobalFrame parent;
     @Nullable private StarlarkSemantics semantics;
-    @Nullable private StarlarkContext starlarkContext;
     @Nullable private EventHandler eventHandler;
     @Nullable private Map<String, Extension> importedExtensions;
     @Nullable private String fileContentHashCode;
 
     Builder(Mutability mutability) {
       this.mutability = mutability;
-      // TODO(cparsons): Require specifying a starlarkContext (or declaring use of an empty stub).
-      this.starlarkContext = new StarlarkContext() {};
     }
 
     /**
@@ -973,16 +968,6 @@
       return this;
     }
 
-    public Builder setStarlarkContext(StarlarkContext starlarkContext) {
-      this.starlarkContext = starlarkContext;
-      return this;
-    }
-
-    public Builder useEmptyStarlarkContext() {
-      this.starlarkContext = new StarlarkContext() {};
-      return this;
-    }
-
     /** Sets an EventHandler for errors and warnings. */
     public Builder setEventHandler(EventHandler eventHandler) {
       Preconditions.checkState(this.eventHandler == null);
@@ -1038,7 +1023,6 @@
       return new Environment(
           globalFrame,
           semantics,
-          starlarkContext,
           eventHandler,
           importedExtensions,
           fileContentHashCode);
@@ -1059,7 +1043,7 @@
   }
 
   /** Modifies a binding in the current Frame. If it is the module Frame, also export it. */
-  public Environment updateAndExport(String varname, Object value) throws EvalException {
+  Environment updateAndExport(String varname, Object value) throws EvalException {
     update(varname, value);
     if (isGlobal()) {
       globalFrame.exportedBindings.add(varname);
@@ -1128,7 +1112,7 @@
    * Returns the value of a variable defined in Local scope. Do not search in any parent scope. This
    * function should be used once the AST has been analysed and we know which variables are local.
    */
-  public Object localLookup(String varname) {
+  Object localLookup(String varname) {
     return lexicalFrame.get(varname);
   }
 
@@ -1167,10 +1151,10 @@
   /**
    * Returns a map containing all bindings that are technically <i>present</i> but are
    * <i>restricted</i> in the current frame with the current semantics. Such bindings should be
-   * treated unresolvable; this method should be invoked to prepare error messaging for
-   * evaluation environments where access of these restricted objects may have been attempted.
+   * treated unresolvable; this method should be invoked to prepare error messaging for evaluation
+   * environments where access of these restricted objects may have been attempted.
    */
-  public Map<String, FlagGuardedValue> getRestrictedBindings() {
+  Map<String, FlagGuardedValue> getRestrictedBindings() {
     return globalFrame.restrictedBindings;
   }
 
@@ -1178,11 +1162,7 @@
     return semantics;
   }
 
-  public StarlarkContext getStarlarkContext() {
-    return starlarkContext;
-  }
-
-  public void handleEvent(Event event) {
+  void handleEvent(Event event) {
     eventHandler.handle(event);
   }
 
@@ -1190,6 +1170,7 @@
    * Returns a set of all names of variables that are accessible in this {@code Environment}, in a
    * deterministic order.
    */
+  // TODO(adonovan): eliminate sole external call from docgen.
   public Set<String> getVariableNames() {
     LinkedHashSet<String> vars = new LinkedHashSet<>();
     vars.addAll(lexicalFrame.getTransitiveBindings().keySet());
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
index f2fa121..b71a888 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
@@ -49,7 +49,6 @@
   private final boolean useAst;
   private final boolean useEnvironment;
   private final boolean useStarlarkSemantics;
-  private final boolean useContext;
 
   private MethodDescriptor(
       Method method,
@@ -66,8 +65,7 @@
       boolean useLocation,
       boolean useAst,
       boolean useEnvironment,
-      boolean useStarlarkSemantics,
-      boolean useContext) {
+      boolean useStarlarkSemantics) {
     this.method = method;
     this.annotation = annotation;
     this.name = name;
@@ -83,7 +81,6 @@
     this.useAst = useAst;
     this.useEnvironment = useEnvironment;
     this.useStarlarkSemantics = useStarlarkSemantics;
-    this.useContext = useContext;
   }
 
   /** Returns the SkylarkCallable annotation corresponding to this method. */
@@ -114,8 +111,7 @@
         annotation.useLocation(),
         annotation.useAst(),
         annotation.useEnvironment(),
-        annotation.useStarlarkSemantics(),
-        annotation.useContext());
+        annotation.useStarlarkSemantics());
   }
 
   /**
@@ -194,11 +190,6 @@
     return useStarlarkSemantics;
   }
 
-  /** See {@link SkylarkCallable#useContext()}. */
-  boolean isUseContext() {
-    return useContext;
-  }
-
   /** @see SkylarkCallable#useLocation() */
   public boolean isUseLocation() {
     return useLocation;
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeBuildApiGlobals.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeBuildApiGlobals.java
index 65beb6f..35d6800 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeBuildApiGlobals.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeBuildApiGlobals.java
@@ -17,7 +17,7 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.skylarkbuildapi.LateBoundDefaultApi;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkBuildApiGlobals;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
+import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 
 /**
@@ -27,7 +27,7 @@
 
   @Override
   public LateBoundDefaultApi configurationField(
-      String fragment, String name, Location loc, StarlarkContext context) throws EvalException {
+      String fragment, String name, Location loc, Environment env) throws EvalException {
     return new FakeLateBoundDefaultApi();
   }
 }
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java
index 5d4949f..7bfddd9 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAttrApi.java
@@ -18,7 +18,6 @@
 import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkAttrApi;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
@@ -42,8 +41,7 @@
       Boolean mandatory,
       SkylarkList<?> values,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.INT, doc, mandatory, ImmutableList.of());
   }
@@ -55,8 +53,7 @@
       Boolean mandatory,
       SkylarkList<?> values,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.STRING, doc, mandatory, ImmutableList.of());
   }
@@ -75,8 +72,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     List<List<String>> allNameGroups = new ArrayList<>();
     if (providers != null) {
@@ -93,8 +89,7 @@
       SkylarkList<?> defaultList,
       String doc,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of());
   }
@@ -107,8 +102,7 @@
       SkylarkList<?> defaultList,
       String doc,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.INT_LIST, doc, mandatory, ImmutableList.of());
   }
@@ -127,8 +121,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     List<List<String>> allNameGroups = new ArrayList<>();
     if (providers != null) {
@@ -151,8 +144,7 @@
       Object cfg,
       SkylarkList<?> aspects,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     List<List<String>> allNameGroups = new ArrayList<>();
     if (providers != null) {
@@ -163,24 +155,14 @@
 
   @Override
   public Descriptor boolAttribute(
-      Boolean defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Boolean defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.BOOLEAN, doc, mandatory, ImmutableList.of());
   }
 
   @Override
   public Descriptor outputAttribute(
-      Object defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.OUTPUT, doc, mandatory, ImmutableList.of());
   }
@@ -193,8 +175,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.OUTPUT_LIST, doc, mandatory, ImmutableList.of());
   }
@@ -207,8 +188,7 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.STRING_DICT, doc, mandatory, ImmutableList.of());
   }
@@ -221,20 +201,14 @@
       Boolean mandatory,
       Boolean nonEmpty,
       FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.STRING_LIST_DICT, doc, mandatory, ImmutableList.of());
   }
 
   @Override
   public Descriptor licenseAttribute(
-      Object defaultO,
-      String doc,
-      Boolean mandatory,
-      FuncallExpression ast,
-      Environment env,
-      StarlarkContext context)
+      Object defaultO, String doc, Boolean mandatory, FuncallExpression ast, Environment env)
       throws EvalException {
     return new FakeDescriptor(AttributeType.STRING_LIST, doc, mandatory, ImmutableList.of());
   }
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
index 88f45fc..21ecbe3 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
@@ -23,7 +23,6 @@
 import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkAspectApi;
 import com.google.devtools.build.lib.skylarkbuildapi.SkylarkRuleFunctionsApi;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -146,8 +145,7 @@
       Object buildSetting,
       Object cfg,
       FuncallExpression ast,
-      Environment funcallEnv,
-      StarlarkContext context)
+      Environment funcallEnv)
       throws EvalException {
     ImmutableMap.Builder<String, FakeDescriptor> attrsMapBuilder = ImmutableMap.builder();
     if (attrs != null && attrs != Runtime.NONE) {
@@ -175,11 +173,7 @@
 
   @Override
   public Label label(
-      String labelString,
-      Boolean relativeToCallerRepository,
-      Location loc,
-      Environment env,
-      StarlarkContext context)
+      String labelString, Boolean relativeToCallerRepository, Location loc, Environment env)
       throws EvalException {
     try {
       return Label.parseAbsolute(
@@ -204,8 +198,7 @@
       String doc,
       Boolean applyToFiles,
       FuncallExpression ast,
-      Environment funcallEnv,
-      StarlarkContext context)
+      Environment funcallEnv)
       throws EvalException {
     FakeSkylarkAspect fakeAspect = new FakeSkylarkAspect();
     ImmutableMap.Builder<String, FakeDescriptor> attrsMapBuilder = ImmutableMap.builder();
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigGlobalLibrary.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigGlobalLibrary.java
index 6476591..d51a1c4 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigGlobalLibrary.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/config/FakeConfigGlobalLibrary.java
@@ -17,7 +17,6 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigGlobalLibraryApi;
 import com.google.devtools.build.lib.skylarkbuildapi.config.ConfigurationTransitionApi;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
@@ -35,8 +34,7 @@
       List<String> inputs,
       List<String> outputs,
       Location location,
-      Environment env,
-      StarlarkContext context) {
+      Environment env) {
     return new FakeConfigurationTransition();
   }
 
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
index d156042..5932393 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
@@ -32,7 +32,6 @@
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcToolchainVariablesApi;
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.FeatureConfigurationApi;
 import com.google.devtools.build.lib.skylarkbuildapi.cpp.LibraryToLinkApi;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
@@ -159,7 +158,7 @@
       Object userLinkFlagsObject,
       SkylarkList<FileApi> nonCodeInputs,
       Location location,
-      StarlarkContext context) {
+      Environment env) {
     return null;
   }
 
@@ -232,7 +231,7 @@
       boolean disallowDynamicLibraries,
       Object grepIncludes,
       Location location,
-      StarlarkContext starlarkContext)
+      Environment env)
       throws InterruptedException, EvalException {
     return null;
   }
@@ -251,8 +250,7 @@
       boolean linkDepsStatically,
       SkylarkList<FileApi> additionalInputs,
       Location location,
-      Environment environment,
-      StarlarkContext starlarkContext)
+      Environment environment)
       throws InterruptedException, EvalException {
     return null;
   }
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java b/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java
index 8fb0583..ad411f2 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java
@@ -67,15 +67,6 @@
     return new EvaluationTestCase() {
       @Override
       public Environment newEnvironment() throws Exception {
-        BazelStarlarkContext context =
-            new BazelStarlarkContext(
-                TestConstants.TOOLS_REPOSITORY,
-                /*fragmentNameToClass=*/ null,
-                /*repoMapping=*/ ImmutableMap.of(),
-                new SymbolGenerator<>(new Object()),
-                /*analysisRuleLabel=*/ null);
-        // This Environment has no PackageContext, so attempts to create a rule will fail.
-        // Rule creation is tested by SkylarkIntegrationTest.
         Environment env =
             Environment.builder(mutability)
                 .setSemantics(semantics)
@@ -84,9 +75,21 @@
                     getSkylarkGlobals()
                         .withLabel(
                             Label.parseAbsoluteUnchecked("//test:label", /*defaultToMain=*/ false)))
-                .setStarlarkContext(context)
                 .build();
+
         SkylarkUtils.setPhase(env, Phase.LOADING);
+
+        // This Environment has no PackageContext, so attempts to create a rule will fail.
+        // Rule creation is tested by SkylarkIntegrationTest.
+
+        new BazelStarlarkContext(
+                TestConstants.TOOLS_REPOSITORY,
+                /*fragmentNameToClass=*/ null,
+                /*repoMapping=*/ ImmutableMap.of(),
+                new SymbolGenerator<>(new Object()),
+                /*analysisRuleLabel=*/ null)
+            .storeInThread(env);
+
         return env;
       }
     };
diff --git a/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessorTest.java b/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessorTest.java
index 22c3e28..aa78222 100644
--- a/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/SkylarkCallableProcessorTest.java
@@ -19,7 +19,6 @@
 
 import com.google.common.io.Resources;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.testing.compile.JavaFileObjects;
 import javax.tools.JavaFileObject;
@@ -144,18 +143,6 @@
   }
 
   @Test
-  public void testContextMissing() throws Exception {
-    assertAbout(javaSource())
-        .that(getFile("ContextMissing.java"))
-        .processedWith(new SkylarkCallableProcessor())
-        .failsToCompile()
-        .withErrorContaining(
-            "Expected parameter index 2 to be the "
-                + StarlarkContext.class.getCanonicalName()
-                + " type, matching useContext, but was java.lang.String");
-  }
-
-  @Test
   public void testLocationMissing() throws Exception {
     assertAbout(javaSource())
         .that(getFile("LocationMissing.java"))
diff --git a/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/testsources/ContextMissing.java b/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/testsources/ContextMissing.java
deleted file mode 100644
index 1af6d4d..0000000
--- a/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/testsources/ContextMissing.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.skylarkinterface.processor.testsources;
-
-import com.google.devtools.build.lib.skylarkinterface.Param;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
-
-/**
- * Test case for a SkylarkCallable method which does not have an appropriate StarlarkContext
- * parameter despite having useContext set.
- */
-public class ContextMissing {
-
-  @SkylarkCallable(
-      name = "three_arg_method_missing_context",
-      documented = false,
-      parameters = {
-        @Param(name = "one", type = String.class, named = true),
-        @Param(name = "two", type = Integer.class, named = true),
-      },
-      useContext = true)
-  public String threeArgMethod(String one, Integer two, String shouldBeContext) {
-    return "bar";
-  }
-}
diff --git a/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/testsources/GoldenCase.java b/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/testsources/GoldenCase.java
index 65c0761..01cc816 100644
--- a/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/testsources/GoldenCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skylarkinterface/processor/testsources/GoldenCase.java
@@ -18,7 +18,6 @@
 import com.google.devtools.build.lib.skylarkinterface.Param;
 import com.google.devtools.build.lib.skylarkinterface.ParamType;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
@@ -165,8 +164,7 @@
       useAst = true,
       useLocation = true,
       useEnvironment = true,
-      useStarlarkSemantics = true,
-      useContext = true)
+      useStarlarkSemantics = true)
   public String twoArgMethodWithParamsAndInfoAndKwargs(
       String one,
       Integer two,
@@ -174,8 +172,7 @@
       Location location,
       FuncallExpression ast,
       Environment environment,
-      StarlarkSemantics starlarkSemantics,
-      StarlarkContext context) {
+      StarlarkSemantics starlarkSemantics) {
     return "blep";
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index 9b197c6..dfa82d5 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -35,7 +35,6 @@
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
-import com.google.devtools.build.lib.skylarkinterface.StarlarkContext;
 import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
 import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
 import com.google.devtools.build.lib.testutil.TestMode;
@@ -316,14 +315,9 @@
         useLocation = true,
         useAst = true,
         useEnvironment = true,
-        useStarlarkSemantics = true,
-        useContext = true)
+        useStarlarkSemantics = true)
     public String withExtraInterpreterParams(
-        Location location,
-        FuncallExpression func,
-        Environment env,
-        StarlarkSemantics sem,
-        StarlarkContext context) {
+        Location location, FuncallExpression func, Environment env, StarlarkSemantics sem) {
       return "with_extra("
           + location.getStartLine()
           + ", "
@@ -332,8 +326,6 @@
           + env.isGlobal()
           + ", "
           + (sem != null)
-          + ", "
-          + (context != null)
           + ")";
     }
 
@@ -1319,7 +1311,7 @@
     new SkylarkTest()
         .update("mock", new Mock())
         .setUp("v = mock.with_extra()")
-        .testLookup("v", "with_extra(1, 0, true, true, true)");
+        .testLookup("v", "with_extra(1, 0, true, true)");
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
index 3645991..a9d871d 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
@@ -65,21 +65,23 @@
    * No PythonPreprocessing, mostly empty mutable Environment.
    */
   public Environment newBuildEnvironment() {
-    BazelStarlarkContext context =
-        new BazelStarlarkContext(
-            TestConstants.TOOLS_REPOSITORY,
-            /* fragmentNameToClass= */ null,
-            /* repoMapping= */ ImmutableMap.of(),
-            new SymbolGenerator<>(new Object()),
-            /* analysisRuleLabel= */ null);
     Environment env =
         Environment.builder(mutability)
             .useDefaultSemantics()
             .setGlobals(BazelLibrary.GLOBALS)
             .setEventHandler(getEventHandler())
-            .setStarlarkContext(context)
             .build();
+
     SkylarkUtils.setPhase(env, Phase.LOADING);
+
+    new BazelStarlarkContext(
+            TestConstants.TOOLS_REPOSITORY,
+            /* fragmentNameToClass= */ null,
+            /* repoMapping= */ ImmutableMap.of(),
+            new SymbolGenerator<>(new Object()),
+            /* analysisRuleLabel= */ null)
+        .storeInThread(env);
+
     return env;
   }