[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
|
||||
}
|
||||
|
||||
sealed class ConeKotlinTypeProjection : ConeTypeProjection() {
|
||||
abstract val type: ConeKotlinType
|
||||
}
|
||||
|
||||
data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection() {
|
||||
override val kind: ProjectionKind
|
||||
get() = ProjectionKind.IN
|
||||
@@ -50,6 +54,16 @@ data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : Cone
|
||||
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
|
||||
// (more exactly, invariant type projection contains type)
|
||||
sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, TypeArgumentListMarker {
|
||||
@@ -68,17 +82,12 @@ sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, Type
|
||||
final override fun toString(): String {
|
||||
return render()
|
||||
}
|
||||
|
||||
abstract override fun equals(other: Any?): Boolean
|
||||
abstract override fun hashCode(): Int
|
||||
}
|
||||
|
||||
sealed class ConeSimpleKotlinType : ConeKotlinType(), SimpleTypeMarker
|
||||
|
||||
sealed class ConeKotlinTypeProjection : ConeTypeProjection() {
|
||||
abstract val type: ConeKotlinType
|
||||
}
|
||||
|
||||
typealias ConeKotlinErrorType = ConeClassErrorType
|
||||
|
||||
class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLikeLookupTag()
|
||||
@@ -162,7 +171,8 @@ data class ConeCapturedType(
|
||||
val lowerType: ConeKotlinType?,
|
||||
override val nullability: ConeNullability = ConeNullability.NOT_NULL,
|
||||
val constructor: ConeCapturedTypeConstructor,
|
||||
override val attributes: ConeAttributes = ConeAttributes.Empty
|
||||
override val attributes: ConeAttributes = ConeAttributes.Empty,
|
||||
val isProjectionNotNull: Boolean = false
|
||||
) : ConeSimpleKotlinType(), CapturedTypeMarker {
|
||||
constructor(
|
||||
captureStatus: CaptureStatus, lowerType: ConeKotlinType?, projection: ConeTypeProjection,
|
||||
@@ -315,6 +325,13 @@ open class ConeTypeVariable(name: String) : TypeVariableMarker {
|
||||
|
||||
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
|
||||
override val name: Name get() = Name.identifier(debugName)
|
||||
|
||||
var isContainedInInvariantOrContravariantPositions: Boolean = false
|
||||
private set
|
||||
|
||||
fun recordInfoAboutTypeVariableUsagesAsInvariantOrContravariantParameter() {
|
||||
isContainedInInvariantOrContravariantPositions = true
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ConeIntegerLiteralType(
|
||||
|
||||
@@ -12,6 +12,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckExplicitReceiverConsistency,
|
||||
NoTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckLowPriorityInOverloadResolution,
|
||||
@@ -22,6 +23,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
MapArguments,
|
||||
NoTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckArguments,
|
||||
EagerResolveOfCallableReferences
|
||||
)
|
||||
@@ -33,6 +35,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckExplicitReceiverConsistency,
|
||||
MapTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckArguments,
|
||||
@@ -47,6 +50,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckExplicitReceiverConsistency,
|
||||
MapTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckArguments,
|
||||
@@ -58,6 +62,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
DiscriminateSynthetics,
|
||||
NoTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckDispatchReceiver,
|
||||
CheckExtensionReceiver,
|
||||
CheckCallableReferenceExpectedType,
|
||||
@@ -68,6 +73,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
MapArguments,
|
||||
NoTypeArguments,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckArguments,
|
||||
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.render
|
||||
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.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
@@ -201,7 +201,7 @@ class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : Simp
|
||||
val csBuilder = system.getBuilder()
|
||||
val substitutionMap = typeParameters.associateBy({ (it as ConeTypeParameterLookupTag).typeParameterSymbol }) {
|
||||
require(it is ConeTypeParameterLookupTag)
|
||||
val variable = TypeParameterBasedTypeVariable(it.typeParameterSymbol)
|
||||
val variable = ConeTypeParameterBasedTypeVariable(it.typeParameterSymbol)
|
||||
csBuilder.registerVariable(variable)
|
||||
|
||||
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.renderWithType
|
||||
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.model.ConeDeclaredUpperBoundConstraintPosition
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
@@ -115,7 +115,7 @@ private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||
|
||||
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 })
|
||||
|
||||
@@ -123,7 +123,7 @@ private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
||||
csBuilder.registerVariable(freshVariable)
|
||||
}
|
||||
|
||||
fun TypeParameterBasedTypeVariable.addSubtypeConstraint(
|
||||
fun ConeTypeParameterBasedTypeVariable.addSubtypeConstraint(
|
||||
upperBound: ConeKotlinType//,
|
||||
//position: DeclaredUpperBoundConstraintPosition
|
||||
) {
|
||||
|
||||
@@ -251,7 +251,7 @@ internal object PostponedVariablesInitializerResolutionStage : ResolutionStage()
|
||||
|
||||
for (freshVariable in candidate.freshVariables) {
|
||||
if (candidate.csBuilder.isPostponedTypeVariable(freshVariable)) continue
|
||||
if (freshVariable !is TypeParameterBasedTypeVariable) continue
|
||||
if (freshVariable !is ConeTypeParameterBasedTypeVariable) continue
|
||||
val typeParameterSymbol = freshVariable.typeParameterSymbol
|
||||
val typeHasVariable = receiverType.contains {
|
||||
(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.ConeFixVariableConstraintPosition
|
||||
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.coneTypeSafe
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext
|
||||
@@ -38,7 +37,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
|
||||
}
|
||||
|
||||
override fun TypeVariableMarker.isReified(): Boolean {
|
||||
return this is TypeParameterBasedTypeVariable && typeParameterSymbol.fir.isReified
|
||||
return this is ConeTypeParameterBasedTypeVariable && typeParameterSymbol.fir.isReified
|
||||
}
|
||||
|
||||
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.types.ConeTypeVariable
|
||||
|
||||
class TypeParameterBasedTypeVariable(val typeParameterSymbol: FirTypeParameterSymbol) :
|
||||
ConeTypeVariable(typeParameterSymbol.name.identifier)
|
||||
class ConeTypeParameterBasedTypeVariable(val typeParameterSymbol: FirTypeParameterSymbol) :
|
||||
ConeTypeVariable(typeParameterSymbol.name.identifier)
|
||||
@@ -295,12 +295,12 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
|
||||
override fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker {
|
||||
require(this is ConeCapturedType)
|
||||
return this // TODO
|
||||
return ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes, isProjectionNotNull = true)
|
||||
}
|
||||
|
||||
override fun CapturedTypeMarker.isProjectionNotNull(): Boolean {
|
||||
require(this is ConeCapturedType)
|
||||
return false // TODO
|
||||
return isProjectionNotNull
|
||||
}
|
||||
|
||||
override fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker {
|
||||
@@ -339,7 +339,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
}
|
||||
|
||||
override fun TypeVariableTypeConstructorMarker.isContainedInInvariantOrContravariantPositions(): Boolean {
|
||||
return false
|
||||
require(this is ConeTypeVariableTypeConstructor)
|
||||
return isContainedInInvariantOrContravariantPositions
|
||||
}
|
||||
|
||||
override fun createErrorType(debugName: String): ConeClassErrorType {
|
||||
|
||||
+2
-2
@@ -140,8 +140,8 @@ class Main<L>(x: L?, y: L) {
|
||||
val x120 = foo12(x!!)
|
||||
val x121 = foo12(y!!)
|
||||
|
||||
val x122 = foo12(x)
|
||||
val x123 = foo12(y)
|
||||
val x122 = <!INAPPLICABLE_CANDIDATE!>foo12<!>(x)
|
||||
val x123 = <!INAPPLICABLE_CANDIDATE!>foo12<!>(y)
|
||||
|
||||
val x133 = Foo13(x).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
|
||||
|
||||
class Inv<T>(val x: T?)
|
||||
|
||||
+1
-1
@@ -13,4 +13,4 @@ class Foo {
|
||||
|
||||
operator fun setValue(thisRef: Foo, property: KProperty<*>, value: T) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user