diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java index 72f38b6652..b925487433 100644 --- a/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java +++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java @@ -40,6 +40,7 @@ import java.lang.reflect.Method; import java.lang.reflect.TypeVariable; import java.util.Arrays; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.OptionalDouble; @@ -922,4 +923,45 @@ public void nestedOptionalGetter() { assertThat(foo.bar()).isNotNull(); assertThat(foo.baz()).isEqualTo(0.0); } + + // Test that we can build a property of type List using a property builder whose + // build() method returns List. The main motivation for this is Kotlin, where you can + // easily run into this situation with "in" types. + // This is a "Java 8" test because the generated code uses List.of (which is actually Java 9). + // If we really are on Java 8 then the generated code will use `new ListBuilder().build()` + // instead. + @AutoValue + public abstract static class PropertyBuilderWildcard { + public abstract List list(); + + public static PropertyBuilderWildcard.Builder builder() { + return new AutoValue_AutoValueJava8Test_PropertyBuilderWildcard.Builder<>(); + } + + @AutoValue.Builder + public interface Builder { + ListBuilder listBuilder(); + + PropertyBuilderWildcard build(); + } + + public static class ListBuilder { + private final List list = new ArrayList<>(); + + public void add(T value) { + list.add(value); + } + + public List build() { + return list; + } + } + } + + @Test + public void propertyBuilderWildcard() { + PropertyBuilderWildcard.Builder builder = PropertyBuilderWildcard.builder(); + builder.listBuilder().add("foo"); + assertThat(builder.build().list()).containsExactly("foo"); + } } diff --git a/value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java b/value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java index d40a867aca..f1c7533acd 100644 --- a/value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java +++ b/value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java @@ -275,9 +275,9 @@ Optional makePropertyBuilder(ExecutableElement method, String p // We've determined that `BarBuilder` has a method `build()` or `buildOrThrow(). But it must // return `Bar`. And if the type of `bar()` is Bar then `BarBuilder.build()` must return - // Bar. + // something that can be assigned to Bar. TypeMirror buildType = eclipseHack.methodReturnType(build, barBuilderDeclaredType); - if (!MoreTypes.equivalence().equivalent(barTypeMirror, buildType)) { + if (!typeUtils.isAssignable(buildType, barTypeMirror)) { errorReporter.reportError( method, "[AutoValueBuilderWrongType] Property builder for %s has type %s whose %s() method"