[FIR] Properly handle that type variable is contained in inv or contravar positions
#KT-45344 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
3d1f4b8386
commit
6cc3fff48d
@@ -40,6 +40,10 @@ object ConeStarProjection : ConeTypeProjection() {
|
|||||||
get() = ProjectionKind.STAR
|
get() = ProjectionKind.STAR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class ConeKotlinTypeProjection : ConeTypeProjection() {
|
||||||
|
abstract val type: ConeKotlinType
|
||||||
|
}
|
||||||
|
|
||||||
data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection() {
|
data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection() {
|
||||||
override val kind: ProjectionKind
|
override val kind: ProjectionKind
|
||||||
get() = ProjectionKind.IN
|
get() = ProjectionKind.IN
|
||||||
@@ -50,6 +54,16 @@ data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : Cone
|
|||||||
get() = ProjectionKind.OUT
|
get() = ProjectionKind.OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ConeTypeProjection.type: ConeKotlinType?
|
||||||
|
get() = when (this) {
|
||||||
|
ConeStarProjection -> null
|
||||||
|
is ConeKotlinTypeProjection -> type
|
||||||
|
is ConeKotlinType -> this
|
||||||
|
}
|
||||||
|
|
||||||
|
val ConeTypeProjection.isStarProjection: Boolean
|
||||||
|
get() = this == ConeStarProjection
|
||||||
|
|
||||||
// We assume type IS an invariant type projection to prevent additional wrapper here
|
// We assume type IS an invariant type projection to prevent additional wrapper here
|
||||||
// (more exactly, invariant type projection contains type)
|
// (more exactly, invariant type projection contains type)
|
||||||
sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, TypeArgumentListMarker {
|
sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, TypeArgumentListMarker {
|
||||||
@@ -68,17 +82,12 @@ sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, Type
|
|||||||
final override fun toString(): String {
|
final override fun toString(): String {
|
||||||
return render()
|
return render()
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract override fun equals(other: Any?): Boolean
|
abstract override fun equals(other: Any?): Boolean
|
||||||
abstract override fun hashCode(): Int
|
abstract override fun hashCode(): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ConeSimpleKotlinType : ConeKotlinType(), SimpleTypeMarker
|
sealed class ConeSimpleKotlinType : ConeKotlinType(), SimpleTypeMarker
|
||||||
|
|
||||||
sealed class ConeKotlinTypeProjection : ConeTypeProjection() {
|
|
||||||
abstract val type: ConeKotlinType
|
|
||||||
}
|
|
||||||
|
|
||||||
typealias ConeKotlinErrorType = ConeClassErrorType
|
typealias ConeKotlinErrorType = ConeClassErrorType
|
||||||
|
|
||||||
class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLikeLookupTag()
|
class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLikeLookupTag()
|
||||||
@@ -162,7 +171,8 @@ data class ConeCapturedType(
|
|||||||
val lowerType: ConeKotlinType?,
|
val lowerType: ConeKotlinType?,
|
||||||
override val nullability: ConeNullability = ConeNullability.NOT_NULL,
|
override val nullability: ConeNullability = ConeNullability.NOT_NULL,
|
||||||
val constructor: ConeCapturedTypeConstructor,
|
val constructor: ConeCapturedTypeConstructor,
|
||||||
override val attributes: ConeAttributes = ConeAttributes.Empty
|
override val attributes: ConeAttributes = ConeAttributes.Empty,
|
||||||
|
val isProjectionNotNull: Boolean = false
|
||||||
) : ConeSimpleKotlinType(), CapturedTypeMarker {
|
) : ConeSimpleKotlinType(), CapturedTypeMarker {
|
||||||
constructor(
|
constructor(
|
||||||
captureStatus: CaptureStatus, lowerType: ConeKotlinType?, projection: ConeTypeProjection,
|
captureStatus: CaptureStatus, lowerType: ConeKotlinType?, projection: ConeTypeProjection,
|
||||||
@@ -315,6 +325,13 @@ open class ConeTypeVariable(name: String) : TypeVariableMarker {
|
|||||||
|
|
||||||
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
|
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
|
||||||
override val name: Name get() = Name.identifier(debugName)
|
override val name: Name get() = Name.identifier(debugName)
|
||||||
|
|
||||||
|
var isContainedInInvariantOrContravariantPositions: Boolean = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter() {
|
||||||
|
isContainedInInvariantOrContravariantPositions = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ConeIntegerLiteralType(
|
abstract class ConeIntegerLiteralType(
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
CheckExplicitReceiverConsistency,
|
CheckExplicitReceiverConsistency,
|
||||||
NoTypeArguments,
|
NoTypeArguments,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
CollectTypeVariableUsagesInfo,
|
||||||
CheckDispatchReceiver,
|
CheckDispatchReceiver,
|
||||||
CheckExtensionReceiver,
|
CheckExtensionReceiver,
|
||||||
CheckLowPriorityInOverloadResolution,
|
CheckLowPriorityInOverloadResolution,
|
||||||
@@ -22,6 +23,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
MapArguments,
|
MapArguments,
|
||||||
NoTypeArguments,
|
NoTypeArguments,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
CollectTypeVariableUsagesInfo,
|
||||||
CheckArguments,
|
CheckArguments,
|
||||||
EagerResolveOfCallableReferences
|
EagerResolveOfCallableReferences
|
||||||
)
|
)
|
||||||
@@ -33,6 +35,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
CheckExplicitReceiverConsistency,
|
CheckExplicitReceiverConsistency,
|
||||||
MapTypeArguments,
|
MapTypeArguments,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
CollectTypeVariableUsagesInfo,
|
||||||
CheckDispatchReceiver,
|
CheckDispatchReceiver,
|
||||||
CheckExtensionReceiver,
|
CheckExtensionReceiver,
|
||||||
CheckArguments,
|
CheckArguments,
|
||||||
@@ -47,6 +50,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
CheckExplicitReceiverConsistency,
|
CheckExplicitReceiverConsistency,
|
||||||
MapTypeArguments,
|
MapTypeArguments,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
CollectTypeVariableUsagesInfo,
|
||||||
CheckDispatchReceiver,
|
CheckDispatchReceiver,
|
||||||
CheckExtensionReceiver,
|
CheckExtensionReceiver,
|
||||||
CheckArguments,
|
CheckArguments,
|
||||||
@@ -58,6 +62,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
DiscriminateSynthetics,
|
DiscriminateSynthetics,
|
||||||
NoTypeArguments,
|
NoTypeArguments,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
CollectTypeVariableUsagesInfo,
|
||||||
CheckDispatchReceiver,
|
CheckDispatchReceiver,
|
||||||
CheckExtensionReceiver,
|
CheckExtensionReceiver,
|
||||||
CheckCallableReferenceExpectedType,
|
CheckCallableReferenceExpectedType,
|
||||||
@@ -68,6 +73,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
MapArguments,
|
MapArguments,
|
||||||
NoTypeArguments,
|
NoTypeArguments,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
CollectTypeVariableUsagesInfo,
|
||||||
CheckArguments,
|
CheckArguments,
|
||||||
EagerResolveOfCallableReferences
|
EagerResolveOfCallableReferences
|
||||||
)
|
)
|
||||||
|
|||||||
+184
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeDeclaredUpperBoundConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||||
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
|
object CollectTypeVariableUsagesInfo : ResolutionStage() {
|
||||||
|
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||||
|
val candidateSymbol = candidate.symbol
|
||||||
|
if (candidateSymbol is FirConstructorSymbol) {
|
||||||
|
val typeParameters = candidateSymbol.fir.typeParameters
|
||||||
|
for (variable in candidate.freshVariables) {
|
||||||
|
if (variable !is ConeTypeParameterBasedTypeVariable) continue
|
||||||
|
if (isContainedInInvariantOrContravariantPositionsAmongTypeParameters(variable, typeParameters)) {
|
||||||
|
variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (candidateSymbol is FirCallableSymbol) {
|
||||||
|
val session = context.session
|
||||||
|
for (variable in candidate.freshVariables) {
|
||||||
|
if (variable !is ConeTypeParameterBasedTypeVariable) continue
|
||||||
|
if (candidate.system.isContainedInInvariantOrContravariantPositionsWithDependencies(session, variable, candidateSymbol)) {
|
||||||
|
variable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isContainedInInvariantOrContravariantPositionsAmongTypeParameters(
|
||||||
|
checkingTypeVariable: ConeTypeParameterBasedTypeVariable,
|
||||||
|
typeParameters: List<FirTypeParameterRef>
|
||||||
|
): Boolean = typeParameters.any {
|
||||||
|
it.symbol.fir.variance != Variance.OUT_VARIANCE && it.symbol == checkingTypeVariable.typeParameterSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun NewConstraintSystemImpl.isContainedInInvariantOrContravariantPositions(
|
||||||
|
session: FirSession,
|
||||||
|
variableTypeConstructor: ConeTypeVariableTypeConstructor,
|
||||||
|
baseType: ConeKotlinType,
|
||||||
|
wasOutVariance: Boolean = true
|
||||||
|
): Boolean {
|
||||||
|
if (baseType !is ConeClassLikeType) return false
|
||||||
|
val dependentTypeParameter = getTypeParameterByVariable(variableTypeConstructor) ?: return false
|
||||||
|
val declaration = baseType.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return false
|
||||||
|
val declaredTypeParameters = declaration.typeParameters
|
||||||
|
|
||||||
|
if (declaredTypeParameters.size < baseType.typeArguments.size) return false
|
||||||
|
|
||||||
|
for ((argumentsIndex, argument) in baseType.typeArguments.withIndex()) {
|
||||||
|
val argumentType = argument.type ?: continue
|
||||||
|
if (argumentType.isMarkedNullable) continue
|
||||||
|
|
||||||
|
val currentEffectiveVariance =
|
||||||
|
declaredTypeParameters[argumentsIndex].symbol.fir.variance == Variance.OUT_VARIANCE || argument.kind == ProjectionKind.OUT
|
||||||
|
val effectiveVarianceFromTopLevel = wasOutVariance && currentEffectiveVariance
|
||||||
|
|
||||||
|
val argumentTypeConstructor = argumentType.typeConstructor()
|
||||||
|
if ((argumentTypeConstructor == dependentTypeParameter || argumentTypeConstructor == variableTypeConstructor) && !effectiveVarianceFromTopLevel)
|
||||||
|
return true
|
||||||
|
|
||||||
|
if (
|
||||||
|
isContainedInInvariantOrContravariantPositions(
|
||||||
|
session,
|
||||||
|
variableTypeConstructor,
|
||||||
|
argumentType,
|
||||||
|
effectiveVarianceFromTopLevel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun NewConstraintSystemImpl.isContainedInInvariantOrContravariantPositionsWithDependencies(
|
||||||
|
session: FirSession,
|
||||||
|
variable: ConeTypeParameterBasedTypeVariable,
|
||||||
|
candidateSymbol: FirCallableSymbol<*>
|
||||||
|
): Boolean {
|
||||||
|
val returnType = candidateSymbol.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: return false
|
||||||
|
|
||||||
|
val typeVariableConstructor = variable.typeConstructor
|
||||||
|
if (isContainedInInvariantOrContravariantPositions(session, typeVariableConstructor, returnType)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
val dependingOnTypeParameter = getDependingOnTypeParameter(typeVariableConstructor)
|
||||||
|
if (dependingOnTypeParameter.any { isContainedInInvariantOrContravariantPositions(session, it, returnType) }) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
val dependentTypeParameters = getDependentTypeParameters(typeVariableConstructor)
|
||||||
|
if (dependentTypeParameters.any { isContainedInInvariantOrContravariantPositions(session, it.first, returnType) }) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isContainedInInvariantOrContravariantPositionsAmongUpperBound(session, typeVariableConstructor, dependentTypeParameters)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return dependentTypeParameters.any { (typeParameter, _) ->
|
||||||
|
returnType.contains {
|
||||||
|
it.typeConstructor(asConstraintSystemCompleterContext()) == getTypeParameterByVariable(typeParameter) && !it.isMarkedNullable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun NewConstraintSystemImpl.getDependentTypeParameters(
|
||||||
|
variable: TypeConstructorMarker,
|
||||||
|
dependentTypeParametersSeen: List<Pair<TypeConstructorMarker, ConeKotlinType?>> = listOf()
|
||||||
|
): List<Pair<ConeTypeVariableTypeConstructor, ConeKotlinType?>> = with(asConstraintSystemCompleterContext()) {
|
||||||
|
val dependentTypeParameters = getBuilder().currentStorage().notFixedTypeVariables.asSequence()
|
||||||
|
.flatMap { (typeConstructor, constraints) ->
|
||||||
|
require(typeConstructor is ConeTypeVariableTypeConstructor)
|
||||||
|
val upperBounds = constraints.constraints.filter {
|
||||||
|
it.position.from is ConeDeclaredUpperBoundConstraintPosition && it.kind == ConstraintKind.UPPER
|
||||||
|
}
|
||||||
|
|
||||||
|
upperBounds.mapNotNull { constraint ->
|
||||||
|
if (constraint.type.typeConstructor() != variable) {
|
||||||
|
val suitableUpperBound = upperBounds.find { upperBound ->
|
||||||
|
upperBound.type.contains { it.typeConstructor() == variable }
|
||||||
|
}?.type as ConeKotlinType?
|
||||||
|
|
||||||
|
if (suitableUpperBound != null) typeConstructor to suitableUpperBound else null
|
||||||
|
} else typeConstructor to null
|
||||||
|
}
|
||||||
|
}.filter { it !in dependentTypeParametersSeen && it.first != variable }.toList()
|
||||||
|
|
||||||
|
return dependentTypeParameters + dependentTypeParameters.flatMapTo(SmartList()) { (typeConstructor, _) ->
|
||||||
|
if (typeConstructor != variable) {
|
||||||
|
getDependentTypeParameters(typeConstructor, dependentTypeParameters + dependentTypeParametersSeen)
|
||||||
|
} else emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun NewConstraintSystemImpl.isContainedInInvariantOrContravariantPositionsAmongUpperBound(
|
||||||
|
session: FirSession,
|
||||||
|
checkingType: ConeTypeVariableTypeConstructor,
|
||||||
|
dependentTypeParameters: List<Pair<ConeTypeVariableTypeConstructor, ConeKotlinType?>>
|
||||||
|
): Boolean {
|
||||||
|
var currentTypeParameterConstructor = checkingType
|
||||||
|
|
||||||
|
return dependentTypeParameters.any { (typeConstructor, upperBound) ->
|
||||||
|
val isContainedOrNoUpperBound =
|
||||||
|
upperBound == null || isContainedInInvariantOrContravariantPositions(session, currentTypeParameterConstructor, upperBound)
|
||||||
|
currentTypeParameterConstructor = typeConstructor
|
||||||
|
isContainedOrNoUpperBound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun NewConstraintSystemImpl.getTypeParameterByVariable(typeConstructor: ConeTypeVariableTypeConstructor): TypeConstructorMarker? =
|
||||||
|
(getBuilder().currentStorage().allTypeVariables[typeConstructor] as? ConeTypeParameterBasedTypeVariable)?.typeParameterSymbol?.toLookupTag()
|
||||||
|
|
||||||
|
private fun NewConstraintSystemImpl.getDependingOnTypeParameter(variable: TypeConstructorMarker): List<ConeTypeVariableTypeConstructor> =
|
||||||
|
with(asConstraintSystemCompleterContext()) {
|
||||||
|
getBuilder().currentStorage().notFixedTypeVariables[variable]?.constraints?.mapNotNull {
|
||||||
|
if (it.position.from is ConeDeclaredUpperBoundConstraintPosition && it.kind == ConstraintKind.UPPER) {
|
||||||
|
it.type.typeConstructor() as? ConeTypeVariableTypeConstructor
|
||||||
|
} else null
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeTypeVariable.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter() {
|
||||||
|
this.typeConstructor.recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.declarations.modality
|
import org.jetbrains.kotlin.fir.declarations.modality
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.TypeParameterBasedTypeVariable
|
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
@@ -201,7 +201,7 @@ class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : Simp
|
|||||||
val csBuilder = system.getBuilder()
|
val csBuilder = system.getBuilder()
|
||||||
val substitutionMap = typeParameters.associateBy({ (it as ConeTypeParameterLookupTag).typeParameterSymbol }) {
|
val substitutionMap = typeParameters.associateBy({ (it as ConeTypeParameterLookupTag).typeParameterSymbol }) {
|
||||||
require(it is ConeTypeParameterLookupTag)
|
require(it is ConeTypeParameterLookupTag)
|
||||||
val variable = TypeParameterBasedTypeVariable(it.typeParameterSymbol)
|
val variable = ConeTypeParameterBasedTypeVariable(it.typeParameterSymbol)
|
||||||
csBuilder.registerVariable(variable)
|
csBuilder.registerVariable(variable)
|
||||||
|
|
||||||
variable.defaultType
|
variable.defaultType
|
||||||
|
|||||||
+3
-3
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
||||||
import org.jetbrains.kotlin.fir.renderWithType
|
import org.jetbrains.kotlin.fir.renderWithType
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.TypeParameterBasedTypeVariable
|
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeDeclaredUpperBoundConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeDeclaredUpperBoundConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
@@ -115,7 +115,7 @@ private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
|||||||
|
|
||||||
val typeParameters = declaration.typeParameters
|
val typeParameters = declaration.typeParameters
|
||||||
|
|
||||||
val freshTypeVariables = typeParameters.map { TypeParameterBasedTypeVariable(it.symbol) }
|
val freshTypeVariables = typeParameters.map { ConeTypeParameterBasedTypeVariable(it.symbol) }
|
||||||
|
|
||||||
val toFreshVariables = substitutorByMap(freshTypeVariables.associate { it.typeParameterSymbol to it.defaultType })
|
val toFreshVariables = substitutorByMap(freshTypeVariables.associate { it.typeParameterSymbol to it.defaultType })
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
|||||||
csBuilder.registerVariable(freshVariable)
|
csBuilder.registerVariable(freshVariable)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TypeParameterBasedTypeVariable.addSubtypeConstraint(
|
fun ConeTypeParameterBasedTypeVariable.addSubtypeConstraint(
|
||||||
upperBound: ConeKotlinType//,
|
upperBound: ConeKotlinType//,
|
||||||
//position: DeclaredUpperBoundConstraintPosition
|
//position: DeclaredUpperBoundConstraintPosition
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ internal object PostponedVariablesInitializerResolutionStage : ResolutionStage()
|
|||||||
|
|
||||||
for (freshVariable in candidate.freshVariables) {
|
for (freshVariable in candidate.freshVariables) {
|
||||||
if (candidate.csBuilder.isPostponedTypeVariable(freshVariable)) continue
|
if (candidate.csBuilder.isPostponedTypeVariable(freshVariable)) continue
|
||||||
if (freshVariable !is TypeParameterBasedTypeVariable) continue
|
if (freshVariable !is ConeTypeParameterBasedTypeVariable) continue
|
||||||
val typeParameterSymbol = freshVariable.typeParameterSymbol
|
val typeParameterSymbol = freshVariable.typeParameterSymbol
|
||||||
val typeHasVariable = receiverType.contains {
|
val typeHasVariable = receiverType.contains {
|
||||||
(it as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol == typeParameterSymbol
|
(it as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol == typeParameterSymbol
|
||||||
|
|||||||
+1
-2
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
|||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext
|
||||||
@@ -38,7 +37,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun TypeVariableMarker.isReified(): Boolean {
|
override fun TypeVariableMarker.isReified(): Boolean {
|
||||||
return this is TypeParameterBasedTypeVariable && typeParameterSymbol.fir.isReified
|
return this is ConeTypeParameterBasedTypeVariable && typeParameterSymbol.fir.isReified
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.refineType(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.refineType(): KotlinTypeMarker {
|
||||||
|
|||||||
+2
-2
@@ -8,5 +8,5 @@ package org.jetbrains.kotlin.fir.resolve.inference
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
||||||
|
|
||||||
class TypeParameterBasedTypeVariable(val typeParameterSymbol: FirTypeParameterSymbol) :
|
class ConeTypeParameterBasedTypeVariable(val typeParameterSymbol: FirTypeParameterSymbol) :
|
||||||
ConeTypeVariable(typeParameterSymbol.name.identifier)
|
ConeTypeVariable(typeParameterSymbol.name.identifier)
|
||||||
@@ -295,12 +295,12 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
|
|
||||||
override fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker {
|
override fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker {
|
||||||
require(this is ConeCapturedType)
|
require(this is ConeCapturedType)
|
||||||
return this // TODO
|
return ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes, isProjectionNotNull = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun CapturedTypeMarker.isProjectionNotNull(): Boolean {
|
override fun CapturedTypeMarker.isProjectionNotNull(): Boolean {
|
||||||
require(this is ConeCapturedType)
|
require(this is ConeCapturedType)
|
||||||
return false // TODO
|
return isProjectionNotNull
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker {
|
override fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker {
|
||||||
@@ -339,7 +339,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun TypeVariableTypeConstructorMarker.isContainedInInvariantOrContravariantPositions(): Boolean {
|
override fun TypeVariableTypeConstructorMarker.isContainedInInvariantOrContravariantPositions(): Boolean {
|
||||||
return false
|
require(this is ConeTypeVariableTypeConstructor)
|
||||||
|
return isContainedInInvariantOrContravariantPositions
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createErrorType(debugName: String): ConeClassErrorType {
|
override fun createErrorType(debugName: String): ConeClassErrorType {
|
||||||
|
|||||||
+2
-2
@@ -140,8 +140,8 @@ class Main<L>(x: L?, y: L) {
|
|||||||
val x120 = foo12(x!!)
|
val x120 = foo12(x!!)
|
||||||
val x121 = foo12(y!!)
|
val x121 = foo12(y!!)
|
||||||
|
|
||||||
val x122 = foo12(x)
|
val x122 = <!INAPPLICABLE_CANDIDATE!>foo12<!>(x)
|
||||||
val x123 = foo12(y)
|
val x123 = <!INAPPLICABLE_CANDIDATE!>foo12<!>(y)
|
||||||
|
|
||||||
val x133 = Foo13(x).foo1(y)
|
val x133 = Foo13(x).foo1(y)
|
||||||
val x135 = Foo13(y).foo1(y)
|
val x135 = Foo13(y).foo1(y)
|
||||||
|
|||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -UNUSED_VARIABLE
|
|
||||||
|
|
||||||
class Inv<T>(val x: T?)
|
|
||||||
|
|
||||||
fun <K> create(y: K) = Inv(y)
|
|
||||||
fun <K> createPrivate(y: K) = Inv(y)
|
|
||||||
|
|
||||||
fun takeInvInt(i: Inv<Int>) {}
|
|
||||||
|
|
||||||
fun <S> test(i: Int, s: S) {
|
|
||||||
val a = Inv(s)
|
|
||||||
|
|
||||||
a
|
|
||||||
|
|
||||||
val b = create(i)
|
|
||||||
|
|
||||||
b
|
|
||||||
|
|
||||||
val c = createPrivate(i)
|
|
||||||
|
|
||||||
c
|
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>takeInvInt<!>(create(i))
|
|
||||||
}
|
|
||||||
Vendored
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -UNUSED_VARIABLE
|
||||||
|
|
||||||
class Inv<T>(val x: T?)
|
class Inv<T>(val x: T?)
|
||||||
|
|||||||
+1
-1
@@ -13,4 +13,4 @@ class Foo {
|
|||||||
|
|
||||||
operator fun setValue(thisRef: Foo, property: KProperty<*>, value: T) {}
|
operator fun setValue(thisRef: Foo, property: KProperty<*>, value: T) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user