[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:
Generated
+10
@@ -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");
|
||||
|
||||
+16
-4
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
Vendored
+38
@@ -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
|
||||
)
|
||||
}
|
||||
Vendored
+38
@@ -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
|
||||
)
|
||||
}
|
||||
Vendored
+14
@@ -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");
|
||||
|
||||
Generated
+10
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user