[FIR] Don't create DNN types for flexible simple types

^KT-50788
This commit is contained in:
Dmitriy Novozhilov
2022-01-18 10:42:05 +03:00
committed by TeamCityServer
parent ceb744b53b
commit 5fc1e2e0cb
8 changed files with 79 additions and 13 deletions
@@ -2799,6 +2799,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolve/inference/definitelyNotNullIntersectionType.kt");
}
@Test
@TestMetadata("dnnThrowJavaCall.kt")
public void testDnnThrowJavaCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/dnnThrowJavaCall.kt");
}
@Test
@TestMetadata("elvisAndUnit.kt")
public void testElvisAndUnit() throws Exception {
@@ -2461,6 +2461,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/inference/definitelyNotNullIntersectionType.kt");
}
@TestMetadata("dnnThrowJavaCall.kt")
public void testDnnThrowJavaCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/dnnThrowJavaCall.kt");
}
@TestMetadata("elvisAndUnit.kt")
public void testElvisAndUnit() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt");
@@ -0,0 +1,4 @@
FILE: main.kt
public final fun getExcludedDirs(project: R|Project|, excludedProjects: R|kotlin/collections/List<Project>|): R|kotlin/collections/List<java/io/File>| {
^getExcludedDirs R|<local>/project|.R|/Project.plugins|.R|/PluginContainer.findPlugin|<R|ft<IdeaPlugin, IdeaPlugin?>|>(<getClass>(Q|IdeaPlugin|).R|kotlin/jvm/java|<R|IdeaPlugin|>)?.{ $subj$.R|/IdeaPlugin.excludeDirs| }?.{ $subj$.R|kotlin/collections/toList|<R|ft<java/io/File, java/io/File?>|>() } ?: R|kotlin/collections/emptyList|<R|java/io/File|>()
}
@@ -0,0 +1,37 @@
// WITH_STDLIB
// FULL_JDK
// FILE: Plugin.java
public interface Plugin {}
// FILE: IdeaPlugin.java
import java.io.File
import java.util.Set
public interface IdeaPlugin extends Plugin {
Set<File> getExcludeDirs()
}
// FILE: PluginContainer.java
import javax.annotation.Nullable
public interface PluginContainer {
@Nullable
<T extends Plugin> T findPlugin(Class<T> type);
}
// FILE: Project.java
public interface Project {
PluginContainer getPlugins();
Project getRootProject();
File getBuildDir();
}
// FILE: main.kt
import java.io.File
fun getExcludedDirs(project: Project, excludedProjects: List<Project>): List<File> {
return project.plugins.findPlugin(IdeaPlugin::class.java)?.excludeDirs?.toList() ?: emptyList()
}
@@ -2799,6 +2799,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/definitelyNotNullIntersectionType.kt");
}
@Test
@TestMetadata("dnnThrowJavaCall.kt")
public void testDnnThrowJavaCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/dnnThrowJavaCall.kt");
}
@Test
@TestMetadata("elvisAndUnit.kt")
public void testElvisAndUnit() throws Exception {
@@ -2799,6 +2799,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/inference/definitelyNotNullIntersectionType.kt");
}
@Test
@TestMetadata("dnnThrowJavaCall.kt")
public void testDnnThrowJavaCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/dnnThrowJavaCall.kt");
}
@Test
@TestMetadata("elvisAndUnit.kt")
public void testElvisAndUnit() throws Exception {
@@ -53,17 +53,19 @@ fun ConeInferenceContext.intersectTypesOrNull(types: List<ConeKotlinType>): Cone
fun TypeCheckerProviderContext.equalTypes(a: ConeKotlinType, b: ConeKotlinType): Boolean =
AbstractTypeChecker.equalTypes(this, a, b)
private fun ConeTypeContext.makesSenseToBeDefinitelyNotNull(type: ConeKotlinType): Boolean = when (type) {
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 ConeFlexibleType ->
!AbstractNullabilityChecker.isSubtypeOfAny(
newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), type
)
// For all other types `T & Any` is the same as `T` without a question mark.
// TODO: not true for flexible types.
else -> false
private fun ConeTypeContext.makesSenseToBeDefinitelyNotNull(originalType: ConeKotlinType): Boolean {
return when (val type = originalType.lowerBoundIfFlexible()) {
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 -> {
!AbstractNullabilityChecker.isSubtypeOfAny(
newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), type
)
}
// For all other types `T & Any` is the same as `T` without a question mark.
else -> false
}
}
// TODO: leave only one of `create` and `makeConeTypeDefinitelyNotNullOrNotNull`
@@ -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())<!>
""
}
}