[NI] Revise variance calculation method for completion mode

Before fix only one level of type arguments was used to determine variance of type variable to find out direction requirements.
This incorrect in general case, because outer variance affects subtyping deductions, for example:
Inv<Out<A>> <: Inv<Out<B>> => A <: B; B <: A, despite A and B are in covariant position if only one level is considered

^KT-36233 Fixed
This commit is contained in:
Pavel Kirpichenkov
2020-01-30 19:06:21 +03:00
parent e27b2990e3
commit 517688e163
22 changed files with 904 additions and 39 deletions
@@ -10602,21 +10602,51 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/inference/completion/basic.kt");
}
@TestMetadata("definetlyNotNullType.kt")
public void testDefinetlyNotNullType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.kt");
}
@TestMetadata("equalityConstraintUpstairs.kt")
public void testEqualityConstraintUpstairs() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/equalityConstraintUpstairs.kt");
}
@TestMetadata("flexibleType.kt")
public void testFlexibleType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/flexibleType.kt");
}
@TestMetadata("intersectionType.kt")
public void testIntersectionType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/intersectionType.kt");
}
@TestMetadata("kt33166.kt")
public void testKt33166() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/kt33166.kt");
}
@TestMetadata("kt36233.kt")
public void testKt36233() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/kt36233.kt");
}
@TestMetadata("lambdaWithVariableAndNothing.kt")
public void testLambdaWithVariableAndNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/lambdaWithVariableAndNothing.kt");
}
@TestMetadata("nestedVariance.kt")
public void testNestedVariance() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/nestedVariance.kt");
}
@TestMetadata("nothingFromNestedCall.kt")
public void testNothingFromNestedCall() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.kt");
}
@TestMetadata("partialForIlt.kt")
public void testPartialForIlt() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/partialForIlt.kt");
@@ -83,19 +83,16 @@ class CompletionModeCalculator {
while (typesToProcess.isNotEmpty()) {
val type = typesToProcess.poll() ?: break
fixationDirectionForTopLevel(type)?.let { directionForVariable ->
if (!type.contains { it.typeConstructor() in notFixedTypeVariables })
continue
val fixationDirectionsFromType = mutableSetOf<FixationDirectionForVariable>()
collectRequiredDirectionsForVariables(type, TypeVariance.OUT, fixationDirectionsFromType)
for (directionForVariable in fixationDirectionsFromType) {
updateDirection(directionForVariable)
enqueueTypesFromConstraints(directionForVariable.variable)
}
// find all variables in type and make requirements for them
type.contains { typePart ->
for (directionForVariable in directionsForVariablesInTypeArguments(typePart)) {
updateDirection(directionForVariable)
enqueueTypesFromConstraints(directionForVariable.variable)
}
false
}
}
}
@@ -130,42 +127,62 @@ class CompletionModeCalculator {
private data class FixationDirectionForVariable(val variable: VariableWithConstraints, val direction: FixationDirection)
private fun CsCompleterContext.fixationDirectionForTopLevel(type: KotlinTypeMarker): FixationDirectionForVariable? {
return notFixedTypeVariables[type.typeConstructor()]?.let {
FixationDirectionForVariable(it, FixationDirection.TO_SUBTYPE)
private fun CsCompleterContext.collectRequiredDirectionsForVariables(
type: KotlinTypeMarker, outerVariance: TypeVariance,
fixationDirectionsCollector: MutableSet<FixationDirectionForVariable>
) {
val typeArgumentsCount = type.argumentsCount()
if (typeArgumentsCount > 0) {
for (position in 0 until typeArgumentsCount) {
val argument = type.getArgument(position)
val parameter = type.typeConstructor().getParameter(position)
if (argument.isStarProjection())
continue
collectRequiredDirectionsForVariables(
argument.getType(),
compositeVariance(outerVariance, argument, parameter),
fixationDirectionsCollector
)
}
} else {
processTypeWithoutParameters(type, outerVariance, fixationDirectionsCollector)
}
}
private fun CsCompleterContext.directionsForVariablesInTypeArguments(type: KotlinTypeMarker): List<FixationDirectionForVariable> {
assert(type.argumentsCount() == type.typeConstructor().parametersCount()) {
"Arguments and parameters count don't match for type $type. " +
"Arguments: ${type.argumentsCount()}, parameters: ${type.typeConstructor().parametersCount()}"
private fun CsCompleterContext.compositeVariance(
outerVariance: TypeVariance,
argument: TypeArgumentMarker,
parameter: TypeParameterMarker
): TypeVariance {
val effectiveArgumentVariance = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance())
?: TypeVariance.INV // conflicting variance
return when (outerVariance) {
TypeVariance.INV -> TypeVariance.INV
TypeVariance.OUT -> effectiveArgumentVariance
TypeVariance.IN -> effectiveArgumentVariance.reversed()
}
}
val directionsForVariables = mutableListOf<FixationDirectionForVariable>()
private fun TypeVariance.reversed(): TypeVariance = when (this) {
TypeVariance.IN -> TypeVariance.OUT
TypeVariance.OUT -> TypeVariance.IN
TypeVariance.INV -> TypeVariance.INV
}
for (position in 0 until type.argumentsCount()) {
val argument = type.getArgument(position)
if (!argument.getType().mayBeTypeVariable())
continue
val variableWithConstraints = notFixedTypeVariables[argument.getType().typeConstructor()] ?: continue
val parameter = type.typeConstructor().getParameter(position)
val effectiveVariance = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance())
?: TypeVariance.INV
val direction = when (effectiveVariance) {
TypeVariance.IN -> FixationDirection.EQUALITY // Assuming that variables in contravariant positions are fixed to subtype
TypeVariance.OUT -> FixationDirection.TO_SUBTYPE
TypeVariance.INV -> FixationDirection.EQUALITY
}
val requirement = FixationDirectionForVariable(variableWithConstraints, direction)
directionsForVariables.add(requirement)
private fun CsCompleterContext.processTypeWithoutParameters(
type: KotlinTypeMarker, compositeVariance: TypeVariance,
newRequirementsCollector: MutableSet<FixationDirectionForVariable>
) {
val variableWithConstraints = notFixedTypeVariables[type.typeConstructor()] ?: return
val direction = when (compositeVariance) {
TypeVariance.IN -> FixationDirection.EQUALITY // Assuming that variables in contravariant positions are fixed to subtype
TypeVariance.OUT -> FixationDirection.TO_SUBTYPE
TypeVariance.INV -> FixationDirection.EQUALITY
}
return directionsForVariables
val requirement = FixationDirectionForVariable(variableWithConstraints, direction)
newRequirementsCollector.add(requirement)
}
private fun CsCompleterContext.hasProperConstraint(
@@ -0,0 +1,39 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun <T : Derived?> test(derived: T) {
id<Out<Base>>(
makeOut(
makeDnn(derived)
)
)
id<In<Base>>(
makeIn(
makeDnn(derived)
)
)
id<Inv<Base>>(
makeInv(
makeDnn(derived)
)
)
id<In<In<Base>>>(
makeInIn(
makeDnn(derived)
)
)
}
interface Base
open class Derived : Base
class Inv<T>
class Out<out O>
class In<in I>
fun <K> id(arg: K) = arg
fun <T : Any> makeDnn(arg: T?): T = TODO()
fun <T> makeInv(arg: T): Inv<T> = TODO()
fun <T> makeOut(arg: T): Out<T> = TODO()
fun <T> makeIn(arg: T): In<T> = TODO()
fun <T> makeInIn(arg: T): In<In<T>> = TODO()
@@ -0,0 +1,39 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun <T : Derived?> test(derived: T) {
<!DEBUG_INFO_EXPRESSION_TYPE("Out<Base>")!>id<Out<Base>>(
makeOut(
<!DEBUG_INFO_EXPRESSION_TYPE("T!!")!>makeDnn(derived)<!>
)
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("In<Base>")!>id<In<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<Base>")!>makeIn(
<!DEBUG_INFO_EXPRESSION_TYPE("T!!")!>makeDnn(derived)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Base>")!>id<Inv<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Base>")!>makeInv(
<!DEBUG_INFO_EXPRESSION_TYPE("T!!")!>makeDnn(derived)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("In<In<Base>>")!>id<In<In<Base>>>(
makeInIn(
<!DEBUG_INFO_EXPRESSION_TYPE("T!!")!>makeDnn(derived)<!>
)
)<!>
}
interface Base
open class Derived : Base
class Inv<T>
class Out<out O>
class In<in I>
fun <K> id(arg: K) = arg
fun <T : Any> makeDnn(arg: T?): T = TODO()
fun <T> makeInv(arg: T): Inv<T> = TODO()
fun <T> makeOut(arg: T): Out<T> = TODO()
fun <T> makeIn(arg: T): In<T> = TODO()
fun <T> makeInIn(arg: T): In<In<T>> = TODO()
@@ -0,0 +1,43 @@
package
public fun </*0*/ K> id(/*0*/ arg: K): K
public fun </*0*/ T : kotlin.Any> makeDnn(/*0*/ arg: T?): T
public fun </*0*/ T> makeIn(/*0*/ arg: T): In<T>
public fun </*0*/ T> makeInIn(/*0*/ arg: T): In<In<T>>
public fun </*0*/ T> makeInv(/*0*/ arg: T): Inv<T>
public fun </*0*/ T> makeOut(/*0*/ arg: T): Out<T>
public fun </*0*/ T : Derived?> test(/*0*/ derived: T): kotlin.Unit
public interface Base {
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
}
public open class Derived : Base {
public constructor Derived()
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
}
public final class In</*0*/ in I> {
public constructor In</*0*/ in I>()
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
}
public final class Inv</*0*/ T> {
public constructor Inv</*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
}
public final class Out</*0*/ out O> {
public constructor Out</*0*/ out O>()
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
}
@@ -0,0 +1,60 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: Test.kt
fun test(arg: Derived) {
id<Out<Base>>(
createOut(
JavaCls.makeFlexible(arg)
)
)
id<In<Base>>(
createIn(
JavaCls.makeFlexible(arg)
)
)
id<Inv<Base>>(
createInv(
JavaCls.makeFlexible(arg)
)
)
id<JavaInv<Out<Base>>>(
createJavaInv(
JavaCls.makeFlexible(arg)
)
)
id<In<In<Base>>>(
createInIn(
JavaCls.makeFlexible(arg)
)
)
}
interface Base
class Derived : Base
class Inv<T>
class Out<out O>
class In<in I>
fun <K> id(arg: K) = arg
fun <T> createInv(arg: T): Inv<T> = TODO()
fun <T> createOut(arg: T): Out<T> = TODO()
fun <T> createIn(arg: T): In<T> = TODO()
fun <T> createInIn(arg: T): In<In<T>> = TODO()
fun <T> createJavaInv(arg: T): JavaInv<Out<T>> = TODO()
// FILE: JavaCls.java
public class JavaCls {
public static <T> T makeFlexible(T argument) {
return argument;
}
}
// FILE: JavaInv.java
public class JavaInv <T> {
}
@@ -0,0 +1,60 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: Test.kt
fun test(arg: Derived) {
<!DEBUG_INFO_EXPRESSION_TYPE("Out<Base>")!>id<Out<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Out<(Derived..Derived?)>")!>createOut(
<!DEBUG_INFO_EXPRESSION_TYPE("(Derived..Derived?)")!>JavaCls.makeFlexible(arg)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("In<Base>")!>id<In<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<(Base..Base?)>")!>createIn(
<!DEBUG_INFO_EXPRESSION_TYPE("(Derived..Derived?)")!>JavaCls.makeFlexible(arg)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Base>")!>id<Inv<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Base>")!>createInv(
<!DEBUG_INFO_EXPRESSION_TYPE("(Derived..Derived?)")!>JavaCls.makeFlexible(arg)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("JavaInv<Out<Base>>")!>id<JavaInv<Out<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("JavaInv<Out<Base>>")!>createJavaInv(
<!DEBUG_INFO_EXPRESSION_TYPE("(Derived..Derived?)")!>JavaCls.makeFlexible(arg)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("In<In<Base>>")!>id<In<In<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<In<(Derived..Derived?)>>")!>createInIn(
<!DEBUG_INFO_EXPRESSION_TYPE("(Derived..Derived?)")!>JavaCls.makeFlexible(arg)<!>
)<!>
)<!>
}
interface Base
class Derived : Base
class Inv<T>
class Out<out O>
class In<in I>
fun <K> id(arg: K) = arg
fun <T> createInv(arg: T): Inv<T> = TODO()
fun <T> createOut(arg: T): Out<T> = TODO()
fun <T> createIn(arg: T): In<T> = TODO()
fun <T> createInIn(arg: T): In<In<T>> = TODO()
fun <T> createJavaInv(arg: T): JavaInv<Out<T>> = TODO()
// FILE: JavaCls.java
public class JavaCls {
public static <T> T makeFlexible(T argument) {
return argument;
}
}
// FILE: JavaInv.java
public class JavaInv <T> {
}
@@ -0,0 +1,60 @@
package
public fun </*0*/ T> createIn(/*0*/ arg: T): In<T>
public fun </*0*/ T> createInIn(/*0*/ arg: T): In<In<T>>
public fun </*0*/ T> createInv(/*0*/ arg: T): Inv<T>
public fun </*0*/ T> createJavaInv(/*0*/ arg: T): JavaInv<Out<T>>
public fun </*0*/ T> createOut(/*0*/ arg: T): Out<T>
public fun </*0*/ K> id(/*0*/ arg: K): K
public fun test(/*0*/ arg: Derived): kotlin.Unit
public interface Base {
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
}
public final class Derived : Base {
public constructor Derived()
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
}
public final class In</*0*/ in I> {
public constructor In</*0*/ in I>()
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
}
public final class Inv</*0*/ T> {
public constructor Inv</*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
}
public open class JavaCls {
public constructor JavaCls()
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
// Static members
public open fun </*0*/ T : kotlin.Any!> makeFlexible(/*0*/ argument: T!): T!
}
public open class JavaInv</*0*/ T : kotlin.Any!> {
public constructor JavaInv</*0*/ T : kotlin.Any!>()
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
}
public final class Out</*0*/ out O> {
public constructor Out</*0*/ out O>()
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
}
@@ -0,0 +1,42 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun test(a: D1, b: D2) {
id<Out<Base>>(
makeOut(
select(a, b)
)
)
id<Inv<Base>>(
makeInv(
select(a, b)
)
)
id<In<Base>>(
makeIn(
select(a, b)
)
)
id<In<In<Base>>>(
makeInIn(
select(a, b)
)
)
}
interface Base
interface B1 : Base
interface B2 : Base
interface D1 : B1, B2
interface D2 : B1, B2
fun <S> select(a: S, b: S): S = TODO()
class Inv<T>
class Out<out O>
class In<in I>
fun <K> id(arg: K) = arg
fun <T> makeInv(arg: T): Inv<T> = TODO()
fun <T> makeOut(arg: T): Out<T> = TODO()
fun <T> makeIn(arg: T): In<T> = TODO()
fun <T> makeInIn(arg: T): In<In<T>> = TODO()
@@ -0,0 +1,42 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun test(a: D1, b: D2) {
<!DEBUG_INFO_EXPRESSION_TYPE("Out<Base>")!>id<Out<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Out<{B1 & B2}>")!>makeOut(
<!DEBUG_INFO_EXPRESSION_TYPE("{B1 & B2}")!>select(a, b)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Base>")!>id<Inv<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Base>")!>makeInv(
<!DEBUG_INFO_EXPRESSION_TYPE("{B1 & B2}")!>select(a, b)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("In<Base>")!>id<In<Base>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<Base>")!>makeIn(
<!DEBUG_INFO_EXPRESSION_TYPE("{B1 & B2}")!>select(a, b)<!>
)<!>
)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("In<In<Base>>")!>id<In<In<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<In<{B1 & B2}>>")!>makeInIn(
<!DEBUG_INFO_EXPRESSION_TYPE("{B1 & B2}")!>select(a, b)<!>
)<!>
)<!>
}
interface Base
interface B1 : Base
interface B2 : Base
interface D1 : B1, B2
interface D2 : B1, B2
fun <S> select(a: S, b: S): S = TODO()
class Inv<T>
class Out<out O>
class In<in I>
fun <K> id(arg: K) = arg
fun <T> makeInv(arg: T): Inv<T> = TODO()
fun <T> makeOut(arg: T): Out<T> = TODO()
fun <T> makeIn(arg: T): In<T> = TODO()
fun <T> makeInIn(arg: T): In<In<T>> = TODO()
@@ -0,0 +1,60 @@
package
public fun </*0*/ K> id(/*0*/ arg: K): K
public fun </*0*/ T> makeIn(/*0*/ arg: T): In<T>
public fun </*0*/ T> makeInIn(/*0*/ arg: T): In<In<T>>
public fun </*0*/ T> makeInv(/*0*/ arg: T): Inv<T>
public fun </*0*/ T> makeOut(/*0*/ arg: T): Out<T>
public fun </*0*/ S> select(/*0*/ a: S, /*1*/ b: S): S
public fun test(/*0*/ a: D1, /*1*/ b: D2): kotlin.Unit
public interface B1 : Base {
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
}
public interface B2 : Base {
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
}
public interface Base {
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
}
public interface D1 : B1, B2 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface D2 : B1, B2 {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class In</*0*/ in I> {
public constructor In</*0*/ in I>()
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
}
public final class Inv</*0*/ T> {
public constructor Inv</*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
}
public final class Out</*0*/ out O> {
public constructor Out</*0*/ out O>()
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
}
@@ -0,0 +1,13 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER -USELESS_CAST
class Inv<T>
class Out<out T>
fun <K> foo(y: K?) = Inv<Out<K>>()
fun <R> test(x: Inv<Out<R>>) {}
fun main() {
test<Int>(foo(null)) // type mismatch
test<Number>(foo(1 as Int)) // type mismatch
}
@@ -0,0 +1,13 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER -USELESS_CAST
class Inv<T>
class Out<out T>
fun <K> foo(y: K?) = Inv<Out<K>>()
fun <R> test(x: Inv<Out<R>>) {}
fun main() {
test<Int>(foo(null)) // type mismatch
test<Number>(foo(1 as Int)) // type mismatch
}
@@ -0,0 +1,19 @@
package
public fun </*0*/ K> foo(/*0*/ y: K?): Inv<Out<K>>
public fun main(): kotlin.Unit
public fun </*0*/ R> test(/*0*/ x: Inv<Out<R>>): kotlin.Unit
public final class Inv</*0*/ T> {
public constructor Inv</*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
}
public final class Out</*0*/ out T> {
public constructor Out</*0*/ out 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
}
@@ -0,0 +1,78 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
interface Base
class Derived : Base
class OtherDerived : Base
class Inv<T>
class Out<out O>
class In<in I>
class BiParam<out F, out S>
fun <K> id(arg: K) = arg
fun <D> createDoubleIn(arg: D): In<In<D>> = TODO()
fun <D> createDoubleInOut1(arg: D): In<In<Out<D>>> = TODO()
fun <D> createDoubleInOut2(arg: D): In<Out<In<D>>> = TODO()
fun <D> createDoubleInOut3(arg: D): Out<In<In<D>>> = TODO()
fun <D> createInOut(arg: D): In<Out<D>> = TODO()
fun <D> createOutIn(arg: D): Out<In<D>> = TODO()
fun <D> createInvOut(arg: D): Inv<Out<D>> = TODO()
fun <D> createOutInvDoubleIn(arg: D): Out<Inv<In<In<D>>>> = TODO()
fun <F, S> biparamEarly(first: F, second: S): BiParam<In<In<F>>, Out<S>> = TODO()
fun <F, S> biparamEarlyIrrelevantInv(first: F, second: S): BiParam<In<In<F>>, Inv<String>> = TODO()
fun <F, S> biparamEarlyStarProjection(first: F, second: S): BiParam<*, In<In<S>>> = TODO()
fun <F, S> biparamLateIn(first: F, second: S): BiParam<In<Out<F>>, S> = TODO()
fun <F, S> biparamLateInv(first: F, second: S): BiParam<Inv<Out<F>>, S> = TODO()
fun <T> take(biParam: BiParam<*, In<In<T>>>) {}
fun testEarlyCompletion(derived: Derived, otherDerived: OtherDerived) {
id<In<In<Base>>>(
createDoubleIn(derived)
)
id<In<In<Out<Base>>>>(
createDoubleInOut1(derived)
)
id<In<Out<In<Base>>>>(
createDoubleInOut2(derived)
)
id<Out<In<In<Base>>>>(
createDoubleInOut3(derived)
)
id<BiParam<In<In<Base>>, Out<Base>>>(
biparamEarly(derived, otherDerived)
)
id<BiParam<In<In<Base>>, Inv<String>>>(
biparamEarlyIrrelevantInv(derived, otherDerived)
)
take<Base>(
biparamEarlyStarProjection(derived, otherDerived)
)
}
fun testLateCompletion(derived: Derived, otherDerived: OtherDerived) {
id<In<Out<Base>>>(
createInOut(derived)
)
id<Out<In<Base>>>(
createOutIn(derived)
)
id<Inv<Out<Base>>>(
createInvOut(derived)
)
id<Out<Inv<In<In<Base>>>>>(
createOutInvDoubleIn(derived)
)
id<BiParam<In<Out<Base>>, OtherDerived>>(
biparamLateIn(derived, otherDerived)
)
id<BiParam<Inv<Out<Base>>, OtherDerived>>(
biparamLateInv(derived, otherDerived)
)
}
@@ -0,0 +1,78 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
interface Base
class Derived : Base
class OtherDerived : Base
class Inv<T>
class Out<out O>
class In<in I>
class BiParam<out F, out S>
fun <K> id(arg: K) = arg
fun <D> createDoubleIn(arg: D): In<In<D>> = TODO()
fun <D> createDoubleInOut1(arg: D): In<In<Out<D>>> = TODO()
fun <D> createDoubleInOut2(arg: D): In<Out<In<D>>> = TODO()
fun <D> createDoubleInOut3(arg: D): Out<In<In<D>>> = TODO()
fun <D> createInOut(arg: D): In<Out<D>> = TODO()
fun <D> createOutIn(arg: D): Out<In<D>> = TODO()
fun <D> createInvOut(arg: D): Inv<Out<D>> = TODO()
fun <D> createOutInvDoubleIn(arg: D): Out<Inv<In<In<D>>>> = TODO()
fun <F, S> biparamEarly(first: F, second: S): BiParam<In<In<F>>, Out<S>> = TODO()
fun <F, S> biparamEarlyIrrelevantInv(first: F, second: S): BiParam<In<In<F>>, Inv<String>> = TODO()
fun <F, S> biparamEarlyStarProjection(first: F, second: S): BiParam<*, In<In<S>>> = TODO()
fun <F, S> biparamLateIn(first: F, second: S): BiParam<In<Out<F>>, S> = TODO()
fun <F, S> biparamLateInv(first: F, second: S): BiParam<Inv<Out<F>>, S> = TODO()
fun <T> take(biParam: BiParam<*, In<In<T>>>) {}
fun testEarlyCompletion(derived: Derived, otherDerived: OtherDerived) {
id<In<In<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<In<Derived>>")!>createDoubleIn(derived)<!>
)
id<In<In<Out<Base>>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<In<Out<Derived>>>")!>createDoubleInOut1(derived)<!>
)
id<In<Out<In<Base>>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<Out<In<Derived>>>")!>createDoubleInOut2(derived)<!>
)
id<Out<In<In<Base>>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Out<In<In<Derived>>>")!>createDoubleInOut3(derived)<!>
)
id<BiParam<In<In<Base>>, Out<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("BiParam<In<In<Derived>>, Out<OtherDerived>>")!>biparamEarly(derived, otherDerived)<!>
)
id<BiParam<In<In<Base>>, Inv<String>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("BiParam<In<In<Derived>>, Inv<kotlin.String>>")!>biparamEarlyIrrelevantInv(derived, otherDerived)<!>
)
take<Base>(
<!DEBUG_INFO_EXPRESSION_TYPE("BiParam<*, In<In<OtherDerived>>>")!>biparamEarlyStarProjection(derived, otherDerived)<!>
)
}
fun testLateCompletion(derived: Derived, otherDerived: OtherDerived) {
id<In<Out<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("In<Out<Base>>")!>createInOut(derived)<!>
)
id<Out<In<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Out<In<Base>>")!>createOutIn(derived)<!>
)
id<Inv<Out<Base>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Out<Base>>")!>createInvOut(derived)<!>
)
id<Out<Inv<In<In<Base>>>>>(
<!DEBUG_INFO_EXPRESSION_TYPE("Out<Inv<In<In<Base>>>>")!>createOutInvDoubleIn(derived)<!>
)
id<BiParam<In<Out<Base>>, OtherDerived>>(
<!DEBUG_INFO_EXPRESSION_TYPE("BiParam<In<Out<Base>>, OtherDerived>")!>biparamLateIn(derived, otherDerived)<!>
)
id<BiParam<Inv<Out<Base>>, OtherDerived>>(
<!DEBUG_INFO_EXPRESSION_TYPE("BiParam<Inv<Out<Base>>, OtherDerived>")!>biparamLateInv(derived, otherDerived)<!>
)
}
@@ -0,0 +1,67 @@
package
public fun </*0*/ F, /*1*/ S> biparamEarly(/*0*/ first: F, /*1*/ second: S): BiParam<In<In<F>>, Out<S>>
public fun </*0*/ F, /*1*/ S> biparamEarlyIrrelevantInv(/*0*/ first: F, /*1*/ second: S): BiParam<In<In<F>>, Inv<kotlin.String>>
public fun </*0*/ F, /*1*/ S> biparamEarlyStarProjection(/*0*/ first: F, /*1*/ second: S): BiParam<*, In<In<S>>>
public fun </*0*/ F, /*1*/ S> biparamLateIn(/*0*/ first: F, /*1*/ second: S): BiParam<In<Out<F>>, S>
public fun </*0*/ F, /*1*/ S> biparamLateInv(/*0*/ first: F, /*1*/ second: S): BiParam<Inv<Out<F>>, S>
public fun </*0*/ D> createDoubleIn(/*0*/ arg: D): In<In<D>>
public fun </*0*/ D> createDoubleInOut1(/*0*/ arg: D): In<In<Out<D>>>
public fun </*0*/ D> createDoubleInOut2(/*0*/ arg: D): In<Out<In<D>>>
public fun </*0*/ D> createDoubleInOut3(/*0*/ arg: D): Out<In<In<D>>>
public fun </*0*/ D> createInOut(/*0*/ arg: D): In<Out<D>>
public fun </*0*/ D> createInvOut(/*0*/ arg: D): Inv<Out<D>>
public fun </*0*/ D> createOutIn(/*0*/ arg: D): Out<In<D>>
public fun </*0*/ D> createOutInvDoubleIn(/*0*/ arg: D): Out<Inv<In<In<D>>>>
public fun </*0*/ K> id(/*0*/ arg: K): K
public fun </*0*/ T> take(/*0*/ biParam: BiParam<*, In<In<T>>>): kotlin.Unit
public fun testEarlyCompletion(/*0*/ derived: Derived, /*1*/ otherDerived: OtherDerived): kotlin.Unit
public fun testLateCompletion(/*0*/ derived: Derived, /*1*/ otherDerived: OtherDerived): kotlin.Unit
public interface Base {
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
}
public final class BiParam</*0*/ out F, /*1*/ out S> {
public constructor BiParam</*0*/ out F, /*1*/ out S>()
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
}
public final class Derived : Base {
public constructor Derived()
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
}
public final class In</*0*/ in I> {
public constructor In</*0*/ in I>()
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
}
public final class Inv</*0*/ T> {
public constructor Inv</*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
}
public final class OtherDerived : Base {
public constructor OtherDerived()
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
}
public final class Out</*0*/ out O> {
public constructor Out</*0*/ out O>()
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
}
@@ -0,0 +1,13 @@
// !LANGUAGE: +NewInference
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE
class Inv<T>
class Out<out T>
fun <K> invOut(y: K?): Inv<Out<K>> = TODO()
fun <R> test(x: Inv<Out<R>>): R = TODO()
fun testNothing() {
test(invOut(null)) checkType { <!UNRESOLVED_REFERENCE!>_<!><Nothing>() }
}
@@ -0,0 +1,13 @@
// !LANGUAGE: +NewInference
// !CHECK_TYPE
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE
class Inv<T>
class Out<out T>
fun <K> invOut(y: K?): Inv<Out<K>> = TODO()
fun <R> test(x: Inv<Out<R>>): R = TODO()
fun testNothing() {
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>test<!>(invOut(null)) checkType { _<Nothing>() }
}
@@ -0,0 +1,19 @@
package
public fun </*0*/ K> invOut(/*0*/ y: K?): Inv<Out<K>>
public fun </*0*/ R> test(/*0*/ x: Inv<Out<R>>): R
public fun testNothing(): kotlin.Unit
public final class Inv</*0*/ T> {
public constructor Inv</*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
}
public final class Out</*0*/ out T> {
public constructor Out</*0*/ out 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
}
@@ -10609,21 +10609,51 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/inference/completion/basic.kt");
}
@TestMetadata("definetlyNotNullType.kt")
public void testDefinetlyNotNullType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.kt");
}
@TestMetadata("equalityConstraintUpstairs.kt")
public void testEqualityConstraintUpstairs() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/equalityConstraintUpstairs.kt");
}
@TestMetadata("flexibleType.kt")
public void testFlexibleType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/flexibleType.kt");
}
@TestMetadata("intersectionType.kt")
public void testIntersectionType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/intersectionType.kt");
}
@TestMetadata("kt33166.kt")
public void testKt33166() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/kt33166.kt");
}
@TestMetadata("kt36233.kt")
public void testKt36233() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/kt36233.kt");
}
@TestMetadata("lambdaWithVariableAndNothing.kt")
public void testLambdaWithVariableAndNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/lambdaWithVariableAndNothing.kt");
}
@TestMetadata("nestedVariance.kt")
public void testNestedVariance() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/nestedVariance.kt");
}
@TestMetadata("nothingFromNestedCall.kt")
public void testNothingFromNestedCall() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.kt");
}
@TestMetadata("partialForIlt.kt")
public void testPartialForIlt() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/partialForIlt.kt");
@@ -10604,21 +10604,51 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/inference/completion/basic.kt");
}
@TestMetadata("definetlyNotNullType.kt")
public void testDefinetlyNotNullType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.kt");
}
@TestMetadata("equalityConstraintUpstairs.kt")
public void testEqualityConstraintUpstairs() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/equalityConstraintUpstairs.kt");
}
@TestMetadata("flexibleType.kt")
public void testFlexibleType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/flexibleType.kt");
}
@TestMetadata("intersectionType.kt")
public void testIntersectionType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/intersectionType.kt");
}
@TestMetadata("kt33166.kt")
public void testKt33166() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/kt33166.kt");
}
@TestMetadata("kt36233.kt")
public void testKt36233() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/kt36233.kt");
}
@TestMetadata("lambdaWithVariableAndNothing.kt")
public void testLambdaWithVariableAndNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/lambdaWithVariableAndNothing.kt");
}
@TestMetadata("nestedVariance.kt")
public void testNestedVariance() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/nestedVariance.kt");
}
@TestMetadata("nothingFromNestedCall.kt")
public void testNothingFromNestedCall() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.kt");
}
@TestMetadata("partialForIlt.kt")
public void testPartialForIlt() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/completion/partialForIlt.kt");