diff --git a/compiler/testData/codegen/box/reified/approximateCapturedTypes.kt b/compiler/testData/codegen/box/reified/approximateCapturedTypes.kt index 7febb78913a..3ea0849d898 100644 --- a/compiler/testData/codegen/box/reified/approximateCapturedTypes.kt +++ b/compiler/testData/codegen/box/reified/approximateCapturedTypes.kt @@ -19,7 +19,7 @@ fun box(): String { val inv = o.lift(SwOperator()) val signature = inv.javaClass.genericSuperclass.toString() - if (signature != "Inv>") return "fail 1: $signature" + if (signature != "Inv>") return "fail 1: $signature" return "OK" } diff --git a/compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt b/compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt new file mode 100644 index 00000000000..6f32d24fe2a --- /dev/null +++ b/compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt @@ -0,0 +1,15 @@ +// !CHECK_TYPE +// SKIP_TXT +fun test(b: S) { + b.collect(toList()) checkType { _>() } +} + +interface S { + fun collect(collector: C): R +} + +class C + +fun toList(): C> = null!! + +class Inv diff --git a/compiler/testData/diagnostics/testsWithJava8/collectorInference.kt b/compiler/testData/diagnostics/testsWithJava8/collectorInference.kt new file mode 100644 index 00000000000..7c393935c73 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJava8/collectorInference.kt @@ -0,0 +1,11 @@ +// !CHECK_TYPE +// SKIP_TXT +import java.util.stream.Collectors +import java.util.stream.Stream + +fun test(a: Stream) { + a.collect(Collectors.toList()) checkType { _>() } + // actually the inferred type is platform + a.collect(Collectors.toList()) checkType { _>() } +} + diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java index a2e0435d6f7..97909fbac75 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java @@ -36,6 +36,12 @@ public class DiagnosticsWithJava8TestGenerated extends AbstractDiagnosticsWithFu KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithJava8"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("collectorInference.kt") + public void testCollectorInference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJava8/collectorInference.kt"); + doTest(fileName); + } + @TestMetadata("defaultMethods.kt") public void testDefaultMethods() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJava8/defaultMethods.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index b8c949dde09..bdce5cb01b1 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -8506,6 +8506,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("doNotCaptureSupertype.kt") + public void testDoNotCaptureSupertype() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/doNotCaptureSupertype.kt"); + doTest(fileName); + } + @TestMetadata("genericsInType.kt") public void testGenericsInType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/genericsInType.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java b/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java index a4770179f9e..6e990812da2 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java @@ -264,22 +264,19 @@ public class TypeCheckingProcedure { } private boolean capture( - @NotNull TypeProjection firstProjection, - @NotNull TypeProjection secondProjection, + @NotNull TypeProjection subtypeArgumentProjection, + @NotNull TypeProjection supertypeArgumentProjection, @NotNull TypeParameterDescriptor parameter ) { // Capturing makes sense only for invariant classes if (parameter.getVariance() != INVARIANT) return false; // Now, both subtype and supertype relations transform to equality constraints on type arguments: - // Array is a subtype, supertype or equal to Array then T captures a type that extends Int: 'Captured(out Int)' - // Array is a subtype, supertype or equal to Array then T captures a type that extends Int: 'Captured(in Int)' + // Array is a subtype or equal to Array then T captures a type that extends Int: 'Captured(out Int)' + // Array is a subtype or equal to Array then T captures a type that extends Int: 'Captured(in Int)' - if (firstProjection.getProjectionKind() == INVARIANT && secondProjection.getProjectionKind() != INVARIANT) { - return constraints.capture(firstProjection.getType(), secondProjection); - } - if (firstProjection.getProjectionKind() != INVARIANT && secondProjection.getProjectionKind() == INVARIANT) { - return constraints.capture(secondProjection.getType(), firstProjection); + if (subtypeArgumentProjection.getProjectionKind() != INVARIANT && supertypeArgumentProjection.getProjectionKind() == INVARIANT) { + return constraints.capture(supertypeArgumentProjection.getType(), subtypeArgumentProjection); } return false; }