[FIR] Properly handle flexible types during creation of DNNT

^KT-50788 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-01-14 16:49:38 +03:00
parent be020c588c
commit 57346bac54
8 changed files with 46 additions and 4 deletions
@@ -3533,6 +3533,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt39000.kt");
}
@Test
@TestMetadata("kt50788.kt")
public void testKt50788() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.kt");
}
@Test
@TestMetadata("multipleCasts.kt")
public void testMultipleCasts() throws Exception {
@@ -3124,6 +3124,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt39000.kt");
}
@TestMetadata("kt50788.kt")
public void testKt50788() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.kt");
}
@TestMetadata("multipleCasts.kt")
public void testMultipleCasts() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/multipleCasts.kt");
@@ -0,0 +1,5 @@
FILE: main.kt
public final fun <T : R|kotlin/CharSequence?|> foo(mapper: R|Mapper|, cls: R|java/lang/Class<T>?|): R|kotlin/Unit| {
lval result: R|T & Any| = R|<local>/mapper|.R|/Mapper.readValue|<R|ft<T, T?>|>(R|<local>/cls|)!!
R|<local>/result|.R|kotlin/CharSequence.length|
}
@@ -0,0 +1,14 @@
// ISSUE: KT-50788
// FILE: Mapper.java
public class Mapper {
public <T> T readValue(Class<T> valueType) {
return null;
}
}
// FILE: main.kt
fun <T : CharSequence?> foo(mapper: Mapper, cls: Class<T>?) {
val result = <!DEBUG_INFO_EXPRESSION_TYPE("T!!")!>mapper.readValue<T>(cls)!!<!> // The type of result is expected to be T & Any here, but in fact it's just T
result.length
}
@@ -3533,6 +3533,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt39000.kt");
}
@Test
@TestMetadata("kt50788.kt")
public void testKt50788() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.kt");
}
@Test
@TestMetadata("multipleCasts.kt")
public void testMultipleCasts() throws Exception {
@@ -3533,6 +3533,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt39000.kt");
}
@Test
@TestMetadata("kt50788.kt")
public void testKt50788() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.kt");
}
@Test
@TestMetadata("multipleCasts.kt")
public void testMultipleCasts() throws Exception {
@@ -57,7 +57,7 @@ private fun ConeTypeContext.makesSenseToBeDefinitelyNotNull(type: ConeKotlinType
is ConeTypeParameterType -> type.isNullableType()
// Actually, this branch should work for type parameters as well, but it breaks some cases. See KT-40114.
// Basically, if we have `T : X..X?`, then `T <: Any` but we still have `T` != `T & Any`.
is ConeTypeVariableType, is ConeCapturedType ->
is ConeTypeVariableType, is ConeCapturedType, is ConeFlexibleType ->
!AbstractNullabilityChecker.isSubtypeOfAny(
newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), type
)
@@ -73,7 +73,7 @@ fun ConeDefinitelyNotNullType.Companion.create(
): ConeDefinitelyNotNullType? {
return when {
original is ConeDefinitelyNotNullType -> original
typeContext.makesSenseToBeDefinitelyNotNull(original) -> ConeDefinitelyNotNullType(original)
typeContext.makesSenseToBeDefinitelyNotNull(original) -> ConeDefinitelyNotNullType(original.coneLowerBoundIfFlexible())
else -> null
}
}
@@ -77,8 +77,8 @@ fun test() {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String?")!>select2(Test.foo(get()), getIn())<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String?")!>select3(get(), getIn())<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String?")!>select3(get(), Test.foo(getIn()))<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String?")!>select3(Test.foo(get()), Test.foo(getIn()))<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String?")!>select3(Test.foo(get()), getIn())<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>select3(Test.foo(get()), Test.foo(getIn()))<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>select3(Test.foo(get()), getIn())<!>
""
}
}