K2: Fix PCLA breaking change when using a bare type on a type variable
See the change at docs/fir/pcla.md and the kdoc at `getAndSemiFixCurrentResultIfTypeVariable` for clarification ^KT-64840 Fixed
This commit is contained in:
committed by
Space Team
parent
141be17b4b
commit
232c3aeadc
+13
@@ -37,6 +37,19 @@ abstract class FirInferenceSession {
|
||||
|
||||
open fun addSubtypeConstraintIfCompatible(lowerType: ConeKotlinType, upperType: ConeKotlinType, element: FirElement) {}
|
||||
|
||||
/**
|
||||
* For non-trivial inference session (currently PCLA-only), if the type is a type variable that might be fixed,
|
||||
* fix it and return a fixation result.
|
||||
*
|
||||
* Type variable might be fixed if it doesn't belong to an outer CS and have proper constraints.
|
||||
*
|
||||
* By semi-fixation we mean that only the relevant EQUALITY constraint is added,
|
||||
* [org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext.fixVariable] is not expected to be called.
|
||||
*
|
||||
* NB: The callee must pay attention that exactly current common CS will be modified.
|
||||
*/
|
||||
open fun getAndSemiFixCurrentResultIfTypeVariable(type: ConeKotlinType): ConeKotlinType? = null
|
||||
|
||||
companion object {
|
||||
val DEFAULT: FirInferenceSession = object : FirInferenceSession() {
|
||||
override fun <T> processPartiallyResolvedCall(
|
||||
|
||||
+9
-6
@@ -135,7 +135,7 @@ class FirPCLAInferenceSession(
|
||||
val system = (this as? FirResolvable)?.candidate()?.system ?: currentCommonSystem
|
||||
|
||||
if (resolutionMode is ResolutionMode.ReceiverResolution) {
|
||||
fixVariablesForMemberScope(resolvedType, system)?.let { additionalBindings += it }
|
||||
fixCurrentResultIfTypeVariableAndReturnBinding(resolvedType, system)?.let { additionalBindings += it }
|
||||
}
|
||||
|
||||
val substitutor = system.buildCurrentSubstitutor(additionalBindings) as ConeSubstitutor
|
||||
@@ -146,19 +146,22 @@ class FirPCLAInferenceSession(
|
||||
}
|
||||
}
|
||||
|
||||
fun fixVariablesForMemberScope(
|
||||
override fun getAndSemiFixCurrentResultIfTypeVariable(type: ConeKotlinType): ConeKotlinType? =
|
||||
fixCurrentResultIfTypeVariableAndReturnBinding(type, currentCommonSystem)?.second
|
||||
|
||||
fun fixCurrentResultIfTypeVariableAndReturnBinding(
|
||||
type: ConeKotlinType,
|
||||
myCs: NewConstraintSystemImpl,
|
||||
): Pair<ConeTypeVariableTypeConstructor, ConeKotlinType>? {
|
||||
return when (type) {
|
||||
is ConeFlexibleType -> fixVariablesForMemberScope(type.lowerBound, myCs)
|
||||
is ConeDefinitelyNotNullType -> fixVariablesForMemberScope(type.original, myCs)
|
||||
is ConeTypeVariableType -> fixVariablesForMemberScope(type, myCs)
|
||||
is ConeFlexibleType -> fixCurrentResultIfTypeVariableAndReturnBinding(type.lowerBound, myCs)
|
||||
is ConeDefinitelyNotNullType -> fixCurrentResultIfTypeVariableAndReturnBinding(type.original, myCs)
|
||||
is ConeTypeVariableType -> fixCurrentResultForNestedTypeVariable(type, myCs)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun fixVariablesForMemberScope(
|
||||
private fun fixCurrentResultForNestedTypeVariable(
|
||||
type: ConeTypeVariableType,
|
||||
myCs: NewConstraintSystemImpl,
|
||||
): Pair<ConeTypeVariableTypeConstructor, ConeKotlinType>? {
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ class PostponedArgumentsAnalyzer(
|
||||
// TODO: Fix variables for context receivers, too (KT-64859)
|
||||
buildMap {
|
||||
lambda.receiver
|
||||
?.let { pclaInferenceSession.fixVariablesForMemberScope(it, candidate.system) }
|
||||
?.let { pclaInferenceSession.fixCurrentResultIfTypeVariableAndReturnBinding(it, candidate.system) }
|
||||
?.let(this::plusAssign)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -867,7 +867,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
||||
val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this
|
||||
if (firClass.typeParameters.isEmpty()) return this
|
||||
|
||||
val originalType = argument.unwrapExpression().resolvedType
|
||||
val originalType = argument.unwrapExpression().resolvedType.let {
|
||||
components.context.inferenceSession.getAndSemiFixCurrentResultIfTypeVariable(it) ?: it
|
||||
}
|
||||
|
||||
val outerClasses by lazy(LazyThreadSafetyMode.NONE) { firClass.symbol.getClassAndItsOuterClassesWhenLocal(session) }
|
||||
val newType = components.computeRepresentativeTypeForBareType(type, originalType)
|
||||
?: if (
|
||||
|
||||
Reference in New Issue
Block a user