Remove delegation from most BindingExpressions. All SimpleInvocationBindingExpressions delegated for any request kind other than INSTANCE and FUTURE, so don't bother creating those.

RELNOTES=n/a

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183670291
diff --git a/java/dagger/internal/codegen/AndroidModeBindingMethodImplementation.java b/java/dagger/internal/codegen/AndroidModeBindingMethodImplementation.java
index bb2668b..ec9a5cc 100644
--- a/java/dagger/internal/codegen/AndroidModeBindingMethodImplementation.java
+++ b/java/dagger/internal/codegen/AndroidModeBindingMethodImplementation.java
@@ -42,25 +42,25 @@
 final class AndroidModeBindingMethodImplementation extends BindingMethodImplementation {
   private final GeneratedComponentModel generatedComponentModel;
   private final ComponentBindingExpressions componentBindingExpressions;
-  private final BindingExpression delegate;
+  private final BindingExpression bindingExpression;
   private final ContributionBinding binding;
   private final ReferenceReleasingManagerFields referenceReleasingManagerFields;
   private final ClassName componentName;
   private final Supplier<String> fieldName = Suppliers.memoize(this::createField);
 
   AndroidModeBindingMethodImplementation(
-      BindingExpression delegate,
+      BindingExpression bindingExpression,
       DaggerTypes types,
       Elements elements,
       GeneratedComponentModel generatedComponentModel,
       ComponentBindingExpressions componentBindingExpressions,
       ReferenceReleasingManagerFields referenceReleasingManagerFields) {
-    super(delegate, generatedComponentModel.name(), types, elements);
+    super(bindingExpression, generatedComponentModel.name(), types, elements);
     this.generatedComponentModel = generatedComponentModel;
     this.componentName = generatedComponentModel.name();
     this.componentBindingExpressions = checkNotNull(componentBindingExpressions);
-    this.delegate = delegate;
-    this.binding = delegate.resolvedBindings().contributionBinding();
+    this.bindingExpression = bindingExpression;
+    this.binding = bindingExpression.resolvedBindings().contributionBinding();
     this.referenceReleasingManagerFields = checkNotNull(referenceReleasingManagerFields);
   }
 
@@ -112,7 +112,9 @@
     return CodeBlock.builder()
         .beginControlFlow("if ($N instanceof $T)", fieldName.get(), MemoizedSentinel.class)
         .addStatement(
-            "$N = $L", fieldName.get(), delegate.getDependencyExpression(componentName).codeBlock())
+            "$N = $L",
+            fieldName.get(),
+            bindingExpression.getDependencyExpression(componentName).codeBlock())
         .endControlFlow()
         .addStatement("return ($T) $N", returnType(), fieldName.get())
         .build();
@@ -128,7 +130,9 @@
         // TODO(user): benchmark to see if this is really faster than instanceof check?
         .beginControlFlow("if (local == $L)", fieldExpression)
         .addStatement(
-            "$L = $L", fieldExpression, delegate.getDependencyExpression(componentName).codeBlock())
+            "$L = $L",
+            fieldExpression,
+            bindingExpression.getDependencyExpression(componentName).codeBlock())
         .endControlFlow()
         .addStatement("local = $L", fieldExpression)
         .endControlFlow()
diff --git a/java/dagger/internal/codegen/ComponentBindingExpressions.java b/java/dagger/internal/codegen/ComponentBindingExpressions.java
index 64d316e..d477b02 100644
--- a/java/dagger/internal/codegen/ComponentBindingExpressions.java
+++ b/java/dagger/internal/codegen/ComponentBindingExpressions.java
@@ -25,6 +25,7 @@
 import static dagger.internal.codegen.CodeBlocks.makeParametersCodeBlock;
 import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.SINGLETON_INSTANCE;
 import static dagger.internal.codegen.DaggerStreams.toImmutableList;
+import static dagger.internal.codegen.DelegateBindingExpression.isBindsScopeStrongerThanDependencyScope;
 import static dagger.internal.codegen.MemberSelect.staticMemberSelect;
 import static dagger.internal.codegen.SourceFiles.membersInjectorNameForType;
 import static dagger.internal.codegen.TypeNames.DOUBLE_CHECK;
