FIR: fix capturing on intersection types #KT-48109 Fixed

This commit is contained in:
Mikhail Glukhikh
2021-08-05 14:05:24 +03:00
parent a04913a197
commit a21d281c19
9 changed files with 99 additions and 26 deletions

View File

@@ -0,0 +1,19 @@
FILE: use.kt
public final class BeforeRunTask<T> : R|kotlin/Any| {
public constructor<T>(): R|BeforeRunTask<T>| {
super<R|kotlin/Any|>()
}
}
public abstract interface PersistentStateComponent<T> : R|kotlin/Any| {
}
public final fun <T> deserializeAndLoadState(component: R|PersistentStateComponent<T>|, clazz: R|java/lang/Class<T>| = Q|ComponentSerializationUtil|.R|/ComponentSerializationUtil.getStateClass|<R|ft<T!!, T?>|>(<getClass>(R|<local>/component|).R|kotlin/jvm/java|<R|CapturedType(out PersistentStateComponent<T>)|>)): R|kotlin/Unit| {
}
public final fun use(beforeRunTask: R|BeforeRunTask<*>|): R|kotlin/Unit| {
when () {
(R|<local>/beforeRunTask| is R|PersistentStateComponent<*>|) -> {
R|/deserializeAndLoadState|<R|CapturedType(*)|>(R|<local>/beforeRunTask|)
}
}
}

View File

@@ -0,0 +1,27 @@
// FILE: ComponentSerializationUtil.java
import org.jetbrains.annotations.NotNull;
public final class ComponentSerializationUtil {
@NotNull
public static <S> Class<S> getStateClass(@NotNull Class<? extends PersistentStateComponent> aClass)
{}
}
// FILE: use.kt
class BeforeRunTask<T>
interface PersistentStateComponent<T>
fun <T> deserializeAndLoadState(
component: PersistentStateComponent<T>,
clazz: Class<T> = ComponentSerializationUtil.getStateClass(component::class.java)
) {}
fun use(beforeRunTask: BeforeRunTask<*>) {
if (beforeRunTask is PersistentStateComponent<*>) {
deserializeAndLoadState(beforeRunTask)
}
}

View File

@@ -5051,6 +5051,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/IntersectionWithJavaString.kt");
}
@Test
@TestMetadata("PersistentStateComponent.kt")
public void testPersistentStateComponent() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/PersistentStateComponent.kt");
}
@Test
@TestMetadata("UastPatterns.kt")
public void testUastPatterns() throws Exception {

View File

@@ -5051,6 +5051,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/IntersectionWithJavaString.kt");
}
@Test
@TestMetadata("PersistentStateComponent.kt")
public void testPersistentStateComponent() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/PersistentStateComponent.kt");
}
@Test
@TestMetadata("UastPatterns.kt")
public void testUastPatterns() throws Exception {

View File

@@ -318,6 +318,15 @@ private fun Candidate.captureTypeFromExpressionOrNull(argumentType: ConeKotlinTy
return captureTypeFromExpressionOrNull(argumentType.lowerBound, context)
}
if (argumentType is ConeIntersectionType) {
val intersectedTypes = argumentType.intersectedTypes.map { captureTypeFromExpressionOrNull(it, context) ?: it }
if (intersectedTypes == argumentType.intersectedTypes) return null
return ConeIntersectionType(
intersectedTypes,
argumentType.alternativeType?.let { captureTypeFromExpressionOrNull(it, context) ?: it }
)
}
if (argumentType !is ConeClassLikeType) return null
argumentType.fullyExpandedType(context.session).let {

View File

@@ -20,7 +20,7 @@ fun <X> InvBase<X>.myLastInv(): X = TODO()
fun <T> fooInv(x: InvBase<T>) {
if (x is InvDerived<*>) {
val l: T = <!INITIALIZER_TYPE_MISMATCH!>x.<!INAPPLICABLE_CANDIDATE!>myLastInv<!>()<!> // required T, found Cap(*). Only in NI
val l: T = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>x.myLastInv()<!> // required T, found Cap(*). Only in NI
}
}
@@ -36,7 +36,7 @@ fun Number.num() {}
fun main(b: Base<out Number>) {
b.foo().num()
if (b is Derived<*>) {
b.<!INAPPLICABLE_CANDIDATE!>foo<!>().<!INAPPLICABLE_CANDIDATE!>num<!>()
b.<!INAPPLICABLE_CANDIDATE!>baz<!>().length
b.foo().<!INAPPLICABLE_CANDIDATE!>num<!>()
b.baz().length
}
}

View File

@@ -52,32 +52,32 @@ fun case_3(a: Int?, b: Float?, c: Double?, d: Boolean?) {
false -> b
null -> c
}.apply {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>?")!>this<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>?")!>this<!>
if (this != null) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.propAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.propNullableT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.propNullableAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.funT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.funAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.funNullableT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>this<!>.funNullableAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propNullableT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.propNullableAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funNullableT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>this<!>.funNullableAny()
}
}.let {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>?")!>it<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>?")!>it<!>
if (it != null) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.propAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.propNullableT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.propNullableAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.funT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.funAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.funNullableT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<*>? & kotlin.Number & kotlin.Comparable<*>")!>it<!>.funNullableAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propNullableT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.propNullableAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funNullableT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number? & kotlin.Comparable<kotlin.Nothing>? & kotlin.Number & kotlin.Comparable<kotlin.Nothing>")!>it<!>.funNullableAny()
}
}
}

View File

@@ -45,7 +45,7 @@ fun case_4(x: ClassWithSixTypeParameters<*, *, *, *, *, *>?) {
x.y
x.z
x.u
<!DEBUG_INFO_EXPRESSION_TYPE("InterfaceWithTwoTypeParameters<*, *> & ClassWithSixTypeParameters<*, *, *, *, *, *>")!>x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!><!>.ip2test()
<!DEBUG_INFO_EXPRESSION_TYPE("InterfaceWithTwoTypeParameters<*, *> & ClassWithSixTypeParameters<*, kotlin.Nothing, *, *, kotlin.Nothing, *>")!>x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!><!>.ip2test()
<!DEBUG_INFO_EXPRESSION_TYPE("ClassWithSixTypeParameters<*, *, *, *, *, *>? & InterfaceWithTwoTypeParameters<*, *> & ClassWithSixTypeParameters<*, *, *, *, *, *>")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("ClassWithSixTypeParameters<*, *, *, *, *, *>? & InterfaceWithTwoTypeParameters<*, *> & ClassWithSixTypeParameters<*, *, *, *, *, *>")!>x<!>.x
}

View File

@@ -5051,6 +5051,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/IntersectionWithJavaString.kt");
}
@Test
@TestMetadata("PersistentStateComponent.kt")
public void testPersistentStateComponent() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/PersistentStateComponent.kt");
}
@Test
@TestMetadata("UastPatterns.kt")
public void testUastPatterns() throws Exception {