[NI] Eliminate special intersection type from result type
This commit is contained in:
+16
-2
@@ -25,10 +25,14 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstituto
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
|
import org.jetbrains.kotlin.types.IntersectionTypeConstructor
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class NewConstraintSystemImpl(
|
class NewConstraintSystemImpl(
|
||||||
private val constraintInjector: ConstraintInjector,
|
private val constraintInjector: ConstraintInjector,
|
||||||
@@ -201,7 +205,8 @@ class NewConstraintSystemImpl(
|
|||||||
override fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType) {
|
override fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType) {
|
||||||
checkState(State.BUILDING, State.COMPLETION)
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
|
|
||||||
constraintInjector.addInitialEqualityConstraint(this, variable.defaultType, resultType, FixVariableConstraintPosition(variable))
|
val actualResultType = eliminateSpecialIntersectionType(resultType) ?: resultType
|
||||||
|
constraintInjector.addInitialEqualityConstraint(this, variable.defaultType, actualResultType, FixVariableConstraintPosition(variable))
|
||||||
notFixedTypeVariables.remove(variable.freshTypeConstructor)
|
notFixedTypeVariables.remove(variable.freshTypeConstructor)
|
||||||
|
|
||||||
for (variableWithConstraint in notFixedTypeVariables.values) {
|
for (variableWithConstraint in notFixedTypeVariables.values) {
|
||||||
@@ -210,7 +215,16 @@ class NewConstraintSystemImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
storage.fixedTypeVariables[variable.freshTypeConstructor] = resultType
|
storage.fixedTypeVariables[variable.freshTypeConstructor] = actualResultType
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun eliminateSpecialIntersectionType(type: UnwrappedType): UnwrappedType? {
|
||||||
|
val constructor = type.constructor.safeAs<IntersectionTypeConstructor>() ?: return null
|
||||||
|
|
||||||
|
if (constructor.supertypes.size != 2) return null
|
||||||
|
val actualType = constructor.supertypes.singleOrNull { it != type.builtIns.anyType }
|
||||||
|
|
||||||
|
return actualType?.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
// KotlinConstraintSystemCompleter.Context, PostponedArgumentsAnalyzer.Context
|
// KotlinConstraintSystemCompleter.Context, PostponedArgumentsAnalyzer.Context
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// IGNORE_BACKEND: JS, NATIVE
|
||||||
|
|
||||||
|
// FILE: First.java
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class First {
|
||||||
|
public static <A> List<A> from(List<A> var0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: second.kt
|
||||||
|
|
||||||
|
fun <T> List<T>.listFromJava() = First.from(this)
|
||||||
|
fun <T> List<T>.listFromKotlin() = fromKotlin(this)
|
||||||
|
|
||||||
|
fun <T> fromKotlin(var0: List<T?>): List<T?> = var0
|
||||||
|
|
||||||
|
fun test(a: List<Int>) {
|
||||||
|
val b: List<Int>? = a.listFromJava()
|
||||||
|
val c: List<Int?> = a.listFromKotlin()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
test(listOf(1))
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// IGNORE_BACKEND: JS, NATIVE
|
||||||
|
|
||||||
|
// FILE: First.java
|
||||||
|
|
||||||
|
public class First<T> {
|
||||||
|
public static <K> First<K> first(K key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: second.kt
|
||||||
|
|
||||||
|
class Inv<T>(val key: T)
|
||||||
|
|
||||||
|
fun <T, R> lastLambda(x: T, block: (T) -> R): R = block(x)
|
||||||
|
|
||||||
|
fun <S> myTest(m: Inv<S>) {
|
||||||
|
lastLambda(m) { First.first(it.key) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+12
@@ -16580,6 +16580,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("approximateIntersectionType.kt")
|
||||||
|
public void testApproximateIntersectionType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/approximateIntersectionType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("arrayLengthNPE.kt")
|
@TestMetadata("arrayLengthNPE.kt")
|
||||||
public void testArrayLengthNPE() throws Exception {
|
public void testArrayLengthNPE() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
||||||
@@ -16652,6 +16658,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("intersectionAsLastLambda.kt")
|
||||||
|
public void testIntersectionAsLastLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionAsLastLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("intersectionOfEqualTypes.kt")
|
@TestMetadata("intersectionOfEqualTypes.kt")
|
||||||
public void testIntersectionOfEqualTypes() throws Exception {
|
public void testIntersectionOfEqualTypes() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
||||||
|
|||||||
@@ -16580,6 +16580,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("approximateIntersectionType.kt")
|
||||||
|
public void testApproximateIntersectionType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/approximateIntersectionType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("arrayLengthNPE.kt")
|
@TestMetadata("arrayLengthNPE.kt")
|
||||||
public void testArrayLengthNPE() throws Exception {
|
public void testArrayLengthNPE() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
||||||
@@ -16652,6 +16658,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("intersectionAsLastLambda.kt")
|
||||||
|
public void testIntersectionAsLastLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionAsLastLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("intersectionOfEqualTypes.kt")
|
@TestMetadata("intersectionOfEqualTypes.kt")
|
||||||
public void testIntersectionOfEqualTypes() throws Exception {
|
public void testIntersectionOfEqualTypes() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
||||||
|
|||||||
@@ -16580,6 +16580,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("approximateIntersectionType.kt")
|
||||||
|
public void testApproximateIntersectionType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/approximateIntersectionType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("arrayLengthNPE.kt")
|
@TestMetadata("arrayLengthNPE.kt")
|
||||||
public void testArrayLengthNPE() throws Exception {
|
public void testArrayLengthNPE() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
||||||
@@ -16652,6 +16658,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("intersectionAsLastLambda.kt")
|
||||||
|
public void testIntersectionAsLastLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionAsLastLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("intersectionOfEqualTypes.kt")
|
@TestMetadata("intersectionOfEqualTypes.kt")
|
||||||
public void testIntersectionOfEqualTypes() throws Exception {
|
public void testIntersectionOfEqualTypes() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
||||||
|
|||||||
+24
@@ -20222,6 +20222,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("approximateIntersectionType.kt")
|
||||||
|
public void testApproximateIntersectionType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/approximateIntersectionType.kt");
|
||||||
|
try {
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
catch (Throwable ignore) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("arrayLengthNPE.kt")
|
@TestMetadata("arrayLengthNPE.kt")
|
||||||
public void testArrayLengthNPE() throws Exception {
|
public void testArrayLengthNPE() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/arrayLengthNPE.kt");
|
||||||
@@ -20306,6 +20318,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("intersectionAsLastLambda.kt")
|
||||||
|
public void testIntersectionAsLastLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionAsLastLambda.kt");
|
||||||
|
try {
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
catch (Throwable ignore) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("intersectionOfEqualTypes.kt")
|
@TestMetadata("intersectionOfEqualTypes.kt")
|
||||||
public void testIntersectionOfEqualTypes() throws Exception {
|
public void testIntersectionOfEqualTypes() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/intersectionOfEqualTypes.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user