@@ -32,6 +33,7 @@
 import static dagger.internal.codegen.TypeNames.SINGLE_CHECK;
 import static dagger.model.BindingKind.COMPONENT;
 import static dagger.model.BindingKind.COMPONENT_DEPENDENCY;
+import static dagger.model.BindingKind.DELEGATE;
 import static dagger.model.BindingKind.INJECTION;
 import static dagger.model.BindingKind.MULTIBOUND_MAP;
 import static dagger.model.BindingKind.MULTIBOUND_SET;
@@ -299,6 +301,7 @@
     BindingExpression create(ResolvedBindings resolvedBindings, RequestKind requestKind) {
       switch (resolvedBindings.bindingType()) {
         case MEMBERS_INJECTION:
+          checkArgument(requestKind.equals(RequestKind.MEMBERS_INJECTION));
           return membersInjectionBindingExpression(resolvedBindings);
 
         case PROVISION:
@@ -474,13 +477,8 @@
     /** Returns a binding expression for a provision binding. */
     private BindingExpression provisionBindingExpression(
         ResolvedBindings resolvedBindings, RequestKind requestKind) {
-      FrameworkInstanceBindingExpression frameworkInstanceBindingExpression =
-          requestKind.equals(RequestKind.PRODUCER)
-              ? producerFromProviderInstanceBindingExpression(resolvedBindings, requestKind)
-              : frameworkInstanceBindingExpression(resolvedBindings, requestKind);
-
-      BindingExpression inlineBindingExpression =
-          inlineProvisionBindingExpression(frameworkInstanceBindingExpression);
+      BindingExpression bindingExpression =
+          basicProvisionBindingExpression(resolvedBindings, requestKind);
 
       Optional<ComponentMethodDescriptor> componentMethod =
           findMatchingComponentMethod(resolvedBindings.key(), requestKind);
@@ -493,19 +491,21 @@
         return new ComponentMethodBindingExpression(
             resolvedBindings,
             requestKind,
-            methodImplementation(inlineBindingExpression),
+            methodImplementation(bindingExpression),
             generatedComponentModel,
             componentMethod.get(),
             componentBindingExpressions);
-      } else if (shouldUsePrivateMethod(resolvedBindings.contributionBinding(), requestKind)) {
+      }
+
+      if (shouldUsePrivateMethod(resolvedBindings.contributionBinding(), requestKind)) {
         return new PrivateMethodBindingExpression(
             resolvedBindings,
             requestKind,
-            methodImplementation(inlineBindingExpression),
+            methodImplementation(bindingExpression),
             generatedComponentModel);
       }
 
-      return inlineBindingExpression;
+      return bindingExpression;
     }
 
     private BindingMethodImplementation methodImplementation(BindingExpression bindingExpression) {
@@ -608,26 +608,53 @@
           elements);
     }
 
