FIR inference: implement simple constraint system properly
This commit is contained in:
committed by
Mikhail Glukhikh
parent
ddb08777d9
commit
b02b090bdf
+27
-3
@@ -8,7 +8,10 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||||
import org.jetbrains.kotlin.resolve.OverloadabilitySpecificityCallbacks
|
import org.jetbrains.kotlin.resolve.OverloadabilitySpecificityCallbacks
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||||
@@ -21,6 +24,7 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
|||||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
|
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
|
||||||
class ConeOverloadConflictResolver(
|
class ConeOverloadConflictResolver(
|
||||||
val specificityComparator: TypeSpecificityComparator,
|
val specificityComparator: TypeSpecificityComparator,
|
||||||
@@ -73,7 +77,8 @@ class ConeOverloadConflictResolver(
|
|||||||
return FlatSignature(
|
return FlatSignature(
|
||||||
call,
|
call,
|
||||||
function.typeParameters.map { it.symbol },
|
function.typeParameters.map { it.symbol },
|
||||||
call.argumentMapping!!.map { it.value.returnTypeRef.coneTypeUnsafe() },
|
listOfNotNull<ConeKotlinType>(function.receiverTypeRef?.coneTypeUnsafe()) +
|
||||||
|
call.argumentMapping!!.map { it.value.returnTypeRef.coneTypeUnsafe() },
|
||||||
function.receiverTypeRef != null,
|
function.receiverTypeRef != null,
|
||||||
function.valueParameters.any { it.isVararg },
|
function.valueParameters.any { it.isVararg },
|
||||||
function.valueParameters.count { it.defaultValue != null },
|
function.valueParameters.count { it.defaultValue != null },
|
||||||
@@ -199,8 +204,24 @@ class ConeOverloadConflictResolver(
|
|||||||
object NoSubstitutor : TypeSubstitutorMarker
|
object NoSubstitutor : TypeSubstitutorMarker
|
||||||
|
|
||||||
class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : SimpleConstraintSystem {
|
class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : SimpleConstraintSystem {
|
||||||
override fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutorMarker {
|
override fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutorMarker = with(context) {
|
||||||
return NoSubstitutor
|
val csBuilder = system.getBuilder()
|
||||||
|
val substitutionMap = typeParameters.associate {
|
||||||
|
require(it is FirTypeParameterSymbol)
|
||||||
|
val variable = TypeParameterBasedTypeVariable(it)
|
||||||
|
csBuilder.registerVariable(variable)
|
||||||
|
|
||||||
|
|
||||||
|
it to variable.defaultType
|
||||||
|
}
|
||||||
|
val substitutor = ConeSubstitutorByMap(substitutionMap.cast())
|
||||||
|
for (typeParameter in typeParameters) {
|
||||||
|
require(typeParameter is FirTypeParameterSymbol)
|
||||||
|
for (upperBound in typeParameter.fir.bounds) {
|
||||||
|
addSubtypeConstraint(substitutionMap[typeParameter]!!, substitutor.substituteOrSelf(upperBound.coneTypeUnsafe()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return substitutor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) {
|
override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) {
|
||||||
@@ -209,6 +230,9 @@ class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : Simp
|
|||||||
|
|
||||||
override fun hasContradiction(): Boolean = system.hasContradiction
|
override fun hasContradiction(): Boolean = system.hasContradiction
|
||||||
|
|
||||||
|
override val captureFromArgument: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
override val context: TypeSystemInferenceExtensionContext
|
override val context: TypeSystemInferenceExtensionContext
|
||||||
get() = system
|
get() = system
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -10,9 +10,10 @@ import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
|
|
||||||
|
|
||||||
interface ConeSubstitutor {
|
interface ConeSubstitutor : TypeSubstitutorMarker {
|
||||||
fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType
|
fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType
|
||||||
fun substituteOrNull(type: ConeKotlinType): ConeKotlinType?
|
fun substituteOrNull(type: ConeKotlinType): ConeKotlinType?
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ FILE: components.kt
|
|||||||
lval y: R|kotlin/String| = R|<local>/<destruct>|.R|/D.component2|()
|
lval y: R|kotlin/String| = R|<local>/<destruct>|.R|/D.component2|()
|
||||||
}
|
}
|
||||||
|
|
||||||
lval <destruct>: <ERROR TYPE REF: Ambiguity: first, [kotlin/collections/first, kotlin/collections/first]> = R|<local>/list|.<Ambiguity: first, [kotlin/collections/first, kotlin/collections/first]>#()
|
lval <destruct>: R|D| = R|<local>/list|.R|kotlin/collections/first|<R|D|>()
|
||||||
lval x: <ERROR TYPE REF: Ambiguity: component1, [kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1, kotlin/collections/component1]> = R|<local>/<destruct>|.component1()
|
lval x: R|kotlin/Int| = R|<local>/<destruct>|.R|/D.component1|()
|
||||||
lval y: <ERROR TYPE REF: Ambiguity: component2, [kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2, kotlin/collections/component2]> = R|<local>/<destruct>|.component2()
|
lval y: R|kotlin/String| = R|<local>/<destruct>|.R|/D.component2|()
|
||||||
R|<local>/list|.R|kotlin/collections/forEach|<R|D|>(<L> = forEach@fun <anonymous>(<destruct>: R|D|): R|kotlin/Unit| {
|
R|<local>/list|.R|kotlin/collections/forEach|<R|D|>(<L> = forEach@fun <anonymous>(<destruct>: R|D|): R|kotlin/Unit| {
|
||||||
lval x: R|kotlin/Int| = R|<local>/<destruct>|.R|/D.component1|()
|
lval x: R|kotlin/Int| = R|<local>/<destruct>|.R|/D.component1|()
|
||||||
lval y: R|kotlin/String| = R|<local>/<destruct>|.R|/D.component2|()
|
lval y: R|kotlin/String| = R|<local>/<destruct>|.R|/D.component2|()
|
||||||
|
|||||||
Reference in New Issue
Block a user