Disambiguate OptionalSubject.hasValue() error message when actual and expected have equal toString's.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=146133517
diff --git a/extensions/java8/src/main/java/com/google/common/truth/OptionalSubject.java b/extensions/java8/src/main/java/com/google/common/truth/OptionalSubject.java
index df43be8..83e752c 100644
--- a/extensions/java8/src/main/java/com/google/common/truth/OptionalSubject.java
+++ b/extensions/java8/src/main/java/com/google/common/truth/OptionalSubject.java
@@ -54,6 +54,11 @@
     } else {
       Object actual = actual().get();
       if (!actual.equals(expected)) {
+        if (actual.toString().equals(expected.toString())) {
+          failWithRawMessage(
+              "Not true that %s (%s) has value <%s> (%s)",
+              actualAsString(), actual.getClass(), expected, expected.getClass());
+        }
         fail("has value", expected);
       }
     }
diff --git a/extensions/java8/src/test/java/com/google/common/truth/OptionalTest.java b/extensions/java8/src/test/java/com/google/common/truth/OptionalTest.java
index 7443fb4..c65fc64 100644
--- a/extensions/java8/src/test/java/com/google/common/truth/OptionalTest.java
+++ b/extensions/java8/src/test/java/com/google/common/truth/OptionalTest.java
@@ -157,6 +157,34 @@
   }
 
   @Test
+  public void hasValue_Named_Failing() {
+    try {
+      assertThat(Optional.of("foo")).named("bar").hasValue("boo");
+    } catch (AssertionError expected) {
+      assertThat(expected)
+          .hasMessageThat()
+          .isEqualTo("Not true that bar (<Optional[foo]>) has value <boo>");
+      return;
+    }
+    fail("Should have thrown");
+  }
+
+  @Test
+  public void hasValue_Named_FailingWithSameToStrings() {
+    try {
+      assertThat(Optional.of(10)).named("bar").hasValue("10");
+    } catch (AssertionError expected) {
+      assertThat(expected)
+          .hasMessageThat()
+          .isEqualTo(
+              "Not true that bar (<Optional[10]>) (class java.lang.Integer) "
+                  + "has value <10> (class java.lang.String)");
+      return;
+    }
+    fail("Should have thrown");
+  }
+
+  @Test
   public void assumption() {
     try {
       assume().about(optionals()).that(Optional.empty()).isPresent();