-    private BindingExpression inlineProvisionBindingExpression(
-        BindingExpression bindingExpression) {
-      ProvisionBinding provisionBinding =
-          (ProvisionBinding) bindingExpression.resolvedBindings().contributionBinding();
-      switch (provisionBinding.kind()) {
+    /**
+     * Returns a binding expression that does not create a private method on the component or use a
+     * component provision method.
+     */
+    private BindingExpression basicProvisionBindingExpression(
+        ResolvedBindings resolvedBindings, RequestKind requestKind) {
+      if (resolvedBindings.contributionBinding().kind().equals(DELEGATE)
+          && !isBindsScopeStrongerThanDependencyScope(resolvedBindings, graph)) {
+        return new DelegateBindingExpression(
+            resolvedBindings, requestKind, componentBindingExpressions, types, elements);
+      }
+      switch (requestKind) {
+        case PRODUCER:
+          return producerFromProviderInstanceBindingExpression(resolvedBindings, requestKind);
+
+        case INSTANCE:
+        case FUTURE:
+          return instanceOrFutureBindingExpression(resolvedBindings, requestKind);
+
+        default:
+          return frameworkInstanceBindingExpression(resolvedBindings, requestKind);
+      }
+    }
+
+    /**
+     * Returns a binding expression for an {@link RequestKind#INSTANCE} or {@link
+     * RequestKind#FUTURE}, which might be a {@link SimpleInvocationBindingExpression}.
+     */
+    private BindingExpression instanceOrFutureBindingExpression(
+        ResolvedBindings resolvedBindings, RequestKind requestKind) {
+      switch (resolvedBindings.contributionBinding().kind()) {
         case COMPONENT:
           return new ComponentInstanceBindingExpression(
-              bindingExpression, provisionBinding, generatedComponentModel.name(), types);
+              resolvedBindings, requestKind, generatedComponentModel.name(), types);
 
         case COMPONENT_DEPENDENCY:
           return new ComponentRequirementBindingExpression(
-              bindingExpression,
-              ComponentRequirement.forDependency(provisionBinding.key().type()),
+              resolvedBindings,
+              requestKind,
+              ComponentRequirement.forDependency(resolvedBindings.key().type()),
               componentRequirementFields,
               types);
 
         case COMPONENT_PROVISION:
           return new ComponentProvisionBindingExpression(
-              bindingExpression,
-              provisionBinding,
+              resolvedBindings,
+              requestKind,
               graph,
               componentRequirementFields,
               compilerOptions,
@@ -635,72 +662,61 @@
 
         case SUBCOMPONENT_BUILDER:
           return new SubcomponentBuilderBindingExpression(
-              bindingExpression,
-              provisionBinding,
-              subcomponentNames.get(bindingExpression.key()),
-              types);
+              resolvedBindings, requestKind, subcomponentNames.get(resolvedBindings.key()), types);
 
         case MULTIBOUND_SET:
           return new SetBindingExpression(
-              provisionBinding,
-              graph,
-              componentBindingExpressions,
-              bindingExpression,
-              types,
-              elements);
+              resolvedBindings, requestKind, graph, componentBindingExpressions, types, elements);
 
         case MULTIBOUND_MAP:
           return new MapBindingExpression(
-              provisionBinding,
-              graph,
-              componentBindingExpressions,
-              bindingExpression,
-              types,
-              elements);
+              resolvedBindings, requestKind, graph, componentBindingExpressions, types, elements);
 
         case OPTIONAL:
           return new OptionalBindingExpression(
-              provisionBinding, bindingExpression, componentBindingExpressions, types);
-
-        case DELEGATE:
-          return DelegateBindingExpression.create(
-              graph, bindingExpression, componentBindingExpressions, types, elements);
+              resolvedBindings, requestKind, componentBindingExpressions, types);
 
         case BOUND_INSTANCE:
           return new ComponentRequirementBindingExpression(
-              bindingExpression,
-              ComponentRequirement.forBoundInstance(provisionBinding),
+              resolvedBindings,
+              requestKind,
+              ComponentRequirement.forBoundInstance(resolvedBindings.contributionBinding()),
               componentRequirementFields,
               types);
 
         case INJECTION:
         case PROVISION:
-          if (canUseSimpleMethod(provisionBinding)) {
+          if (canCallSimpleMethod(resolvedBindings)) {
             return new SimpleMethodBindingExpression(
+                resolvedBindings,
+                requestKind,
                 compilerOptions,
-                provisionBinding,
-                bindingExpression,
                 componentBindingExpressions,
                 membersInjectionMethods,
                 componentRequirementFields,
                 types,
                 elements);
           }
-          // fall through
+          break;
 
         default:
-          return bindingExpression;
+          break;
       }
+      return frameworkInstanceBindingExpression(resolvedBindings, requestKind);
     }
 
-    private boolean canUseSimpleMethod(ContributionBinding binding) {
-      // Use the inlined form when in experimentalAndroidMode, as PrivateMethodBindingExpression
-      // implements scoping directly
-      // TODO(user): Also inline releasable references in experimentalAndroidMode
-      return !binding.scope().isPresent()
-          || (compilerOptions.experimentalAndroidMode()
-              && !referenceReleasingManagerFields.requiresReleasableReferences(
-                  binding.scope().get()));
+    private boolean canCallSimpleMethod(ResolvedBindings resolvedBindings) {
+      Optional<Scope> scope = resolvedBindings.contributionBinding().scope();
+      if (compilerOptions.experimentalAndroidMode()) {
+        // In Android mode we can call simple methods unless the scope is a releasable-references
+        // scope.
+        // TODO(user): Also inline releasable references in experimentalAndroidMode
+        return !scope.isPresent()
+            || !referenceReleasingManagerFields.requiresReleasableReferences(scope.get());
+      } else {
+        // In default mode, we can call simple methods unless the binding is scoped.
+        return !scope.isPresent();
+      }
     }
   }
 }
