FIR: instantiate type argument to captured type if needed

This commit is contained in:
Tianyu Geng
2021-07-21 14:11:19 -07:00
committed by TeamCityServer
parent bcf6582af7
commit cd99c35649
13 changed files with 32 additions and 36 deletions
@@ -7,7 +7,7 @@ FILE: typeAliasWithNotNullBound.kt
} }
public final typealias MyAlias = R|Inv<out kotlin/CharSequence>| public final typealias MyAlias = R|Inv<out kotlin/CharSequence>|
public final fun foo(p: R|MyAlias|): R|kotlin/Unit| { public final fun foo(p: R|MyAlias|): R|kotlin/Unit| {
R|/bar|<R|kotlin/CharSequence|>(R|<local>/p|).R|kotlin/CharSequence.length| R|/bar|<R|CapturedType(out kotlin/CharSequence)|>(R|<local>/p|).R|kotlin/CharSequence.length|
} }
public final fun <T : R|kotlin/Any|> bar(x: R|Inv<T>|): R|T| { public final fun <T : R|kotlin/Any|> bar(x: R|Inv<T>|): R|T| {
^bar R|kotlin/TODO|() ^bar R|kotlin/TODO|()
@@ -4,5 +4,5 @@ FILE: main.kt
public final fun <D : R|A|> foo(b: R|B<D>|): R|kotlin/Unit| { public final fun <D : R|A|> foo(b: R|B<D>|): R|kotlin/Unit| {
} }
public final fun main(b: R|B<*>|): R|kotlin/Unit| { public final fun main(b: R|B<*>|): R|kotlin/Unit| {
R|/foo|<R|ft<A, A?>|>(R|<local>/b|) R|/foo|<R|CapturedType(*)|>(R|<local>/b|)
} }
@@ -5,7 +5,7 @@ FILE: kt40131.kt
} }
public final val <T : R|kotlin/reflect/KClass<*>|> R|T|.myJava1: R|java/lang/Class<*>| public final val <T : R|kotlin/reflect/KClass<*>|> R|T|.myJava1: R|java/lang/Class<*>|
public get(): R|java/lang/Class<*>| { public get(): R|java/lang/Class<*>| {
^ this@R|/myJava1|.R|/javaImpl|<R|kotlin/Any|> ^ this@R|/myJava1|.R|/javaImpl|<R|CapturedType(*)|>
} }
public final val <E : R|kotlin/Any|, T : R|kotlin/reflect/KClass<E>|> R|T|.myJava2: R|java/lang/Class<E>| public final val <E : R|kotlin/Any|, T : R|kotlin/reflect/KClass<E>|> R|T|.myJava2: R|java/lang/Class<E>|
public get(): R|java/lang/Class<E>| { public get(): R|java/lang/Class<E>| {
@@ -15,19 +15,19 @@ FILE: receiverWithCapturedType.kt
^updateD R|<local>/d| ^updateD R|<local>/d|
} }
public final fun test_1_1(resolvedCall: R|ResolvedCall<out CallableDescriptor>|): R|kotlin/Unit| { public final fun test_1_1(resolvedCall: R|ResolvedCall<out CallableDescriptor>|): R|kotlin/Unit| {
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CallableDescriptor|>() R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CapturedType(out CallableDescriptor)|>()
} }
public final fun test_1_2(resolvedCall: R|ResolvedCall<in CallableDescriptor>|): R|kotlin/Unit| { public final fun test_1_2(resolvedCall: R|ResolvedCall<in CallableDescriptor>|): R|kotlin/Unit| {
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CallableDescriptor|>() R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CapturedType(in CallableDescriptor)|>()
} }
public final fun test_1_3(resolvedCall: R|ResolvedCall<CallableDescriptor>|): R|kotlin/Unit| { public final fun test_1_3(resolvedCall: R|ResolvedCall<CallableDescriptor>|): R|kotlin/Unit| {
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CallableDescriptor|>() R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CallableDescriptor|>()
} }
public final fun test_2_1(resolvedCall: R|ResolvedCall<out CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| { public final fun test_2_1(resolvedCall: R|ResolvedCall<out CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| {
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.<Inapplicable(INAPPLICABLE): /updateD>#<R|CallableDescriptor|>(R|<local>/d|) lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.<Inapplicable(INAPPLICABLE): /updateD>#<R|CapturedType(out CallableDescriptor)|>(R|<local>/d|)
} }
public final fun test_2_2(resolvedCall: R|ResolvedCall<in CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| { public final fun test_2_2(resolvedCall: R|ResolvedCall<in CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| {
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.R|/updateD|<R|CallableDescriptor|>(R|<local>/d|) lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.R|/updateD|<R|CapturedType(in CallableDescriptor)|>(R|<local>/d|)
} }
public final fun test_2_3(resolvedCall: R|ResolvedCall<CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| { public final fun test_2_3(resolvedCall: R|ResolvedCall<CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| {
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.R|/updateD|<R|CallableDescriptor|>(R|<local>/d|) lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.R|/updateD|<R|CallableDescriptor|>(R|<local>/d|)
@@ -19,10 +19,10 @@ FILE: simpleCapturedTypes.kt
^ this@R|/idP| ^ this@R|/idP|
} }
private final fun getSetterInfos(kc: R|KC<out Ann>|): R|kotlin/Unit| { private final fun getSetterInfos(kc: R|KC<out Ann>|): R|kotlin/Unit| {
R|/id|<R|Ann|>(R|<local>/kc|).R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|() R|/id|<R|CapturedType(out Ann)|>(R|<local>/kc|).R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idR|<R|Ann|>().R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|() R|<local>/kc|.R|/idR|<R|CapturedType(out Ann)|>().R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idP|<R|Ann|>.R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|() R|<local>/kc|.R|/idP|<R|CapturedType(out Ann)|>.R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
lval x1: R|KC<out Ann>| = R|/id|<R|Ann|>(R|<local>/kc|) lval x1: R|KC<out Ann>| = R|/id|<R|CapturedType(out Ann)|>(R|<local>/kc|)
lval x2: R|KC<out Ann>| = R|<local>/kc|.R|/idR|<R|Ann|>() lval x2: R|KC<out Ann>| = R|<local>/kc|.R|/idR|<R|CapturedType(out Ann)|>()
lval x3: R|KC<out Ann>| = R|<local>/kc|.R|/idP|<R|Ann|> lval x3: R|KC<out Ann>| = R|<local>/kc|.R|/idP|<R|CapturedType(out Ann)|>
} }
@@ -40,8 +40,8 @@ FILE: referenceToExtension.kt
} }
public final fun test_2(): R|kotlin/Unit| { public final fun test_2(): R|kotlin/Unit| {
lval extensionValRef: R|kotlin/reflect/KProperty1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionVal<kotlin/Any?>| lval extensionValRef: R|kotlin/reflect/KProperty1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionVal<CapturedType(*)>|
lval extensionFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionFun<kotlin/Any?>| lval extensionFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionFun<CapturedType(*)>|
} }
} }
@@ -7,7 +7,7 @@ FILE: test.kt
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
private final val klass: R|java/lang/Class<out MyTest>| = <getClass>(this@R|/MyTest|).R|kotlin/jvm/java|<R|MyTest|> private final val klass: R|java/lang/Class<out MyTest>| = <getClass>(this@R|/MyTest|).R|kotlin/jvm/java|<R|CapturedType(out MyTest)|>
private get(): R|java/lang/Class<out MyTest>| private get(): R|java/lang/Class<out MyTest>|
private final val logger: R|ft<Logger, Logger?>| = Q|Logger|.R|/Logger.getInstance|(this@R|/MyTest|.R|/MyTest.klass|) private final val logger: R|ft<Logger, Logger?>| = Q|Logger|.R|/Logger.getInstance|(this@R|/MyTest|.R|/MyTest.klass|)
@@ -1,4 +1,4 @@
FILE: capturedFlexible.kt FILE: capturedFlexible.kt
public final fun foo(z: R|java/util/zip/ZipFile|): R|kotlin/Unit| { public final fun foo(z: R|java/util/zip/ZipFile|): R|kotlin/Unit| {
R|<local>/z|.R|java/util/zip/ZipFile.entries|().R|kotlin/sequences/asSequence|<R|ft<java/util/zip/ZipEntry, java/util/zip/ZipEntry?>|>() R|<local>/z|.R|java/util/zip/ZipFile.entries|().R|kotlin/sequences/asSequence|<R|CapturedType(out ft<java/util/zip/ZipEntry, java/util/zip/ZipEntry?>)|>()
} }
@@ -135,14 +135,12 @@ class Fir2IrTypeConverter(
is ConeCapturedType -> { is ConeCapturedType -> {
val cached = capturedTypeCache[this] val cached = capturedTypeCache[this]
if (cached == null) { if (cached == null) {
val irType = lowerType?.toIrType(typeContext) ?: run { capturedTypeCache[this] = errorTypeForCapturedTypeStub
capturedTypeCache[this] = errorTypeForCapturedTypeStub val supertypes = constructor.supertypes!!
val supertypes = constructor.supertypes!! val approximation = supertypes.find {
val approximation = supertypes.find { it == (constructor.projection as? ConeKotlinTypeProjection)?.type
it == (constructor.projection as? ConeKotlinTypeProjection)?.type } ?: supertypes.first()
} ?: supertypes.first() val irType = approximation.toIrType(typeContext)
approximation.toIrType(typeContext)
}
capturedTypeCache[this] = irType capturedTypeCache[this] = irType
irType irType
} else { } else {
@@ -504,7 +504,7 @@ class FirCallCompletionResultsWriterTransformer(
.map { .map {
finalSubstitutor.substituteOrSelf(it).let { substitutedType -> finalSubstitutor.substituteOrSelf(it).let { substitutedType ->
typeApproximator.approximateToSuperType( typeApproximator.approximateToSuperType(
substitutedType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference, substitutedType, TypeApproximatorConfiguration.TypeArgumentApproximation,
) ?: substitutedType ) ?: substitutedType
} }
} }
@@ -53,14 +53,14 @@ open class TypeApproximatorConfiguration {
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
abstract class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus) : sealed class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus?) :
AllFlexibleSameValue() { AllFlexibleSameValue() {
override val allFlexible: Boolean get() = true override val allFlexible: Boolean get() = true
override val errorType: Boolean get() = true override val errorType: Boolean get() = true
// i.e. will be approximated only approximatedCapturedStatus captured types // i.e. will be approximated only approximatedCapturedStatus captured types
override fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean = override fun capturedType(ctx: TypeSystemInferenceExtensionContext, type: CapturedTypeMarker): Boolean =
type.captureStatus(ctx) == approximatedCapturedStatus approximatedCapturedStatus != null && type.captureStatus(ctx) == approximatedCapturedStatus
override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED override val intersection: IntersectionStrategy get() = IntersectionStrategy.ALLOWED
override val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean get() = { true } override val typeVariable: (TypeVariableTypeConstructorMarker) -> Boolean get() = { true }
@@ -79,6 +79,11 @@ open class TypeApproximatorConfiguration {
override val intersectionTypesInContravariantPositions: Boolean get() = true override val intersectionTypesInContravariantPositions: Boolean get() = true
} }
object TypeArgumentApproximation : AbstractCapturedTypesApproximation(null) {
override val integerLiteralType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
}
object IntegerLiteralsTypesApproximation : AllFlexibleSameValue() { object IntegerLiteralsTypesApproximation : AllFlexibleSameValue() {
override val integerLiteralType: Boolean get() = true override val integerLiteralType: Boolean get() = true
override val allFlexible: Boolean get() = true override val allFlexible: Boolean get() = true
@@ -1,8 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A<F>
inline fun <reified T> foo(x: A<T>) {}
fun test(x: A<out CharSequence>) {
foo(x)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER // !DIAGNOSTICS: -UNUSED_PARAMETER
class A<F> class A<F>