Substitute captured types with type variables properly

^KT-44687 Fixed
This commit is contained in:
Victor Petukhov
2021-03-15 12:51:42 +03:00
parent d276d583ba
commit a2b1aa753b
6 changed files with 51 additions and 4 deletions
@@ -12558,6 +12558,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/starProjectionRegression.kt");
}
@Test
@TestMetadata("substituteCapturedTypesWithTypeVariables.kt")
public void testSubstituteCapturedTypesWithTypeVariables() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/substituteCapturedTypesWithTypeVariables.kt");
}
@Test
@TestMetadata("topLevelCapturingInsideReturnType.kt")
public void testTopLevelCapturingInsideReturnType() throws Exception {
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.substitute
import org.jetbrains.kotlin.types.*
@@ -105,8 +106,8 @@ interface NewTypeSubstitutor : TypeSubstitutorMarker {
val substitutedInnerType = substitute(innerType, keepAnnotation, runCapturedChecks = false)
if (substitutedInnerType != null) {
if (innerType is StubType || substitutedInnerType is StubType || innerType.constructor is IntersectionTypeConstructor) {
return NewCapturedType(
return if (substitutedInnerType.isCaptured()) substitutedInnerType else {
NewCapturedType(
capturedType.captureStatus,
NewCapturedTypeConstructor(
TypeProjectionImpl(typeConstructor.projection.projectionKind, substitutedInnerType),
@@ -114,8 +115,6 @@ interface NewTypeSubstitutor : TypeSubstitutorMarker {
),
lowerType = if (capturedType.lowerType != null) substitutedInnerType else null
)
} else {
throwExceptionAboutInvalidCapturedSubstitution(capturedType, innerType, substitutedInnerType)
}
}
@@ -0,0 +1,12 @@
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
class Foo<K>
fun <T> getFoo(value: T) = null as Foo<out Foo<T>>
fun <R> takeLambda(block: () -> R) {}
fun main(x: Int) {
takeLambda {
getFoo(x)
}
}
@@ -0,0 +1,12 @@
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
class Foo<K>
fun <T> getFoo(value: T) = null as Foo<out Foo<T>>
fun <R> takeLambda(block: () -> R) {}
fun main(x: Int) {
takeLambda {
getFoo(x)
}
}
@@ -0,0 +1,12 @@
package
public fun </*0*/ T> getFoo(/*0*/ value: T): Foo<out Foo<T>>
public fun main(/*0*/ x: kotlin.Int): kotlin.Unit
public fun </*0*/ R> takeLambda(/*0*/ block: () -> R): kotlin.Unit
public final class Foo</*0*/ K> {
public constructor Foo</*0*/ K>()
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
}
@@ -12564,6 +12564,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/starProjectionRegression.kt");
}
@Test
@TestMetadata("substituteCapturedTypesWithTypeVariables.kt")
public void testSubstituteCapturedTypesWithTypeVariables() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/substituteCapturedTypesWithTypeVariables.kt");
}
@Test
@TestMetadata("topLevelCapturingInsideReturnType.kt")
public void testTopLevelCapturingInsideReturnType() throws Exception {