diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index ea5c05149c7..38a724a200c 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -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"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CompletionModeCalculator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CompletionModeCalculator.kt index 5d1f16609bb..f2fc75067e8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CompletionModeCalculator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CompletionModeCalculator.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() + 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 + ) { + 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 { - 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() + 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 + ) { + 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( diff --git a/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.fir.kt new file mode 100644 index 00000000000..7b7d0461d29 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.fir.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun test(derived: T) { + id>( + makeOut( + makeDnn(derived) + ) + ) + id>( + makeIn( + makeDnn(derived) + ) + ) + id>( + makeInv( + makeDnn(derived) + ) + ) + id>>( + makeInIn( + makeDnn(derived) + ) + ) +} + +interface Base +open class Derived : Base + +class Inv +class Out +class In + +fun id(arg: K) = arg +fun makeDnn(arg: T?): T = TODO() +fun makeInv(arg: T): Inv = TODO() +fun makeOut(arg: T): Out = TODO() +fun makeIn(arg: T): In = TODO() +fun makeInIn(arg: T): In> = TODO() diff --git a/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.kt b/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.kt new file mode 100644 index 00000000000..589fcb9da92 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun test(derived: T) { + ")!>id>( + makeOut( + makeDnn(derived) + ) + ) + ")!>id>( + ")!>makeIn( + makeDnn(derived) + ) + ) + ")!>id>( + ")!>makeInv( + makeDnn(derived) + ) + ) + >")!>id>>( + makeInIn( + makeDnn(derived) + ) + ) +} + +interface Base +open class Derived : Base + +class Inv +class Out +class In + +fun id(arg: K) = arg +fun makeDnn(arg: T?): T = TODO() +fun makeInv(arg: T): Inv = TODO() +fun makeOut(arg: T): Out = TODO() +fun makeIn(arg: T): In = TODO() +fun makeInIn(arg: T): In> = TODO() diff --git a/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.txt b/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.txt new file mode 100644 index 00000000000..bbf7ae9ea43 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/definetlyNotNullType.txt @@ -0,0 +1,43 @@ +package + +public fun id(/*0*/ arg: K): K +public fun makeDnn(/*0*/ arg: T?): T +public fun makeIn(/*0*/ arg: T): In +public fun makeInIn(/*0*/ arg: T): In> +public fun makeInv(/*0*/ arg: T): Inv +public fun makeOut(/*0*/ arg: T): Out +public fun 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 { + public constructor In() + 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 { + public constructor Inv() + 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 { + public constructor Out() + 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/testData/diagnostics/tests/inference/completion/flexibleType.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/flexibleType.fir.kt new file mode 100644 index 00000000000..868db4ac7ea --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/flexibleType.fir.kt @@ -0,0 +1,60 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// FILE: Test.kt + +fun test(arg: Derived) { + id>( + createOut( + JavaCls.makeFlexible(arg) + ) + ) + id>( + createIn( + JavaCls.makeFlexible(arg) + ) + ) + id>( + createInv( + JavaCls.makeFlexible(arg) + ) + ) + id>>( + createJavaInv( + JavaCls.makeFlexible(arg) + ) + ) + id>>( + createInIn( + JavaCls.makeFlexible(arg) + ) + ) +} + +interface Base +class Derived : Base + +class Inv +class Out +class In + +fun id(arg: K) = arg + +fun createInv(arg: T): Inv = TODO() +fun createOut(arg: T): Out = TODO() +fun createIn(arg: T): In = TODO() +fun createInIn(arg: T): In> = TODO() +fun createJavaInv(arg: T): JavaInv> = TODO() + +// FILE: JavaCls.java + +public class JavaCls { + public static T makeFlexible(T argument) { + return argument; + } +} + +// FILE: JavaInv.java + +public class JavaInv { +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/flexibleType.kt b/compiler/testData/diagnostics/tests/inference/completion/flexibleType.kt new file mode 100644 index 00000000000..42b595213d2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/flexibleType.kt @@ -0,0 +1,60 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// FILE: Test.kt + +fun test(arg: Derived) { + ")!>id>( + ")!>createOut( + JavaCls.makeFlexible(arg) + ) + ) + ")!>id>( + ")!>createIn( + JavaCls.makeFlexible(arg) + ) + ) + ")!>id>( + ")!>createInv( + JavaCls.makeFlexible(arg) + ) + ) + >")!>id>>( + >")!>createJavaInv( + JavaCls.makeFlexible(arg) + ) + ) + >")!>id>>( + >")!>createInIn( + JavaCls.makeFlexible(arg) + ) + ) +} + +interface Base +class Derived : Base + +class Inv +class Out +class In + +fun id(arg: K) = arg + +fun createInv(arg: T): Inv = TODO() +fun createOut(arg: T): Out = TODO() +fun createIn(arg: T): In = TODO() +fun createInIn(arg: T): In> = TODO() +fun createJavaInv(arg: T): JavaInv> = TODO() + +// FILE: JavaCls.java + +public class JavaCls { + public static T makeFlexible(T argument) { + return argument; + } +} + +// FILE: JavaInv.java + +public class JavaInv { +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/flexibleType.txt b/compiler/testData/diagnostics/tests/inference/completion/flexibleType.txt new file mode 100644 index 00000000000..e71cf655402 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/flexibleType.txt @@ -0,0 +1,60 @@ +package + +public fun createIn(/*0*/ arg: T): In +public fun createInIn(/*0*/ arg: T): In> +public fun createInv(/*0*/ arg: T): Inv +public fun createJavaInv(/*0*/ arg: T): JavaInv> +public fun createOut(/*0*/ arg: T): Out +public fun 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 { + public constructor In() + 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 { + public constructor Inv() + 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 makeFlexible(/*0*/ argument: T!): T! +} + +public open class JavaInv { + public constructor JavaInv() + 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 { + public constructor Out() + 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/testData/diagnostics/tests/inference/completion/intersectionType.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/intersectionType.fir.kt new file mode 100644 index 00000000000..b3d3927f06d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/intersectionType.fir.kt @@ -0,0 +1,42 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun test(a: D1, b: D2) { + id>( + makeOut( + select(a, b) + ) + ) + id>( + makeInv( + select(a, b) + ) + ) + id>( + makeIn( + select(a, b) + ) + ) + id>>( + makeInIn( + select(a, b) + ) + ) +} + +interface Base +interface B1 : Base +interface B2 : Base +interface D1 : B1, B2 +interface D2 : B1, B2 + +fun select(a: S, b: S): S = TODO() +class Inv +class Out +class In + +fun id(arg: K) = arg +fun makeInv(arg: T): Inv = TODO() +fun makeOut(arg: T): Out = TODO() +fun makeIn(arg: T): In = TODO() +fun makeInIn(arg: T): In> = TODO() diff --git a/compiler/testData/diagnostics/tests/inference/completion/intersectionType.kt b/compiler/testData/diagnostics/tests/inference/completion/intersectionType.kt new file mode 100644 index 00000000000..9c570ab1f93 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/intersectionType.kt @@ -0,0 +1,42 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun test(a: D1, b: D2) { + ")!>id>( + ")!>makeOut( + select(a, b) + ) + ) + ")!>id>( + ")!>makeInv( + select(a, b) + ) + ) + ")!>id>( + ")!>makeIn( + select(a, b) + ) + ) + >")!>id>>( + >")!>makeInIn( + select(a, b) + ) + ) +} + +interface Base +interface B1 : Base +interface B2 : Base +interface D1 : B1, B2 +interface D2 : B1, B2 + +fun select(a: S, b: S): S = TODO() +class Inv +class Out +class In + +fun id(arg: K) = arg +fun makeInv(arg: T): Inv = TODO() +fun makeOut(arg: T): Out = TODO() +fun makeIn(arg: T): In = TODO() +fun makeInIn(arg: T): In> = TODO() diff --git a/compiler/testData/diagnostics/tests/inference/completion/intersectionType.txt b/compiler/testData/diagnostics/tests/inference/completion/intersectionType.txt new file mode 100644 index 00000000000..fd566881caf --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/intersectionType.txt @@ -0,0 +1,60 @@ +package + +public fun id(/*0*/ arg: K): K +public fun makeIn(/*0*/ arg: T): In +public fun makeInIn(/*0*/ arg: T): In> +public fun makeInv(/*0*/ arg: T): Inv +public fun makeOut(/*0*/ arg: T): Out +public fun 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 { + public constructor In() + 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 { + public constructor Inv() + 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 { + public constructor Out() + 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/testData/diagnostics/tests/inference/completion/kt36233.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/kt36233.fir.kt new file mode 100644 index 00000000000..a0c83c074d7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/kt36233.fir.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -USELESS_CAST + +class Inv +class Out + +fun foo(y: K?) = Inv>() +fun test(x: Inv>) {} + +fun main() { + test(foo(null)) // type mismatch + test(foo(1 as Int)) // type mismatch +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/kt36233.kt b/compiler/testData/diagnostics/tests/inference/completion/kt36233.kt new file mode 100644 index 00000000000..a0c83c074d7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/kt36233.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -USELESS_CAST + +class Inv +class Out + +fun foo(y: K?) = Inv>() +fun test(x: Inv>) {} + +fun main() { + test(foo(null)) // type mismatch + test(foo(1 as Int)) // type mismatch +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/kt36233.txt b/compiler/testData/diagnostics/tests/inference/completion/kt36233.txt new file mode 100644 index 00000000000..b403cd3e992 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/kt36233.txt @@ -0,0 +1,19 @@ +package + +public fun foo(/*0*/ y: K?): Inv> +public fun main(): kotlin.Unit +public fun test(/*0*/ x: Inv>): kotlin.Unit + +public final class Inv { + public constructor Inv() + 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 { + public constructor Out() + 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/testData/diagnostics/tests/inference/completion/nestedVariance.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.fir.kt new file mode 100644 index 00000000000..903f7319022 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.fir.kt @@ -0,0 +1,78 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +interface Base +class Derived : Base +class OtherDerived : Base + +class Inv +class Out +class In + +class BiParam + +fun id(arg: K) = arg + +fun createDoubleIn(arg: D): In> = TODO() +fun createDoubleInOut1(arg: D): In>> = TODO() +fun createDoubleInOut2(arg: D): In>> = TODO() +fun createDoubleInOut3(arg: D): Out>> = TODO() + +fun createInOut(arg: D): In> = TODO() +fun createOutIn(arg: D): Out> = TODO() +fun createInvOut(arg: D): Inv> = TODO() +fun createOutInvDoubleIn(arg: D): Out>>> = TODO() + +fun biparamEarly(first: F, second: S): BiParam>, Out> = TODO() +fun biparamEarlyIrrelevantInv(first: F, second: S): BiParam>, Inv> = TODO() +fun biparamEarlyStarProjection(first: F, second: S): BiParam<*, In>> = TODO() + +fun biparamLateIn(first: F, second: S): BiParam>, S> = TODO() +fun biparamLateInv(first: F, second: S): BiParam>, S> = TODO() + +fun take(biParam: BiParam<*, In>>) {} + +fun testEarlyCompletion(derived: Derived, otherDerived: OtherDerived) { + id>>( + createDoubleIn(derived) + ) + id>>>( + createDoubleInOut1(derived) + ) + id>>>( + createDoubleInOut2(derived) + ) + id>>>( + createDoubleInOut3(derived) + ) + id>, Out>>( + biparamEarly(derived, otherDerived) + ) + id>, Inv>>( + biparamEarlyIrrelevantInv(derived, otherDerived) + ) + take( + biparamEarlyStarProjection(derived, otherDerived) + ) +} + +fun testLateCompletion(derived: Derived, otherDerived: OtherDerived) { + id>>( + createInOut(derived) + ) + id>>( + createOutIn(derived) + ) + id>>( + createInvOut(derived) + ) + id>>>>( + createOutInvDoubleIn(derived) + ) + id>, OtherDerived>>( + biparamLateIn(derived, otherDerived) + ) + id>, OtherDerived>>( + biparamLateInv(derived, otherDerived) + ) +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.kt b/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.kt new file mode 100644 index 00000000000..3a65e39af07 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.kt @@ -0,0 +1,78 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +interface Base +class Derived : Base +class OtherDerived : Base + +class Inv +class Out +class In + +class BiParam + +fun id(arg: K) = arg + +fun createDoubleIn(arg: D): In> = TODO() +fun createDoubleInOut1(arg: D): In>> = TODO() +fun createDoubleInOut2(arg: D): In>> = TODO() +fun createDoubleInOut3(arg: D): Out>> = TODO() + +fun createInOut(arg: D): In> = TODO() +fun createOutIn(arg: D): Out> = TODO() +fun createInvOut(arg: D): Inv> = TODO() +fun createOutInvDoubleIn(arg: D): Out>>> = TODO() + +fun biparamEarly(first: F, second: S): BiParam>, Out> = TODO() +fun biparamEarlyIrrelevantInv(first: F, second: S): BiParam>, Inv> = TODO() +fun biparamEarlyStarProjection(first: F, second: S): BiParam<*, In>> = TODO() + +fun biparamLateIn(first: F, second: S): BiParam>, S> = TODO() +fun biparamLateInv(first: F, second: S): BiParam>, S> = TODO() + +fun take(biParam: BiParam<*, In>>) {} + +fun testEarlyCompletion(derived: Derived, otherDerived: OtherDerived) { + id>>( + >")!>createDoubleIn(derived) + ) + id>>>( + >>")!>createDoubleInOut1(derived) + ) + id>>>( + >>")!>createDoubleInOut2(derived) + ) + id>>>( + >>")!>createDoubleInOut3(derived) + ) + id>, Out>>( + >, Out>")!>biparamEarly(derived, otherDerived) + ) + id>, Inv>>( + >, Inv>")!>biparamEarlyIrrelevantInv(derived, otherDerived) + ) + take( + >>")!>biparamEarlyStarProjection(derived, otherDerived) + ) +} + +fun testLateCompletion(derived: Derived, otherDerived: OtherDerived) { + id>>( + >")!>createInOut(derived) + ) + id>>( + >")!>createOutIn(derived) + ) + id>>( + >")!>createInvOut(derived) + ) + id>>>>( + >>>")!>createOutInvDoubleIn(derived) + ) + id>, OtherDerived>>( + >, OtherDerived>")!>biparamLateIn(derived, otherDerived) + ) + id>, OtherDerived>>( + >, OtherDerived>")!>biparamLateInv(derived, otherDerived) + ) +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.txt b/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.txt new file mode 100644 index 00000000000..3b915f9c179 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/nestedVariance.txt @@ -0,0 +1,67 @@ +package + +public fun biparamEarly(/*0*/ first: F, /*1*/ second: S): BiParam>, Out> +public fun biparamEarlyIrrelevantInv(/*0*/ first: F, /*1*/ second: S): BiParam>, Inv> +public fun biparamEarlyStarProjection(/*0*/ first: F, /*1*/ second: S): BiParam<*, In>> +public fun biparamLateIn(/*0*/ first: F, /*1*/ second: S): BiParam>, S> +public fun biparamLateInv(/*0*/ first: F, /*1*/ second: S): BiParam>, S> +public fun createDoubleIn(/*0*/ arg: D): In> +public fun createDoubleInOut1(/*0*/ arg: D): In>> +public fun createDoubleInOut2(/*0*/ arg: D): In>> +public fun createDoubleInOut3(/*0*/ arg: D): Out>> +public fun createInOut(/*0*/ arg: D): In> +public fun createInvOut(/*0*/ arg: D): Inv> +public fun createOutIn(/*0*/ arg: D): Out> +public fun createOutInvDoubleIn(/*0*/ arg: D): Out>>> +public fun id(/*0*/ arg: K): K +public fun take(/*0*/ biParam: BiParam<*, In>>): 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 { + public constructor BiParam() + 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 { + public constructor In() + 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 { + public constructor Inv() + 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 { + public constructor Out() + 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/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.fir.kt new file mode 100644 index 00000000000..e97e31bbaf8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.fir.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +NewInference +// !CHECK_TYPE +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE + +class Inv +class Out + +fun invOut(y: K?): Inv> = TODO() +fun test(x: Inv>): R = TODO() + +fun testNothing() { + test(invOut(null)) checkType { _() } +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.kt b/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.kt new file mode 100644 index 00000000000..407707c2e8f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +NewInference +// !CHECK_TYPE +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE + +class Inv +class Out + +fun invOut(y: K?): Inv> = TODO() +fun test(x: Inv>): R = TODO() + +fun testNothing() { + test(invOut(null)) checkType { _() } +} diff --git a/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.txt b/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.txt new file mode 100644 index 00000000000..ac6f79ea30d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/completion/nothingFromNestedCall.txt @@ -0,0 +1,19 @@ +package + +public fun invOut(/*0*/ y: K?): Inv> +public fun test(/*0*/ x: Inv>): R +public fun testNothing(): kotlin.Unit + +public final class Inv { + public constructor Inv() + 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 { + public constructor Out() + 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/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 66a4f9f5ad0..d36b4ae7374 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 22764a5d6a7..05aebd0e52e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -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");