K2: handle non lookup-tag based types in private-to-this analysis

#KT-62134 Fixed
This commit is contained in:
Mikhail Glukhikh
2024-01-31 12:27:29 +01:00
committed by Space Team
parent 3c3396a87e
commit e1df52bc02
3 changed files with 44 additions and 20 deletions
@@ -355,28 +355,50 @@ class FirStatusResolver(
}
private fun contradictsWith(type: ConeKotlinType, requiredVariance: Variance): Boolean {
if (type is ConeTypeParameterType) {
return !type.lookupTag.typeParameterSymbol.fir.variance.allowsPosition(requiredVariance)
}
// TODO: handle other types (like flexible, DNN, captured, ...) KT-62134
if (type is ConeClassLikeType) {
val classLike = type.lookupTag.toSymbol(session)?.fir
for ((index, argument) in type.typeArguments.withIndex()) {
val typeParameterRef = classLike?.typeParameters?.getOrNull(index)
if (typeParameterRef !is FirTypeParameter) continue
val requiredVarianceForArgument = when (
EnrichedProjectionKind.getEffectiveProjectionKind(typeParameterRef.variance, argument.variance)
) {
EnrichedProjectionKind.OUT -> requiredVariance
EnrichedProjectionKind.IN -> requiredVariance.opposite()
EnrichedProjectionKind.INV -> Variance.INVARIANT
EnrichedProjectionKind.STAR -> continue // CONFLICTING_PROJECTION error was reported
when (type) {
is ConeLookupTagBasedType -> {
if (type is ConeTypeParameterType) {
return !type.lookupTag.typeParameterSymbol.fir.variance.allowsPosition(requiredVariance)
}
val argType = argument.type ?: continue
if (contradictsWith(argType, requiredVarianceForArgument)) {
return true
if (type is ConeClassLikeType) {
val classLike = type.lookupTag.toSymbol(session)?.fir
for ((index, argument) in type.typeArguments.withIndex()) {
val typeParameterRef = classLike?.typeParameters?.getOrNull(index)
if (typeParameterRef !is FirTypeParameter) continue
val requiredVarianceForArgument = when (
EnrichedProjectionKind.getEffectiveProjectionKind(typeParameterRef.variance, argument.variance)
) {
EnrichedProjectionKind.OUT -> requiredVariance
EnrichedProjectionKind.IN -> requiredVariance.opposite()
EnrichedProjectionKind.INV -> Variance.INVARIANT
EnrichedProjectionKind.STAR -> continue // CONFLICTING_PROJECTION error was reported
}
val argType = argument.type ?: continue
if (contradictsWith(argType, requiredVarianceForArgument)) {
return true
}
}
}
}
is ConeFlexibleType -> {
return contradictsWith(type.lowerBound, requiredVariance)
}
is ConeDefinitelyNotNullType -> {
return contradictsWith(type.original, requiredVariance)
}
is ConeIntersectionType -> {
return type.intersectedTypes.any { contradictsWith(it, requiredVariance) }
}
is ConeCapturedType -> {
// Looks like not possible here
return false
}
is ConeIntegerConstantOperatorType,
is ConeIntegerLiteralConstantType,
is ConeStubTypeForChainInference,
is ConeStubTypeForTypeVariableInSubtyping,
is ConeTypeVariableType,
-> return false
}
return false
}
@@ -19,7 +19,8 @@ class Foo<in T> : Base<<!TYPE_VARIANCE_CONFLICT_ERROR!>T<!>>() {
private val flex = foo()
fun bar(f: Foo<Bar>) {
val dnn = f.dnn
val dnn = f.<!INVISIBLE_REFERENCE!>dnn<!>
// This case (and any other with non-denotable type) requires KT-55446 to be fixed
val flex = f.flex
}
}
@@ -20,6 +20,7 @@ class Foo<in T> : Base<<!TYPE_VARIANCE_CONFLICT_ERROR!>T<!>>() {
fun bar(f: Foo<Bar>) {
val dnn = f.<!INVISIBLE_MEMBER!>dnn<!>
// This case (and any other with non-denotable type) requires KT-55446 to be fixed
val flex = f.<!INVISIBLE_MEMBER!>flex<!>
}
}