Ignore constraint from implicit 'in Nothing'

From Array<T> <: Array<out Int> we may generate T >: Nothing (implicit) and T <: Int (explicit).
Without ignoring we'll infer 'Nothing' for T too often
This commit is contained in:
Svetlana Isakova
2014-12-19 19:24:49 +03:00
parent 70f6fcadc9
commit 6489ff2cb6
5 changed files with 39 additions and 5 deletions
@@ -0,0 +1,15 @@
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
class Foo<T>
fun <T> foo1(f: (T) -> Unit): Foo<T> = Foo()
inline fun <reified T> foo2(f: (T) -> Unit): Foo<T> = Foo()
fun test1() {
val f1: Foo<out Int> = foo1 { it checkType { it : _<Int> } }
val f2: Foo<in Nothing> = foo1 { it <!UNREACHABLE_CODE!>checkType { it : _<Nothing> }<!> }
val f3: Foo<out Int> = foo2 { it checkType { it : _<Int> } }
val f4: Foo<in Nothing> = <!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>foo2<!> { it <!UNREACHABLE_CODE!>checkType { it : _<Nothing> }<!> }
}
@@ -0,0 +1,12 @@
package
internal fun </*0*/ T> foo1(/*0*/ f: (T) -> kotlin.Unit): Foo<T>
kotlin.inline() internal fun </*0*/ reified T> foo2(/*0*/ f: (T) -> kotlin.Unit): Foo<T>
internal fun test1(): kotlin.Unit
internal final class Foo</*0*/ T> {
public constructor Foo</*0*/ T>()
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
}
@@ -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");
@@ -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)) {
@@ -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;