Do not return star-projections during approximation
See comment in test for clarification #KT-14453 Fixed
This commit is contained in:
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// See KT-14453
|
||||||
|
val <T : Any> KClass1<T>.primaryConstructor: KFunction1<T>? get() = null!!
|
||||||
|
|
||||||
|
interface KClass1<F : Any>
|
||||||
|
interface KFunction1<out R>
|
||||||
|
fun f(type: KClass1<*>): KFunction1<Any>? =
|
||||||
|
// What happens here:
|
||||||
|
// 1. Create captured type for type argument T (it's built upon star-projection from `KClass<*>` that's argument is <: Any)
|
||||||
|
// 2. Approximate resulting descriptor, now it 'KClass1<*>.primaryConstructor: KFunction1<*>'
|
||||||
|
// Note that star-projection in 'KFunction1<*>' is obtained from KClass and its `projectionType` is Any (not-nullable).
|
||||||
|
// Of course that situation is already strange
|
||||||
|
// 3. When checking subtyping after call completion we get that 'KFunction1<*>' is not a subtype of 'KFunction1<Any>' in new type checker.
|
||||||
|
// The answer is correct, but this old type checker used `projectionType` for this and it was resulting in KFunction1<*> <: KFunction1<Any>
|
||||||
|
//
|
||||||
|
// So to fix the issue we use 'out starProjectionType' instead of star-projection itself in approximation
|
||||||
|
// Note that in new inference there should be no approximation for IN-position types (they must remain captured)
|
||||||
|
type.primaryConstructor
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val </*0*/ T : kotlin.Any> KClass1<T>.primaryConstructor: KFunction1<T>?
|
||||||
|
public fun f(/*0*/ type: KClass1<*>): KFunction1<kotlin.Any>?
|
||||||
|
|
||||||
|
public interface KClass1</*0*/ F : 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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface KFunction1</*0*/ out R> {
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -9740,6 +9740,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForOutCaptured.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForOutCaptured.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("starProjectionRegression.kt")
|
||||||
|
public void testStarProjectionRegression() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/starProjectionRegression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/commonSystem")
|
@TestMetadata("compiler/testData/diagnostics/tests/inference/commonSystem")
|
||||||
|
|||||||
@@ -86,7 +86,11 @@ fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?, approxi
|
|||||||
private fun substituteCapturedTypesWithProjections(typeProjection: TypeProjection): TypeProjection? {
|
private fun substituteCapturedTypesWithProjections(typeProjection: TypeProjection): TypeProjection? {
|
||||||
val typeSubstitutor = TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
val typeSubstitutor = TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||||
override fun get(key: TypeConstructor): TypeProjection? {
|
override fun get(key: TypeConstructor): TypeProjection? {
|
||||||
return (key as? CapturedTypeConstructor)?.typeProjection
|
val capturedTypeConstructor = key as? CapturedTypeConstructor ?: return null
|
||||||
|
if (capturedTypeConstructor.typeProjection.isStarProjection) {
|
||||||
|
return TypeProjectionImpl(Variance.OUT_VARIANCE, capturedTypeConstructor.typeProjection.type)
|
||||||
|
}
|
||||||
|
return capturedTypeConstructor.typeProjection
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return typeSubstitutor.substituteWithoutApproximation(typeProjection)
|
return typeSubstitutor.substituteWithoutApproximation(typeProjection)
|
||||||
|
|||||||
Reference in New Issue
Block a user