Resolution: extract projections from captured flexible type properly

#KT-54100 Fixed
Related to KT-54196, KT-54198
This commit is contained in:
Mikhail Glukhikh
2022-09-20 13:59:29 +02:00
committed by teamcity
parent 8517249776
commit e9bb0f4fda
12 changed files with 130 additions and 4 deletions
@@ -35694,6 +35694,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt");
}
@Test
@TestMetadata("typeVariableShouldNotBeFixed.kt")
public void testTypeVariableShouldNotBeFixed() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt");
}
@Test
@TestMetadata("useInferenceInformationFromExtension.kt")
public void testUseInferenceInformationFromExtension() throws Exception {
@@ -35694,6 +35694,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt");
}
@Test
@TestMetadata("typeVariableShouldNotBeFixed.kt")
public void testTypeVariableShouldNotBeFixed() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt");
}
@Test
@TestMetadata("useInferenceInformationFromExtension.kt")
public void testUseInferenceInformationFromExtension() throws Exception {
@@ -35694,6 +35694,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt");
}
@Test
@TestMetadata("typeVariableShouldNotBeFixed.kt")
public void testTypeVariableShouldNotBeFixed() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt");
}
@Test
@TestMetadata("useInferenceInformationFromExtension.kt")
public void testUseInferenceInformationFromExtension() throws Exception {
@@ -204,9 +204,15 @@ class VariableFixationFinder(
inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation(type: KotlinTypeMarker, isProper: (KotlinTypeMarker) -> Boolean) =
isProper(type) && extractProjectionsForAllCapturedTypes(type).all(isProper)
@OptIn(ExperimentalStdlibApi::class)
fun TypeSystemInferenceExtensionContext.extractProjectionsForAllCapturedTypes(baseType: KotlinTypeMarker): Set<KotlinTypeMarker> {
val simpleBaseType = baseType.asSimpleType()
if (baseType.isFlexible()) {
val flexibleType = baseType.asFlexibleType()!!
return buildSet {
addAll(extractProjectionsForAllCapturedTypes(flexibleType.lowerBound()))
addAll(extractProjectionsForAllCapturedTypes(flexibleType.upperBound()))
}
}
val simpleBaseType = baseType.asSimpleType()?.originalIfDefinitelyNotNullable()
return buildSet {
val projectionType = if (simpleBaseType is CapturedTypeMarker) {
@@ -289,7 +289,7 @@ class NewConstraintSystemImpl(
private fun isProperTypeImpl(type: KotlinTypeMarker): Boolean =
!type.contains {
val capturedType = it.asSimpleType()?.asCapturedType()
// TODO: change NewCapturedType to markered one for FE-IR
val typeToCheck = if (capturedType is CapturedTypeMarker && capturedType.captureStatus() == CaptureStatus.FROM_EXPRESSION)
capturedType.typeConstructorProjection().takeUnless { projection -> projection.isStarProjection() }?.getType()
else
@@ -117,7 +117,8 @@ interface NewTypeSubstitutor : TypeSubstitutorMarker {
TypeProjectionImpl(typeConstructor.projection.projectionKind, substitutedInnerType),
typeParameter = typeConstructor.typeParameter
).also { it.initializeSupertypes(substitutedSuperTypes) },
lowerType = if (capturedType.lowerType != null) substitutedInnerType else null
lowerType = if (capturedType.lowerType != null) substitutedInnerType else null,
isMarkedNullable = type.isMarkedNullable
)
}
}
@@ -0,0 +1,32 @@
// FILE: spr/Expr.java
package spr;
import org.jetbrains.annotations.NotNull;
public interface Exec<E> {
boolean run(@NotNull Model model, @NotNull Processor<? super E> params);
}
// FILE: spr/foo.kt
package spr
open class Processor<P> {
fun process(t: P): Boolean {
return true
}
}
class Model
fun <C> context(p: Processor<in C>, exec: Exec<C>) {}
fun <M> materialize(): Processor<M> = TODO()
private fun foo(model: Model) {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER("M")!>materialize<!>().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER("T")!>apply<!> {
context(
this,
Exec { m, p -> p.process(m) } // Note: Builder inference
)
}
}
@@ -0,0 +1,32 @@
// FILE: spr/Expr.java
package spr;
import org.jetbrains.annotations.NotNull;
public interface Exec<E> {
boolean run(@NotNull Model model, @NotNull Processor<? super E> params);
}
// FILE: spr/foo.kt
package spr
open class Processor<P> {
fun process(t: P): Boolean {
return true
}
}
class Model
fun <C> context(p: Processor<in C>, exec: Exec<C>) {}
fun <M> materialize(): Processor<M> = TODO()
private fun foo(model: Model) {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>materialize<!>().<!DEBUG_INFO_MISSING_UNRESOLVED!>apply<!> {
context(
<!NO_THIS!>this<!>,
Exec { m, p -> p.process(m) } // Note: Builder inference
)
}
}
@@ -0,0 +1,29 @@
package
package spr {
public fun </*0*/ C> context(/*0*/ p: spr.Processor<in C>, /*1*/ exec: spr.Exec<C>): kotlin.Unit
private fun foo(/*0*/ model: spr.Model): kotlin.Unit
public fun </*0*/ M> materialize(): spr.Processor<M>
public interface Exec</*0*/ E : kotlin.Any!> {
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 abstract fun run(/*0*/ @org.jetbrains.annotations.NotNull model: spr.Model, /*1*/ @org.jetbrains.annotations.NotNull params: spr.Processor<in E!>): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Model {
public constructor Model()
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
}
public open class Processor</*0*/ P> {
public constructor Processor</*0*/ P>()
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 final fun process(/*0*/ t: P): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -35784,6 +35784,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt");
}
@Test
@TestMetadata("typeVariableShouldNotBeFixed.kt")
public void testTypeVariableShouldNotBeFixed() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt");
}
@Test
@TestMetadata("useInferenceInformationFromExtension.kt")
public void testUseInferenceInformationFromExtension() throws Exception {
@@ -122,6 +122,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
}
override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? {
// TODO: https://youtrack.jetbrains.com/issue/KT-54196 (old captured type here)
require(this is NewCapturedType, this::errorMessage)
return this.lowerType
}
@@ -101,6 +101,7 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Flexibl
assert(!lowerBound.isFlexible()) { "Lower bound of a flexible type can not be flexible: $lowerBound" }
assert(!upperBound.isFlexible()) { "Upper bound of a flexible type can not be flexible: $upperBound" }
// TODO: https://youtrack.jetbrains.com/issue/KT-54198 (two captured types)
assert(lowerBound != upperBound) { "Lower and upper bounds are equal: $lowerBound == $upperBound" }
assert(KotlinTypeChecker.DEFAULT.isSubtypeOf(lowerBound, upperBound)) {
"Lower bound $lowerBound of a flexible type must be a subtype of the upper bound $upperBound"