[NI] Check stub types in result type

An uninferred parameter stub may leak through calculation of CST(Inv<Uninferred Stub>, Nothing) into a result type.
A stub type in the result type means a type error. So we can afford recalculating
CST with stub-containing types filtered out, since its an error anyway.
This prevents stub types leakages and helps with reporting type error diagnostics.

KT-35914 Fixed
KT-35943 Fixed
This commit is contained in:
Pavel Kirpichenkov
2020-01-17 11:43:50 +03:00
parent 581db19544
commit cb0b44273d
17 changed files with 210 additions and 4 deletions
@@ -10861,6 +10861,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/inference/nothingType/nestedLambdaInferenceWithIncorporationOfVariables.kt");
}
@TestMetadata("notEnoughInformationAndNothing.kt")
public void testNotEnoughInformationAndNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/notEnoughInformationAndNothing.kt");
}
@TestMetadata("notEnoughInformationFromNullabilityConstraint.kt")
public void testNotEnoughInformationFromNullabilityConstraint() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/notEnoughInformationFromNullabilityConstraint.kt");
@@ -11185,6 +11190,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt35844.kt");
}
@TestMetadata("kt35943.kt")
public void testKt35943() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt35943.kt");
}
@TestMetadata("kt4420.kt")
public void testKt4420() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
@@ -17,13 +17,11 @@
package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionStatelessCallbacks
import org.jetbrains.kotlin.resolve.calls.inference.components.TypeVariableDirectionCalculator.ResolveDirection
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.types.AbstractTypeApproximator
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ResultTypeResolver(
val typeApproximator: AbstractTypeApproximator,
@@ -98,9 +96,20 @@ class ResultTypeResolver(
if (lowerConstraintTypes.isNotEmpty()) {
val types = sinkIntegerLiteralTypes(lowerConstraintTypes)
val commonSuperType = with(NewCommonSuperTypeCalculator) {
this@findSubType.commonSuperType(types)
var commonSuperType = computeCommonSuperType(types)
if (commonSuperType.contains { it is StubTypeMarker }) {
val typesWithoutStubs = types.filter { lowerType ->
!lowerType.contains { it is StubTypeMarker }
}
if (typesWithoutStubs.isNotEmpty()) {
commonSuperType = computeCommonSuperType(typesWithoutStubs)
} else {
return null
}
}
/**
*
* fun <T> Array<out T>.intersect(other: Iterable<T>) {
@@ -128,6 +137,9 @@ class ResultTypeResolver(
return null
}
private fun Context.computeCommonSuperType(types: List<KotlinTypeMarker>): KotlinTypeMarker =
with(NewCommonSuperTypeCalculator) { commonSuperType(types) }
private fun Context.prepareLowerConstraints(constraints: List<Constraint>): List<KotlinTypeMarker> {
var atLeastOneProper = false
var atLeastOneNonProper = false
+15
View File
@@ -0,0 +1,15 @@
// !LANGUAGE: +NewInference
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
// IGNORE_BACKEND_FIR: JVM_IR
class Inv<T>
fun <T> bar(x: Inv<T>.() -> Unit) = x
fun box(): String {
listOf(
bar<Char> { },
bar { } // the problem is here
)
return "OK"
}
@@ -0,0 +1,38 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// !CHECK_TYPE
class Inv<I>
fun <T> materialize(): Inv<T> = TODO()
fun <K> id(arg: K) = arg
fun <S> select(vararg args: S): S = TODO()
fun test1(b: Boolean?) {
val v = when(b) {
true -> materialize()
false -> null
null -> materialize<String>()
}
v checkType { <!UNRESOLVED_REFERENCE!>_<!><Inv<String>?>() }
}
fun test2() {
select(
materialize()
)
select(materialize(), materialize<String>())
select(materialize(), null, Inv<String>())
select(
materialize(),
null
)
select(
materialize(),
materialize()
)
select(
materialize(),
materialize(),
null
)
}
@@ -0,0 +1,38 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// !CHECK_TYPE
class Inv<I>
fun <T> materialize(): Inv<T> = TODO()
fun <K> id(arg: K) = arg
fun <S> select(vararg args: S): S = TODO()
fun test1(b: Boolean?) {
val v = when(b) {
true -> materialize()
false -> null
null -> materialize<String>()
}
v checkType { _<Inv<String>?>() }
}
fun test2() {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>()
)
select(materialize(), materialize<String>())
select(materialize(), null, Inv<String>())
<!TYPE_MISMATCH!>select<!>(
materialize(),
null
)
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>(),
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>()
)
select(
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>(),
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>(),
null
)
}
@@ -0,0 +1,14 @@
package
public fun </*0*/ K> id(/*0*/ arg: K): K
public fun </*0*/ T> materialize(): Inv<T>
public fun </*0*/ S> select(/*0*/ vararg args: S /*kotlin.Array<out S>*/): S
public fun test1(/*0*/ b: kotlin.Boolean?): kotlin.Unit
public fun test2(): kotlin.Unit
public final class Inv</*0*/ I> {
public constructor Inv</*0*/ I>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,9 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
class Inv<I>
fun <T> create(): Inv<T> = TODO()
fun main() {
if (true) create() else null
}
@@ -0,0 +1,9 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_EXPRESSION
class Inv<I>
fun <T> create(): Inv<T> = TODO()
fun main() {
<!TYPE_MISMATCH!>if (true) create() else null<!>
}
@@ -0,0 +1,11 @@
package
public fun </*0*/ T> create(): Inv<T>
public fun main(): kotlin.Unit
public final class Inv</*0*/ I> {
public constructor Inv</*0*/ I>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -10868,6 +10868,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/nestedLambdaInferenceWithIncorporationOfVariables.kt");
}
@TestMetadata("notEnoughInformationAndNothing.kt")
public void testNotEnoughInformationAndNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/notEnoughInformationAndNothing.kt");
}
@TestMetadata("notEnoughInformationFromNullabilityConstraint.kt")
public void testNotEnoughInformationFromNullabilityConstraint() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/notEnoughInformationFromNullabilityConstraint.kt");
@@ -11192,6 +11197,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt35844.kt");
}
@TestMetadata("kt35943.kt")
public void testKt35943() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt35943.kt");
}
@TestMetadata("kt4420.kt")
public void testKt4420() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
@@ -10863,6 +10863,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/inference/nothingType/nestedLambdaInferenceWithIncorporationOfVariables.kt");
}
@TestMetadata("notEnoughInformationAndNothing.kt")
public void testNotEnoughInformationAndNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/notEnoughInformationAndNothing.kt");
}
@TestMetadata("notEnoughInformationFromNullabilityConstraint.kt")
public void testNotEnoughInformationFromNullabilityConstraint() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/notEnoughInformationFromNullabilityConstraint.kt");
@@ -11187,6 +11192,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt35844.kt");
}
@TestMetadata("kt35943.kt")
public void testKt35943() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt35943.kt");
}
@TestMetadata("kt4420.kt")
public void testKt4420() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
@@ -25926,6 +25926,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/regressions/kt3587.kt");
}
@TestMetadata("kt35914.kt")
public void testKt35914() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt35914.kt");
}
@TestMetadata("kt3850.kt")
public void testKt3850() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt3850.kt");
@@ -24743,6 +24743,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/regressions/kt3587.kt");
}
@TestMetadata("kt35914.kt")
public void testKt35914() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt35914.kt");
}
@TestMetadata("kt3850.kt")
public void testKt3850() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt3850.kt");
@@ -24425,6 +24425,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/regressions/kt3587.kt");
}
@TestMetadata("kt35914.kt")
public void testKt35914() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt35914.kt");
}
@TestMetadata("kt3850.kt")
public void testKt3850() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt3850.kt");
@@ -24425,6 +24425,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/regressions/kt3587.kt");
}
@TestMetadata("kt35914.kt")
public void testKt35914() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt35914.kt");
}
@TestMetadata("kt3850.kt")
public void testKt3850() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt3850.kt");
@@ -20076,6 +20076,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/regressions/kt3587.kt");
}
@TestMetadata("kt35914.kt")
public void testKt35914() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt35914.kt");
}
@TestMetadata("kt3850.kt")
public void testKt3850() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt3850.kt");
@@ -21211,6 +21211,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/regressions/kt3587.kt");
}
@TestMetadata("kt35914.kt")
public void testKt35914() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt35914.kt");
}
@TestMetadata("kt3850.kt")
public void testKt3850() throws Exception {
runTest("compiler/testData/codegen/box/regressions/kt3850.kt");