From 6489ff2cb611cfe3d6bc5e88523732a3c4a450e1 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 19 Dec 2014 19:24:49 +0300 Subject: [PATCH] Ignore constraint from implicit 'in Nothing' From Array <: Array we may generate T >: Nothing (implicit) and T <: Int (explicit). Without ignoring we'll infer 'Nothing' for T too often --- .../ignoreConstraintFromImplicitInNothing.kt | 15 +++++++++++++++ .../ignoreConstraintFromImplicitInNothing.txt | 12 ++++++++++++ .../jet/checkers/JetDiagnosticsTestGenerated.java | 6 ++++++ .../resolve/calls/inference/TypeBoundsImpl.kt | 4 ---- .../lang/types/checker/TypeCheckingProcedure.java | 7 ++++++- 5 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.kt create mode 100644 compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.txt diff --git a/compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.kt b/compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.kt new file mode 100644 index 00000000000..8a53fcbb03a --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.kt @@ -0,0 +1,15 @@ +// !CHECK_TYPE +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +class Foo + +fun foo1(f: (T) -> Unit): Foo = Foo() +inline fun foo2(f: (T) -> Unit): Foo = Foo() + +fun test1() { + val f1: Foo = foo1 { it checkType { it : _ } } + val f2: Foo = foo1 { it checkType { it : _ } } + + val f3: Foo = foo2 { it checkType { it : _ } } + val f4: Foo = foo2 { it checkType { it : _ } } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.txt b/compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.txt new file mode 100644 index 00000000000..6ba6b57c13f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.txt @@ -0,0 +1,12 @@ +package + +internal fun foo1(/*0*/ f: (T) -> kotlin.Unit): Foo +kotlin.inline() internal fun foo2(/*0*/ f: (T) -> kotlin.Unit): Foo +internal fun test1(): kotlin.Unit + +internal final class Foo { + public constructor Foo() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index dc17b4d80c9..9bcc864dae3 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -5181,6 +5181,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("ignoreConstraintFromImplicitInNothing.kt") + public void testIgnoreConstraintFromImplicitInNothing() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.kt"); + doTest(fileName); + } + @TestMetadata("kt6320.kt") public void testKt6320() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/constraints/kt6320.kt"); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeBoundsImpl.kt b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeBoundsImpl.kt index fbe6eb356f3..d56fcef04e5 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeBoundsImpl.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeBoundsImpl.kt @@ -160,10 +160,6 @@ public class TypeBoundsImpl( // a captured type might be an answer if (!possibleAnswer.getConstructor().isDenotable() && !possibleAnswer.isCaptured()) return false - // e.g. if T has a lower bound 'Nothing' and an upper bound 'String', - // by default 'Nothing' is inferred which can lead to an error for reified type variable - if (typeVariable.isReified() && possibleAnswer.cannotBeReified()) return false - for (bound in bounds) { when (bound.kind) { LOWER_BOUND -> if (!JetTypeChecker.DEFAULT.isSubtypeOf(bound.constrainingType, possibleAnswer)) { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java index d5b96b0e993..5400d85ddfa 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java @@ -244,7 +244,12 @@ public class TypeCheckingProcedure { } else { if (!constraints.assertSubtype(subOut, superOut, this)) return false; - if (!constraints.assertSubtype(superIn, subIn, this)) return false; + if (superArgument.getProjectionKind() != Variance.OUT_VARIANCE) { + if (!constraints.assertSubtype(superIn, subIn, this)) return false; + } + else { + assert KotlinBuiltIns.isNothing(superIn) : "In component must be Nothing for out-projection"; + } } } return true;