diff --git a/java/dagger/internal/codegen/ComponentInstanceBindingExpression.java b/java/dagger/internal/codegen/ComponentInstanceBindingExpression.java
index f1c2e6a..0febe94 100644
--- a/java/dagger/internal/codegen/ComponentInstanceBindingExpression.java
+++ b/java/dagger/internal/codegen/ComponentInstanceBindingExpression.java
@@ -18,6 +18,7 @@
 
 import com.squareup.javapoet.ClassName;
 import com.squareup.javapoet.CodeBlock;
+import dagger.model.RequestKind;
 
 /** A binding expression for the instance of the component itself, i.e. {@code this}. */
 final class ComponentInstanceBindingExpression extends SimpleInvocationBindingExpression {
@@ -25,13 +26,13 @@
   private final ContributionBinding binding;
 
   ComponentInstanceBindingExpression(
-      BindingExpression delegate,
-      ContributionBinding binding,
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       ClassName componentName,
       DaggerTypes types) {
-    super(delegate, types);
+    super(resolvedBindings, requestKind, types);
     this.componentName = componentName;
-    this.binding = binding;
+    this.binding = resolvedBindings.contributionBinding();
   }
 
   @Override
diff --git a/java/dagger/internal/codegen/ComponentProvisionBindingExpression.java b/java/dagger/internal/codegen/ComponentProvisionBindingExpression.java
index d95267b..c3e53e8 100644
--- a/java/dagger/internal/codegen/ComponentProvisionBindingExpression.java
+++ b/java/dagger/internal/codegen/ComponentProvisionBindingExpression.java
@@ -22,6 +22,7 @@
 import com.squareup.javapoet.ClassName;
 import com.squareup.javapoet.CodeBlock;
 import dagger.internal.Preconditions;
+import dagger.model.RequestKind;
 
 /** A binding expression for component provision methods. */
 final class ComponentProvisionBindingExpression extends SimpleInvocationBindingExpression {
@@ -31,14 +32,14 @@
   private final CompilerOptions compilerOptions;
 
   ComponentProvisionBindingExpression(
-      BindingExpression providerBindingExpression,
-      ProvisionBinding binding,
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       BindingGraph bindingGraph,
       ComponentRequirementFields componentRequirementFields,
       CompilerOptions compilerOptions,
       DaggerTypes types) {
-    super(providerBindingExpression, types);
-    this.binding = checkNotNull(binding);
+    super(resolvedBindings, requestKind, types);
+    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
     this.bindingGraph = checkNotNull(bindingGraph);
     this.componentRequirementFields = checkNotNull(componentRequirementFields);
     this.compilerOptions = checkNotNull(compilerOptions);
diff --git a/java/dagger/internal/codegen/ComponentRequirementBindingExpression.java b/java/dagger/internal/codegen/ComponentRequirementBindingExpression.java
index d2d5794..68abf5d 100644
--- a/java/dagger/internal/codegen/ComponentRequirementBindingExpression.java
+++ b/java/dagger/internal/codegen/ComponentRequirementBindingExpression.java
@@ -17,6 +17,7 @@
 package dagger.internal.codegen;
 
 import com.squareup.javapoet.ClassName;
+import dagger.model.RequestKind;
 
 /**
  * A binding expression for instances bound with {@link dagger.BindsInstance} and instances of
@@ -28,11 +29,12 @@
   private final ComponentRequirementFields componentRequirementFields;
 
   ComponentRequirementBindingExpression(
-      BindingExpression delegate,
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       ComponentRequirement componentRequirement,
       ComponentRequirementFields componentRequirementFields,
       DaggerTypes types) {
-    super(delegate, types);
+    super(resolvedBindings, requestKind, types);
     this.componentRequirement = componentRequirement;
     this.componentRequirementFields = componentRequirementFields;
   }
diff --git a/java/dagger/internal/codegen/DelegateBindingExpression.java b/java/dagger/internal/codegen/DelegateBindingExpression.java
index 55fb86d..562cfba 100644
--- a/java/dagger/internal/codegen/DelegateBindingExpression.java
+++ b/java/dagger/internal/codegen/DelegateBindingExpression.java
@@ -16,10 +16,12 @@
 
 package dagger.internal.codegen;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Iterables.getOnlyElement;
 import static dagger.internal.codegen.Accessibility.isTypeAccessibleFrom;
 import static dagger.internal.codegen.RequestKinds.requestType;
+import static dagger.model.BindingKind.DELEGATE;
 
 import com.squareup.javapoet.ClassName;
 import dagger.model.RequestKind;
@@ -34,7 +36,7 @@
   private final DaggerTypes types;
   private final BindsTypeChecker bindsTypeChecker;
 
-  private DelegateBindingExpression(
+  DelegateBindingExpression(
       ResolvedBindings resolvedBindings,
       RequestKind requestKind,
       ComponentBindingExpressions componentBindingExpressions,
@@ -47,24 +49,22 @@
     this.bindsTypeChecker = new BindsTypeChecker(types, elements);
   }
 
-  static BindingExpression create(
-      BindingGraph graph,
-      BindingExpression bindingExpression,
-      ComponentBindingExpressions componentBindingExpressions,
-      DaggerTypes types,
-      Elements elements) {
-    ResolvedBindings resolvedBindings = bindingExpression.resolvedBindings();
-    ContributionBinding binding = resolvedBindings.contributionBinding();
-    Binding delegateBinding =
-        graph.contributionBindings().get(getOnlyElement(binding.dependencies()).key()).binding();
-    ScopeKind bindsScope = ScopeKind.get(binding, graph, elements);
-    ScopeKind delegateScope = ScopeKind.get(delegateBinding, graph, elements);
-    if (bindsScope.isSimilarOrWeakerScopeThan(delegateScope)) {
-      RequestKind requestKind = bindingExpression.requestKind();
-      return new DelegateBindingExpression(
-          resolvedBindings, requestKind, componentBindingExpressions, types, elements);
-    }
-    return bindingExpression;
+  /**
+   * Returns {@code true} if the {@code @Binds} binding's scope is stronger than the scope of the
+   * binding it depends on.
+   */
+  static boolean isBindsScopeStrongerThanDependencyScope(
+      ResolvedBindings resolvedBindings, BindingGraph graph) {
+    ContributionBinding bindsBinding = resolvedBindings.contributionBinding();
+    checkArgument(bindsBinding.kind().equals(DELEGATE));
+    Binding dependencyBinding =
+        graph
+            .contributionBindings()
+            .get(getOnlyElement(bindsBinding.dependencies()).key())
+            .binding();
+    ScopeKind bindsScope = ScopeKind.get(bindsBinding, graph);
+    ScopeKind dependencyScope = ScopeKind.get(dependencyBinding, graph);
+    return bindsScope.isStrongerScopeThan(dependencyScope);
   }
 
   @Override
@@ -116,7 +116,7 @@
     DOUBLE_CHECK,
     ;
 
-    static ScopeKind get(Binding binding, BindingGraph graph, Elements elements) {
+    static ScopeKind get(Binding binding, BindingGraph graph) {
       if (!binding.scope().isPresent()) {
         return UNSCOPED;
       }
@@ -128,8 +128,8 @@
       return scope.isReusable() ? SINGLE_CHECK : DOUBLE_CHECK;
     }
 
-    boolean isSimilarOrWeakerScopeThan(ScopeKind other) {
-      return ordinal() <= other.ordinal();
+    boolean isStrongerScopeThan(ScopeKind other) {
+      return this.ordinal() > other.ordinal();
     }
   }
 }
diff --git a/java/dagger/internal/codegen/MapBindingExpression.java b/java/dagger/internal/codegen/MapBindingExpression.java
index 150bdae..5de5038 100644
--- a/java/dagger/internal/codegen/MapBindingExpression.java
+++ b/java/dagger/internal/codegen/MapBindingExpression.java
@@ -30,6 +30,7 @@
 import dagger.internal.MapBuilder;
 import dagger.model.BindingKind;
 import dagger.model.DependencyRequest;
+import dagger.model.RequestKind;
 import java.util.Collections;
 import java.util.Map;
 import javax.lang.model.type.TypeMirror;
@@ -46,16 +47,16 @@
   private final Elements elements;
 
   MapBindingExpression(
-      ProvisionBinding binding,
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       BindingGraph graph,
       ComponentBindingExpressions componentBindingExpressions,
-      BindingExpression delegate,
       DaggerTypes types,
       Elements elements) {
-    super(delegate, types);
-    BindingKind bindingKind = binding.kind();
+    super(resolvedBindings, requestKind, types);
+    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
+    BindingKind bindingKind = this.binding.kind();
     checkArgument(bindingKind.equals(MULTIBOUND_MAP), bindingKind);
-    this.binding = binding;
     this.componentBindingExpressions = componentBindingExpressions;
     this.elements = elements;
     this.dependencies =
diff --git a/java/dagger/internal/codegen/OptionalBindingExpression.java b/java/dagger/internal/codegen/OptionalBindingExpression.java
index e1f1da8..a6aa380 100644
--- a/java/dagger/internal/codegen/OptionalBindingExpression.java
+++ b/java/dagger/internal/codegen/OptionalBindingExpression.java
@@ -23,6 +23,7 @@
 import com.squareup.javapoet.CodeBlock;
 import dagger.internal.codegen.OptionalType.OptionalKind;
 import dagger.model.DependencyRequest;
+import dagger.model.RequestKind;
 import javax.inject.Inject;
 import javax.lang.model.util.Types;
 
@@ -34,12 +35,12 @@
 
   @Inject
   OptionalBindingExpression(
-      ProvisionBinding binding,
-      BindingExpression delegate,
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       ComponentBindingExpressions componentBindingExpressions,
       DaggerTypes types) {
-    super(delegate, types);
-    this.binding = binding;
+    super(resolvedBindings, requestKind, types);
+    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
     this.componentBindingExpressions = componentBindingExpressions;
     this.types = types;
   }
diff --git a/java/dagger/internal/codegen/SetBindingExpression.java b/java/dagger/internal/codegen/SetBindingExpression.java
index 96b9002..091f6f0 100644
--- a/java/dagger/internal/codegen/SetBindingExpression.java
+++ b/java/dagger/internal/codegen/SetBindingExpression.java
@@ -25,6 +25,7 @@
 import com.squareup.javapoet.CodeBlock;
 import dagger.internal.SetBuilder;
 import dagger.model.DependencyRequest;
+import dagger.model.RequestKind;
 import java.util.Collections;
 import java.util.Set;
 import javax.lang.model.type.TypeMirror;
@@ -38,14 +39,14 @@
   private final Elements elements;
 
   SetBindingExpression(
-      ProvisionBinding binding,
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       BindingGraph graph,
       ComponentBindingExpressions componentBindingExpressions,
-      BindingExpression delegate,
       DaggerTypes types,
       Elements elements) {
-    super(delegate, types);
-    this.binding = binding;
+    super(resolvedBindings, requestKind, types);
+    this.binding = (ProvisionBinding) resolvedBindings.contributionBinding();
     this.graph = graph;
     this.componentBindingExpressions = componentBindingExpressions;
     this.elements = elements;
diff --git a/java/dagger/internal/codegen/SimpleInvocationBindingExpression.java b/java/dagger/internal/codegen/SimpleInvocationBindingExpression.java
index 2c57c49..d2f692b 100644
--- a/java/dagger/internal/codegen/SimpleInvocationBindingExpression.java
+++ b/java/dagger/internal/codegen/SimpleInvocationBindingExpression.java
@@ -16,22 +16,30 @@
 
 package dagger.internal.codegen;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.squareup.javapoet.ClassName;
 import com.squareup.javapoet.CodeBlock;
+import dagger.model.RequestKind;
 
 /**
  * A binding expression that can use a simple expression for instance requests, and delegates to
  * another expression for other requests.
  */
 abstract class SimpleInvocationBindingExpression extends BindingExpression {
-  private final BindingExpression delegate;
+
+  private static final ImmutableSet<RequestKind> REQUEST_KINDS =
+      ImmutableSet.of(RequestKind.INSTANCE, RequestKind.FUTURE);
+
   private final DaggerTypes types;
 
-  SimpleInvocationBindingExpression(BindingExpression delegate, DaggerTypes types) {
-    super(delegate.resolvedBindings(), delegate.requestKind());
-    this.delegate = delegate;
+  SimpleInvocationBindingExpression(
+      ResolvedBindings resolvedBindings, RequestKind requestKind, DaggerTypes types) {
+    super(resolvedBindings, requestKind);
+    checkArgument(REQUEST_KINDS.contains(requestKind));
     this.types = types;
   }
 
@@ -68,7 +76,7 @@
                 .add("immediateFuture($L)", expression.codeBlock())
                 .build());
       default:
-        return delegate.getDependencyExpression(requestingClass);
+        throw new AssertionError(requestKind());
     }
   }
 }
diff --git a/java/dagger/internal/codegen/SimpleMethodBindingExpression.java b/java/dagger/internal/codegen/SimpleMethodBindingExpression.java
index 12ca8e2..6973443 100644
--- a/java/dagger/internal/codegen/SimpleMethodBindingExpression.java
+++ b/java/dagger/internal/codegen/SimpleMethodBindingExpression.java
@@ -30,6 +30,7 @@
 import com.squareup.javapoet.TypeName;
 import dagger.internal.codegen.InjectionMethods.ProvisionMethod;
 import dagger.model.DependencyRequest;
+import dagger.model.RequestKind;
 import java.util.Optional;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ExecutableElement;
@@ -50,21 +51,21 @@
   private final Elements elements;
 
   SimpleMethodBindingExpression(
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       CompilerOptions compilerOptions,
-      ProvisionBinding provisionBinding,
-      BindingExpression delegate,
       ComponentBindingExpressions componentBindingExpressions,
       MembersInjectionMethods membersInjectionMethods,
       ComponentRequirementFields componentRequirementFields,
       DaggerTypes types,
       Elements elements) {
-    super(delegate, types);
+    super(resolvedBindings, requestKind, types);
+    this.compilerOptions = compilerOptions;
+    this.provisionBinding = (ProvisionBinding) resolvedBindings.contributionBinding();
     checkArgument(
         provisionBinding.implicitDependencies().isEmpty(),
         "framework deps are not currently supported");
     checkArgument(provisionBinding.bindingElement().isPresent());
-    this.compilerOptions = compilerOptions;
-    this.provisionBinding = provisionBinding;
     this.componentBindingExpressions = componentBindingExpressions;
     this.membersInjectionMethods = membersInjectionMethods;
     this.componentRequirementFields = componentRequirementFields;
diff --git a/java/dagger/internal/codegen/SubcomponentBuilderBindingExpression.java b/java/dagger/internal/codegen/SubcomponentBuilderBindingExpression.java
index fec388f..9df3502 100644
--- a/java/dagger/internal/codegen/SubcomponentBuilderBindingExpression.java
+++ b/java/dagger/internal/codegen/SubcomponentBuilderBindingExpression.java
@@ -18,6 +18,7 @@
 
 import com.squareup.javapoet.ClassName;
 import com.squareup.javapoet.CodeBlock;
+import dagger.model.RequestKind;
 
 /** A binding expression for a subcomponent builder that just invokes the constructor. */
 final class SubcomponentBuilderBindingExpression extends SimpleInvocationBindingExpression {
@@ -25,13 +26,13 @@
   private final ContributionBinding binding;
 
   SubcomponentBuilderBindingExpression(
-      BindingExpression delegate,
-      ContributionBinding binding,
+      ResolvedBindings resolvedBindings,
+      RequestKind requestKind,
       String subcomponentBuilderName,
       DaggerTypes types) {
-    super(delegate, types);
+    super(resolvedBindings, requestKind, types);
     this.subcomponentBuilderName = subcomponentBuilderName;
-    this.binding = binding;
+    this.binding = resolvedBindings.contributionBinding();
   }
 
   @Override