K2: Fix incorrect inference of delegated property type

It was working incorrectly, because we've been trying to fix
P1 variable to intersectTypes(String?, StubForP2) that should result
to String? because we've got stubEqualsToAnything enabled there,
but nullability was being chosen incorrectly because
`StubForP2.isNullableType()` returned false

NB: The code inside `is ConeTypeVariable` case wasn't working properly
because it always `lookupTag.toSymbol(session)` always returned null,
thus there was effectively five dead lines of code there.

^KT-57814 Fixed
^KT-57921 Related
This commit is contained in:
Denis.Zharkov
2023-04-06 18:54:33 +02:00
committed by Space Team
parent e079d9d405
commit 39639e08f9
8 changed files with 58 additions and 8 deletions
@@ -8829,6 +8829,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt"); runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt");
} }
@Test
@TestMetadata("decoratedLambda.kt")
public void testDecoratedLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/decoratedLambda.kt");
}
@Test @Test
@TestMetadata("delegateExpressionAsLambda.kt") @TestMetadata("delegateExpressionAsLambda.kt")
public void testDelegateExpressionAsLambda() throws Exception { public void testDelegateExpressionAsLambda() throws Exception {
@@ -8829,6 +8829,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt"); runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt");
} }
@Test
@TestMetadata("decoratedLambda.kt")
public void testDecoratedLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/decoratedLambda.kt");
}
@Test @Test
@TestMetadata("delegateExpressionAsLambda.kt") @TestMetadata("delegateExpressionAsLambda.kt")
public void testDelegateExpressionAsLambda() throws Exception { public void testDelegateExpressionAsLambda() throws Exception {
@@ -8829,6 +8829,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt"); runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt");
} }
@Test
@TestMetadata("decoratedLambda.kt")
public void testDecoratedLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/decoratedLambda.kt");
}
@Test @Test
@TestMetadata("delegateExpressionAsLambda.kt") @TestMetadata("delegateExpressionAsLambda.kt")
public void testDelegateExpressionAsLambda() throws Exception { public void testDelegateExpressionAsLambda() throws Exception {
@@ -8835,6 +8835,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt"); runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt");
} }
@Test
@TestMetadata("decoratedLambda.kt")
public void testDecoratedLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/decoratedLambda.kt");
}
@Test @Test
@TestMetadata("delegateExpressionAsLambda.kt") @TestMetadata("delegateExpressionAsLambda.kt")
public void testDelegateExpressionAsLambda() throws Exception { public void testDelegateExpressionAsLambda() throws Exception {
@@ -31,6 +31,7 @@ fun ConeClassifierLookupTag.toSymbol(useSiteSession: FirSession): FirClassifierS
when (this) { when (this) {
is ConeClassLikeLookupTag -> toSymbol(useSiteSession) is ConeClassLikeLookupTag -> toSymbol(useSiteSession)
is ConeClassifierLookupTagWithFixedSymbol -> this.symbol is ConeClassifierLookupTagWithFixedSymbol -> this.symbol
// TODO: replace null with error(), see KT-57921
else -> null else -> null
} }
@@ -136,4 +137,3 @@ private fun Collection<ConeKotlinType>.findClassRepresentationThatIsSubtypeOf(
supertype: ConeKotlinType, supertype: ConeKotlinType,
session: FirSession session: FirSession
): ConeClassLikeLookupTag? = firstOrNull { it.isSubtypeOf(supertype, session) }?.findClassRepresentation(supertype, session) ): ConeClassLikeLookupTag? = firstOrNull { it.isSubtypeOf(supertype, session) }?.findClassRepresentation(supertype, session)
@@ -480,13 +480,12 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return when (this) { return when (this) {
is ConeFlexibleType -> this.upperBound.isNullableType() is ConeFlexibleType -> this.upperBound.isNullableType()
is ConeTypeParameterType -> lookupTag.symbol.allBoundsAreNullableOrUnresolved() is ConeTypeParameterType -> lookupTag.symbol.allBoundsAreNullableOrUnresolved()
is ConeTypeVariableType -> { // NB: There's no branch for ConeTypeVariableType, i.e. it always returns false for them
val symbol = lookupTag.toSymbol(session) ?: return false // And while it seems reasonable to have similar semantics as for stub types, it would make some diagnostic test failing
when (symbol) { // Thus, we leave the same semantics only for stubs (similar to TypeUtils.isNullableType)
is FirClassSymbol -> false is ConeStubType -> {
is FirTypeAliasSymbol -> symbol.fir.expandedConeType?.isNullableType() ?: false val symbol = (this.constructor.variable.defaultType.lookupTag.originalTypeParameter as? ConeTypeParameterLookupTag)?.symbol
is FirTypeParameterSymbol -> symbol.allBoundsAreNullableOrUnresolved() symbol == null || symbol.allBoundsAreNullableOrUnresolved()
}
} }
is ConeIntersectionType -> intersectedTypes.all { it.isNullableType() } is ConeIntersectionType -> intersectedTypes.all { it.isNullableType() }
is ConeClassLikeType -> directExpansionType(session)?.isNullableType() ?: false is ConeClassLikeType -> directExpansionType(session)?.isNullableType() ?: false
@@ -0,0 +1,21 @@
// FIR_IDENTICAL
// ISSUE: KT-57814
import kotlin.reflect.KProperty
fun <P2> xComponent(
builder: (prop1: P2) -> Unit
): (prop1: P2) -> Unit = {}
operator fun <P1> ((prop1: P1) -> Unit).getValue(
thisRef: Any?,
property: KProperty<*>
): (prop1: P1) -> Unit = this
val pdfDocumentViewer by xComponent { _: String? ->
}
fun xPDFDocumentViewer(
href: String?
) = pdfDocumentViewer(
href // Should be OK to pass nullable String? there
)
@@ -8835,6 +8835,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt"); runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/callableReferenceArgumentInDelegatedExpression.kt");
} }
@Test
@TestMetadata("decoratedLambda.kt")
public void testDecoratedLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/decoratedLambda.kt");
}
@Test @Test
@TestMetadata("delegateExpressionAsLambda.kt") @TestMetadata("delegateExpressionAsLambda.kt")
public void testDelegateExpressionAsLambda() throws Exception { public void testDelegateExpressionAsLambda() throws Exception {