Fixes bug with cyclic deps in explicit bindings.

git-svn-id: https://google-guice.googlecode.com/svn/trunk@362 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/BindingBuilderImpl.java b/src/com/google/inject/BindingBuilderImpl.java
index 2b50070..796baa5 100644
--- a/src/com/google/inject/BindingBuilderImpl.java
+++ b/src/com/google/inject/BindingBuilderImpl.java
@@ -285,7 +285,8 @@
       Class<T> clazz = (Class<T>) type;
 
       BindingImpl<T> binding = injector.createBindingForInjectableType(
-          clazz, scope, source, false);
+          clazz, scope, source);
+      // TODO: Should we clean up the binding left behind in jitBindings? 
 
       if (binding == null) {
         injector.errorHandler.handle(source,
diff --git a/src/com/google/inject/ErrorMessages.java b/src/com/google/inject/ErrorMessages.java
index f2f5a61..30f6293 100644
--- a/src/com/google/inject/ErrorMessages.java
+++ b/src/com/google/inject/ErrorMessages.java
@@ -138,7 +138,7 @@
       + " types is not supported. Please use a concrete type instead of %s.";
 
   static final String CANNOT_INJECT_INNER_CLASS = "Injecting into inner"
-      + " classes is not supported.  Please use a static class (top-level or"
+      + " classes is not supported.  Please use a 'static' class (top-level or"
       + " nested) instead.";
 
   static final String ANNOTATION_ALREADY_SPECIFIED = "More than one annotation"
diff --git a/src/com/google/inject/InjectorImpl.java b/src/com/google/inject/InjectorImpl.java
index 0e9cda8..a8d0ad1 100644
--- a/src/com/google/inject/InjectorImpl.java
+++ b/src/com/google/inject/InjectorImpl.java
@@ -464,7 +464,7 @@
    */
   <T> BindingImpl<T> createBindingForInjectableType(Class<T> type) {
     return createBindingForInjectableType(type, null,
-        SourceProviders.defaultSource(), true);
+        SourceProviders.defaultSource());
   }
 
   /**
@@ -472,7 +472,7 @@
    * a scope on the type if none is specified.
    */
   <T> BindingImpl<T> createBindingForInjectableType(Class<T> type,
-      Scope scope, Object source, boolean isJit) {
+      Scope scope, Object source) {
     // We can't inject abstract classes.
     // TODO: Method interceptors could actually enable us to implement
     // abstract types. Should we remove this restriction?
@@ -501,12 +501,12 @@
     BindingImpl<T> binding
         = new ClassBindingImpl<T>(this, key, source, scopedFactory, scope);
 
-    if (isJit) {
-      // Put the partially constructed binding in the map a little early. This
-      // enables us to handle circular dependencies.
-      // Example: FooImpl -> BarImpl -> FooImpl.
-      jitBindings.put(key, binding);
-    }
+    // Put the partially constructed binding in the map a little early. This
+    // enables us to handle circular dependencies.
+    // Example: FooImpl -> BarImpl -> FooImpl.
+    // Note: We don't need to synchronize on jitBindings during injector
+    // creation.
+    jitBindings.put(key, binding);
 
     try {
       lateBoundConstructor.bind(this, type);
@@ -514,16 +514,12 @@
     }
     catch (RuntimeException e) {
       // Clean up state.
-      if (isJit) {
-        jitBindings.remove(key);
-      }
+      jitBindings.remove(key);
       throw e;
     }
     catch (Throwable t) {
       // Clean up state.
-      if (isJit) {
-        jitBindings.remove(key);
-      }
+      jitBindings.remove(key);
       throw new AssertionError(t);
     }
   }
@@ -649,7 +645,13 @@
   <T> BindingImpl<T> createBindingJustInTime(Key<T> key) {
     // Handle cases where T is a Provider<?>.
     if (isProvider(key)) {
-      return createProviderBindingUnsafely(key);
+      // These casts are safe. We know T extends Provider<X> and that given
+      // Key<Provider<X>>, createProviderBinding() will return
+      // BindingImpl<Provider<X>>.
+      @SuppressWarnings({ "UnnecessaryLocalVariable", "unchecked" })
+      BindingImpl<T> binding
+          = (BindingImpl<T>) createProviderBinding((Key) key);
+      return binding;
     }
 
     // Treat primitive types and their wrappers interchangeably.
@@ -686,15 +688,6 @@
     return createBindingFromType(clazz);
   }
 
-  @SuppressWarnings("unchecked")
-  private <T> BindingImpl<T> createProviderBindingUnsafely(Key<T> key) {
-    // These casts are safe. We know T extends Provider<X> and that given
-    // Key<Provider<X>>, createProviderBinding() will return
-    // BindingImpl<Provider<X>>.
-    // noinspection unchecked
-    return (BindingImpl<T>) createProviderBinding((Key) key);
-  }
-
   <T> InternalFactory<? extends T> getInternalFactory(Key<T> key) {
     BindingImpl<T> binding = getBinding(key);
     return binding == null ? null : binding.internalFactory;
diff --git a/test/com/google/inject/BindingTest.java b/test/com/google/inject/BindingTest.java
index f4ec2b7..7a2fcda 100644
--- a/test/com/google/inject/BindingTest.java
+++ b/test/com/google/inject/BindingTest.java
@@ -33,6 +33,18 @@
  */
 public class BindingTest extends TestCase {
 
+  public void testExplicitCyclicDependency() {
+    Guice.createInjector(new AbstractModule() {
+      protected void configure() {
+        bind(A.class);
+        bind(B.class);
+      }
+    }).getInstance(A.class);
+  }
+
+  static class A { @Inject B b; }
+  static class B { @Inject A a; }
+
   public void testProviderBinding() {
     Injector injector = Guice.createInjector();
     Binding<Bob> bobBinding = injector.getBinding(Bob.class);