FIR substitution: use standard approximation to remove captured types

This commit is contained in:
Mikhail Glukhikh
2020-09-10 09:13:09 +03:00
parent 7a73787680
commit b5f8fec213
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusIm
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.chain
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
class FirClassSubstitutionScope(
private val session: FirSession,
@@ -128,6 +130,18 @@ class FirClassSubstitutionScope(
return substitutor.substituteOrNull(this)
}
private fun ConeKotlinType.approximateCapturedCovariant(): ConeKotlinType {
return session.inferenceComponents.approximator.approximateToSuperType(
this, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation
) as? ConeKotlinType ?: this
}
private fun ConeKotlinType.approximateCapturedContravariant(): ConeKotlinType {
return session.inferenceComponents.approximator.approximateToSubType(
this, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation
) as? ConeKotlinType ?: this
}
private fun createFakeOverrideFunction(original: FirFunctionSymbol<*>): FirFunctionSymbol<*> {
if (substitutor == ConeSubstitutor.Empty) return original
val member = when (original) {
@@ -139,7 +153,7 @@ class FirClassSubstitutionScope(
val (newTypeParameters, newReceiverType, newReturnType, newSubstitutor) = createSubstitutedData(member)
val newParameterTypes = member.valueParameters.map {
it.returnTypeRef.coneType.substitute(newSubstitutor)
it.returnTypeRef.coneType.substitute(newSubstitutor)?.approximateCapturedContravariant()
}
if (newReceiverType == null && newReturnType == null && newParameterTypes.all { it == null } &&
@@ -171,7 +185,7 @@ class FirClassSubstitutionScope(
val (newTypeParameters, _, newReturnType, newSubstitutor) = createSubstitutedData(constructor)
val newParameterTypes = constructor.valueParameters.map {
it.returnTypeRef.coneType.substitute(newSubstitutor)
it.returnTypeRef.coneType.substitute(newSubstitutor)?.approximateCapturedContravariant()
}
if (newReturnType == null && newParameterTypes.all { it == null } && newTypeParameters === constructor.typeParameters) {
@@ -188,7 +202,7 @@ class FirClassSubstitutionScope(
val member = original.fir
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
val (newTypeParameters, newReceiverType, newReturnType) = createSubstitutedData(member)
val (newTypeParameters, newReceiverType, newReturnType, _) = createSubstitutedData(member)
if (newReceiverType == null &&
newReturnType == null && newTypeParameters === member.typeParameters
) {
@@ -223,10 +237,10 @@ class FirClassSubstitutionScope(
)
val receiverType = member.receiverTypeRef?.coneType
val newReceiverType = receiverType?.substitute(substitutor)
val newReceiverType = receiverType?.substitute(substitutor)?.approximateCapturedContravariant()
val returnType = typeCalculator.tryCalculateReturnType(member).type
val newReturnType = returnType.substitute(substitutor)
val newReturnType = returnType.substitute(substitutor)?.approximateCapturedCovariant()
return SubstitutedData(newTypeParameters, newReceiverType, newReturnType, substitutor)
}
@@ -236,7 +250,7 @@ class FirClassSubstitutionScope(
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
val returnType = typeCalculator.tryCalculateReturnType(member).type
val newReturnType = returnType.substitute() ?: return original
val newReturnType = returnType.substitute()?.approximateCapturedCovariant() ?: return original
return createFakeOverrideField(session, member, original, newReturnType, derivedClassId)
}
@@ -247,10 +261,10 @@ class FirClassSubstitutionScope(
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
val returnType = typeCalculator.tryCalculateReturnType(member).type
val newReturnType = returnType.substitute()
val newReturnType = returnType.substitute()?.approximateCapturedCovariant()
val newParameterTypes = member.getter.valueParameters.map {
it.returnTypeRef.coneType.substitute()
it.returnTypeRef.coneType.substitute()?.approximateCapturedContravariant()
}
if (newReturnType == null && newParameterTypes.all { it == null }) {
@@ -423,7 +437,9 @@ class FirClassSubstitutionScope(
isLocal = false
status = baseProperty.status.withExpect(isExpect)
resolvePhase = baseProperty.resolvePhase
typeParameters += configureAnnotationsTypeParametersAndSignature(baseProperty, newTypeParameters, newReceiverType, newReturnType)
typeParameters += configureAnnotationsTypeParametersAndSignature(
baseProperty, newTypeParameters, newReceiverType, newReturnType
)
}
return symbol
}