[FIR] Implement REDUNDANT_PROJECTION diagnostics, rename FirConflictingProjectionChecker -> FirProjectionRelationChecker, fix tests
This commit is contained in:
committed by
teamcityserver
parent
03e577bf98
commit
f081a6b4fa
+12
-12
@@ -7,12 +7,12 @@ fun a2(value: None<in Int>) {}
|
||||
fun a3(value: None<out Int>) {}
|
||||
|
||||
fun a4(value: In<Int>) {}
|
||||
fun a5(value: In<in Int>) {}
|
||||
fun a5(value: In<<!REDUNDANT_PROJECTION!>in<!> Int>) {}
|
||||
fun a6(value: In<<!CONFLICTING_PROJECTION!>out<!> Int>) {}
|
||||
|
||||
fun a7(value: Out<Int>) {}
|
||||
fun a8(value: Out<<!CONFLICTING_PROJECTION!>in<!> Int>) {}
|
||||
fun a9(value: Out<out Int>) {}
|
||||
fun a9(value: Out<<!REDUNDANT_PROJECTION!>out<!> Int>) {}
|
||||
|
||||
typealias A1<K> = None<K>
|
||||
typealias A2<K> = None<in K>
|
||||
@@ -27,28 +27,28 @@ typealias A8<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = None<in K>
|
||||
typealias A9<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = None<out K>
|
||||
|
||||
typealias A10<K> = In<K>
|
||||
typealias A11<K> = In<in K>
|
||||
typealias A11<K> = In<<!REDUNDANT_PROJECTION!>in<!> K>
|
||||
typealias A12<K> = In<<!CONFLICTING_PROJECTION!>out<!> K>
|
||||
|
||||
typealias A13<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = In<K>
|
||||
typealias A14<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = In<in K>
|
||||
typealias A14<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = In<<!REDUNDANT_PROJECTION!>in<!> K>
|
||||
typealias A15<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = In<<!CONFLICTING_PROJECTION!>out<!> K>
|
||||
|
||||
typealias A16<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = In<K>
|
||||
typealias A17<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = In<in K>
|
||||
typealias A17<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = In<<!REDUNDANT_PROJECTION!>in<!> K>
|
||||
typealias A18<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = In<<!CONFLICTING_PROJECTION!>out<!> K>
|
||||
|
||||
typealias A19<K> = Out<K>
|
||||
typealias A20<K> = Out<<!CONFLICTING_PROJECTION!>in<!> K>
|
||||
typealias A21<K> = Out<out K>
|
||||
typealias A21<K> = Out<<!REDUNDANT_PROJECTION!>out<!> K>
|
||||
|
||||
typealias A22<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = Out<K>
|
||||
typealias A23<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = Out<<!CONFLICTING_PROJECTION!>in<!> K>
|
||||
typealias A24<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = Out<out K>
|
||||
typealias A24<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>in<!> K> = Out<<!REDUNDANT_PROJECTION!>out<!> K>
|
||||
|
||||
typealias A25<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = Out<K>
|
||||
typealias A26<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = Out<<!CONFLICTING_PROJECTION!>in<!> K>
|
||||
typealias A27<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = Out<out K>
|
||||
typealias A27<<!VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED!>out<!> K> = Out<<!REDUNDANT_PROJECTION!>out<!> K>
|
||||
|
||||
class Outer<T> {
|
||||
inner class Intermediate<K> {
|
||||
@@ -82,16 +82,16 @@ class InOuter<in T> {
|
||||
|
||||
fun test10(): InOuter<Int>.OutIntermediate<String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
|
||||
fun test11(): InOuter<in Int>.OutIntermediate<String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test11(): InOuter<<!REDUNDANT_PROJECTION!>in<!> Int>.OutIntermediate<String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test12(): InOuter<<!CONFLICTING_PROJECTION!>out<!> Int>.OutIntermediate<String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
|
||||
fun test13(): InOuter<Int>.OutIntermediate<<!CONFLICTING_PROJECTION!>in<!> String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test14(): InOuter<Int>.OutIntermediate<out String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test14(): InOuter<Int>.OutIntermediate<<!REDUNDANT_PROJECTION!>out<!> String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
|
||||
fun test15(): InOuter<Int>.OutIntermediate<String>.InInner<in Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test15(): InOuter<Int>.OutIntermediate<String>.InInner<<!REDUNDANT_PROJECTION!>in<!> Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test16(): InOuter<Int>.OutIntermediate<String>.InInner<<!CONFLICTING_PROJECTION!>out<!> Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
|
||||
fun test17(): InOuter<in Int>.OutIntermediate<out String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test17(): InOuter<<!REDUNDANT_PROJECTION!>in<!> Int>.OutIntermediate<<!REDUNDANT_PROJECTION!>out<!> String>.InInner<Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
fun test18(): InOuter<Int>.OutIntermediate<<!CONFLICTING_PROJECTION!>in<!> String>.InInner<<!CONFLICTING_PROJECTION!>out<!> Char> = InOuter<Int>().OutIntermediate<String>().InInner()
|
||||
|
||||
class TwoParametersOuter<T, in T1> {
|
||||
|
||||
@@ -4,7 +4,7 @@ interface List<out T : Any> {
|
||||
infix fun concat(other: List<<!TYPE_VARIANCE_CONFLICT!>T<!>>): List<T>
|
||||
}
|
||||
|
||||
typealias StringList = List<out String>
|
||||
typealias StringList = List<<!REDUNDANT_PROJECTION!>out<!> String>
|
||||
typealias AnyList = List<*>
|
||||
|
||||
abstract class AbstractList<out T : Any> : List<T>
|
||||
|
||||
@@ -71,13 +71,13 @@ typealias Out1<X> = Out<X>
|
||||
typealias Invariant1<X> = Invariant<X>
|
||||
|
||||
|
||||
fun test_5(a: A, in1: In1<A>, in2: In1<in A>, in3: In1<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>out<!> A>) {
|
||||
fun test_5(a: A, in1: In1<A>, in2: In1<<!REDUNDANT_PROJECTION!>in<!> A>, in3: In1<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>out<!> A>) {
|
||||
in1.take(a)
|
||||
in2.take(a)
|
||||
in3.<!UNRESOLVED_REFERENCE!>take<!>(a)
|
||||
}
|
||||
|
||||
fun test_6(a: A, out1: Out1<A>, out2: Out1<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>in<!> A>, out3: Out1<out A>) {
|
||||
fun test_6(a: A, out1: Out1<A>, out2: Out1<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>in<!> A>, out3: Out1<<!REDUNDANT_PROJECTION!>out<!> A>) {
|
||||
out1.value().foo()
|
||||
out2.<!UNRESOLVED_REFERENCE!>value<!>().foo()
|
||||
out3.value().foo()
|
||||
|
||||
+3
@@ -386,6 +386,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION by error<KtTypeParameter>(PositioningStrategy.VARIANCE_MODIFIER) {
|
||||
parameter<ConeKotlinType>("type")
|
||||
}
|
||||
val REDUNDANT_PROJECTION by warning<KtTypeParameter>(PositioningStrategy.VARIANCE_MODIFIER) {
|
||||
parameter<ConeKotlinType>("type")
|
||||
}
|
||||
val VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED by error<KtTypeParameter>(PositioningStrategy.VARIANCE_MODIFIER)
|
||||
|
||||
val CATCH_PARAMETER_WITH_DEFAULT_VALUE by error<PsiElement>()
|
||||
|
||||
@@ -276,6 +276,7 @@ object FirErrors {
|
||||
val TYPE_PARAMETERS_IN_ENUM by error0<PsiElement>()
|
||||
val CONFLICTING_PROJECTION by error1<KtTypeParameter, ConeKotlinType>(SourceElementPositioningStrategies.VARIANCE_MODIFIER)
|
||||
val CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION by error1<KtTypeParameter, ConeKotlinType>(SourceElementPositioningStrategies.VARIANCE_MODIFIER)
|
||||
val REDUNDANT_PROJECTION by warning1<KtTypeParameter, ConeKotlinType>(SourceElementPositioningStrategies.VARIANCE_MODIFIER)
|
||||
val VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED by error0<KtTypeParameter>(SourceElementPositioningStrategies.VARIANCE_MODIFIER)
|
||||
val CATCH_PARAMETER_WITH_DEFAULT_VALUE by error0<PsiElement>()
|
||||
val REIFIED_TYPE_IN_CATCH_CLAUSE by error0<PsiElement>()
|
||||
|
||||
+1
-2
@@ -15,14 +15,13 @@ import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDelegationInInterfac
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirFunctionTypeParametersSyntaxChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirTypeParameterSyntaxChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirReservedUnderscoreDeclarationChecker
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
|
||||
object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
|
||||
get() = setOf(
|
||||
FirModifierChecker,
|
||||
FirConflictsChecker,
|
||||
FirConflictingProjectionChecker,
|
||||
FirProjectionRelationChecker,
|
||||
FirTypeConstraintsChecker,
|
||||
FirReservedUnderscoreDeclarationChecker
|
||||
)
|
||||
|
||||
+26
-36
@@ -6,8 +6,8 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.extractTypeRefAndSourceFromTypeArgument
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirConflictingProjectionChecker : FirBasicDeclarationChecker() {
|
||||
object FirProjectionRelationChecker : FirBasicDeclarationChecker() {
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (declaration is FirPropertyAccessor) {
|
||||
return
|
||||
@@ -62,16 +62,28 @@ object FirConflictingProjectionChecker : FirBasicDeclarationChecker() {
|
||||
?.symbol?.fir
|
||||
?.variance
|
||||
|
||||
if (
|
||||
(fullyExpandedProjection is ConeKotlinTypeConflictingProjection ||
|
||||
actual is ConeKotlinTypeProjectionIn && protoVariance == Variance.OUT_VARIANCE ||
|
||||
actual is ConeKotlinTypeProjectionOut && protoVariance == Variance.IN_VARIANCE) &&
|
||||
typeRef.source?.kind !is FirFakeSourceElementKind
|
||||
val projectionRelation = if (fullyExpandedProjection is ConeKotlinTypeConflictingProjection ||
|
||||
actual is ConeKotlinTypeProjectionIn && protoVariance == Variance.OUT_VARIANCE ||
|
||||
actual is ConeKotlinTypeProjectionOut && protoVariance == Variance.IN_VARIANCE
|
||||
) {
|
||||
val typeArgSource = extractTypeArgumentSource(typeRef, it)
|
||||
ProjectionRelation.Conflicting
|
||||
} else if (actual is ConeKotlinTypeProjectionIn && protoVariance == Variance.IN_VARIANCE ||
|
||||
actual is ConeKotlinTypeProjectionOut && protoVariance == Variance.OUT_VARIANCE
|
||||
) {
|
||||
ProjectionRelation.Redundant
|
||||
} else {
|
||||
ProjectionRelation.None
|
||||
}
|
||||
|
||||
val (typeArgTypeRef, typeArgSource) = extractTypeRefAndSourceFromTypeArgument(typeRef, it) ?: continue
|
||||
|
||||
if (projectionRelation != ProjectionRelation.None && typeRef.source?.kind !is FirFakeSourceElementKind) {
|
||||
reporter.reportOn(
|
||||
typeArgSource ?: typeRef.source,
|
||||
if (type != fullyExpandedType) FirErrors.CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION else FirErrors.CONFLICTING_PROJECTION,
|
||||
typeArgSource ?: typeArgTypeRef.source,
|
||||
if (projectionRelation == ProjectionRelation.Conflicting)
|
||||
if (type != fullyExpandedType) FirErrors.CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION else FirErrors.CONFLICTING_PROJECTION
|
||||
else
|
||||
FirErrors.REDUNDANT_PROJECTION,
|
||||
fullyExpandedType,
|
||||
context
|
||||
)
|
||||
@@ -79,31 +91,9 @@ object FirConflictingProjectionChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractTypeArgumentSource(typeRef: FirTypeRef, index: Int): FirSourceElement? {
|
||||
if (typeRef is FirResolvedTypeRef) {
|
||||
val delegatedTypeRef = typeRef.delegatedTypeRef
|
||||
if (delegatedTypeRef is FirUserTypeRef) {
|
||||
var currentTypeArguments: List<FirTypeProjection>? = null
|
||||
var currentIndex = index
|
||||
val qualifier = delegatedTypeRef.qualifier
|
||||
|
||||
for (i in qualifier.size - 1 downTo 0) {
|
||||
val typeArguments = qualifier[i].typeArgumentList.typeArguments
|
||||
if (currentIndex < typeArguments.size) {
|
||||
currentTypeArguments = typeArguments
|
||||
break
|
||||
} else {
|
||||
currentIndex -= typeArguments.size
|
||||
}
|
||||
}
|
||||
|
||||
val typeArgument = currentTypeArguments?.elementAtOrNull(currentIndex)
|
||||
if (typeArgument is FirTypeProjectionWithVariance) {
|
||||
return typeArgument.source
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
private enum class ProjectionRelation {
|
||||
Conflicting,
|
||||
Redundant,
|
||||
None
|
||||
}
|
||||
}
|
||||
+6
@@ -254,6 +254,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_EXPLICI
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_OPEN_IN_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_PROJECTION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_RETURN_UNIT_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SETTER_PARAMETER_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE
|
||||
@@ -616,6 +617,11 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
"Conflicting projection in type alias expansion in intermediate type '{0}'",
|
||||
RENDER_TYPE
|
||||
)
|
||||
map.put(
|
||||
REDUNDANT_PROJECTION,
|
||||
"Projection is redundant: the corresponding type parameter of {0} has the same variance",
|
||||
RENDER_TYPE
|
||||
)
|
||||
map.put(
|
||||
VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED,
|
||||
"Variance annotations are only allowed for type parameters of classes and interfaces"
|
||||
|
||||
Vendored
-20
@@ -1,20 +0,0 @@
|
||||
class In<in T>
|
||||
class Out<out T>
|
||||
class Inv<T>
|
||||
class X
|
||||
|
||||
fun f1(p: In<in X>) {}
|
||||
fun f2(p: In<<!CONFLICTING_PROJECTION!>out<!> X>) {}
|
||||
fun f3(p: In<X>) {}
|
||||
|
||||
fun f4(p: Out<out X>) {}
|
||||
fun f5(p: Out<<!CONFLICTING_PROJECTION!>in<!> X>) {}
|
||||
fun f6(p: Out<X>) {}
|
||||
|
||||
fun f6(p: Inv<X>) {}
|
||||
fun f7(p: Inv<in X>) {}
|
||||
fun f8(p: Inv<out X>) {}
|
||||
|
||||
fun f9(p: In<*>) {}
|
||||
fun f10(p: Out<*>) {}
|
||||
fun f11(p: Inv<*>) {}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class In<in T>
|
||||
class Out<out T>
|
||||
class Inv<T>
|
||||
|
||||
+3
-3
@@ -2,11 +2,11 @@ typealias Action<K> = (@UnsafeVariance K) -> Unit
|
||||
typealias Action2<K> = (@UnsafeVariance K) -> K
|
||||
|
||||
data class Tag<L>(val action: Action<L>)
|
||||
data class Tag2<L>(val action: Action<in L>)
|
||||
data class Tag2<L>(val action: Action<<!REDUNDANT_PROJECTION!>in<!> L>)
|
||||
data class Tag3<in L>(val action: Action<L>)
|
||||
data class Tag4<in L>(val action: Action<in L>)
|
||||
data class Tag4<in L>(val action: Action<<!REDUNDANT_PROJECTION!>in<!> L>)
|
||||
data class Tag5<L>(val action: Action2<L>)
|
||||
data class Tag6<out L>(val action: Action<in L>)
|
||||
data class Tag6<out L>(val action: Action<<!REDUNDANT_PROJECTION!>in<!> L>)
|
||||
data class Tag7<out L>(val action: Action<L>)
|
||||
data class Tag8<out L>(val action: Action2<L>)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ fun foo() : G<Point> {
|
||||
|
||||
class Out<out T>() {}
|
||||
|
||||
fun <T> fout(expression : T) : Out<out T> = Out<T>()
|
||||
fun <T> fout(expression : T) : Out<<!REDUNDANT_PROJECTION!>out<!> T> = Out<T>()
|
||||
|
||||
fun fooout() : Out<Point> {
|
||||
val p = Point();
|
||||
|
||||
@@ -5,13 +5,13 @@ class Out<out T>
|
||||
class Inv<T>
|
||||
|
||||
typealias In1<T> = In<T>
|
||||
typealias In2<T> = In<in T>
|
||||
typealias In2<T> = In<<!REDUNDANT_PROJECTION!>in<!> T>
|
||||
typealias In3<T> = In<<!CONFLICTING_PROJECTION!>out<!> T>
|
||||
typealias In4<T> = In<*>
|
||||
|
||||
typealias Out1<T> = Out<T>
|
||||
typealias Out2<T> = Out<<!CONFLICTING_PROJECTION!>in<!> T>
|
||||
typealias Out3<T> = Out<out T>
|
||||
typealias Out3<T> = Out<<!REDUNDANT_PROJECTION!>out<!> T>
|
||||
typealias Out4<T> = Out<*>
|
||||
|
||||
typealias Inv1<T> = Inv<T>
|
||||
@@ -22,12 +22,12 @@ typealias Inv4<T> = Inv<*>
|
||||
val inv1: Inv1<Int> = Inv<Int>()
|
||||
|
||||
fun inInv_Inv(x: In1<Int>) = x
|
||||
fun inInv_In(x: In1<in Int>) = x
|
||||
fun inInv_In(x: In1<<!REDUNDANT_PROJECTION!>in<!> Int>) = x
|
||||
fun inInv_Out(x: In1<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>out<!> Int>) = x
|
||||
fun inInv_Star(x: In1<*>) = x
|
||||
|
||||
fun inIn_Inv(x: In2<Int>) = x
|
||||
fun inIn_In(x: In2<in Int>) = x
|
||||
fun inIn_In(x: In2<<!REDUNDANT_PROJECTION!>in<!> Int>) = x
|
||||
fun inIn_Out(x: In2<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>out<!> Int>) = x
|
||||
fun inIn_Star(x: In2<*>) = x
|
||||
|
||||
@@ -38,7 +38,7 @@ fun inOut_Star(x: In3<*>) = x
|
||||
|
||||
fun outInv_Inv(x: Out1<Int>) = x
|
||||
fun outInv_In(x: Out1<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>in<!> Int>) = x
|
||||
fun outInv_Out(x: Out1<out Int>) = x
|
||||
fun outInv_Out(x: Out1<<!REDUNDANT_PROJECTION!>out<!> Int>) = x
|
||||
fun outInv_Star(x: Out1<*>) = x
|
||||
|
||||
fun outIn_Inv(x: Out2<Int>) = x
|
||||
@@ -48,7 +48,7 @@ fun outIn_Star(x: Out2<*>) = x
|
||||
|
||||
fun outOut_Inv(x: Out3<Int>) = x
|
||||
fun outOut_In(x: Out3<<!CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION!>in<!> Int>) = x
|
||||
fun outOut_Out(x: Out3<out Int>) = x
|
||||
fun outOut_Out(x: Out3<<!REDUNDANT_PROJECTION!>out<!> Int>) = x
|
||||
fun outOut_Star(x: Out3<*>) = x
|
||||
|
||||
fun invInv_Inv(x: Inv1<Int>) = x
|
||||
|
||||
Vendored
+4
-4
@@ -8,11 +8,11 @@ typealias InvOut = Inv<out Int>
|
||||
typealias InvT<T> = Inv<T>
|
||||
|
||||
typealias OutStar = Out<*>
|
||||
typealias OutOut = Out<out Int>
|
||||
typealias OutOut = Out<<!REDUNDANT_PROJECTION!>out<!> Int>
|
||||
typealias OutT<T> = Out<T>
|
||||
|
||||
typealias InStar = In<*>
|
||||
typealias InIn = In<in Int>
|
||||
typealias InIn = In<<!REDUNDANT_PROJECTION!>in<!> Int>
|
||||
typealias InT<T> = In<T>
|
||||
|
||||
class Test1 : InvStar
|
||||
@@ -24,9 +24,9 @@ class Test5 : InvT<InvT<*>>
|
||||
class Test6 : OutStar
|
||||
class Test7 : OutOut
|
||||
class Test8 : OutT<Int>
|
||||
class Test9 : OutT<out Int>
|
||||
class Test9 : OutT<<!REDUNDANT_PROJECTION!>out<!> Int>
|
||||
|
||||
class Test10 : InStar
|
||||
class Test11 : InIn
|
||||
class Test12 : InT<Int>
|
||||
class Test13 : InT<in Int>
|
||||
class Test13 : InT<<!REDUNDANT_PROJECTION!>in<!> Int>
|
||||
|
||||
@@ -2525,7 +2525,7 @@ fun <T> case_37(x: Map<in T, *>?) {
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 38
|
||||
fun <T> case_38(x: Map<*, out T>?) {
|
||||
fun <T> case_38(x: Map<*, <!REDUNDANT_PROJECTION!>out<!> T>?) {
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.Map<*, out T>? & kotlin.collections.Map<*, out T>")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.Map<*, out T>? & kotlin.collections.Map<*, out T>")!>x<!>.equals(null)
|
||||
@@ -2731,7 +2731,7 @@ fun <T> case_40(x: InterfaceWithTwoTypeParameters<in T, in T>?) {
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 41
|
||||
fun <T> case_41(x: Map<out T, out T>?) {
|
||||
fun <T> case_41(x: Map<out T, <!REDUNDANT_PROJECTION!>out<!> T>?) {
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.Map<out T, out T>? & kotlin.collections.Map<out T, out T>")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.Map<out T, out T>? & kotlin.collections.Map<out T, out T>")!>x<!>.equals(null)
|
||||
@@ -2803,7 +2803,7 @@ fun <T> case_41(x: Map<out T, out T>?) {
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 42
|
||||
fun <T> case_42(x: Map<T, out T>?) {
|
||||
fun <T> case_42(x: Map<T, <!REDUNDANT_PROJECTION!>out<!> T>?) {
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.Map<T, out T>? & kotlin.collections.Map<T, out T>")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.Map<T, out T>? & kotlin.collections.Map<T, out T>")!>x<!>.equals(null)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// SKIP_TXT
|
||||
|
||||
// TESTCASE NUMBER: 1
|
||||
fun case_1(x: Out<out Int?>?) {
|
||||
fun case_1(x: Out<<!REDUNDANT_PROJECTION!>out<!> Int?>?) {
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int?>? & Out<out kotlin.Int?>")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int?>? & Out<out kotlin.Int?>")!>x<!>.equals(null)
|
||||
@@ -23,7 +23,7 @@ fun case_1(x: Out<out Int?>?) {
|
||||
* UNEXPECTED BEHAVIOUR
|
||||
* ISSUES: KT-28598
|
||||
*/
|
||||
fun case_2(a: Out<out Out<out Out<out Out<out Out<out Out<out Int?>?>?>?>?>?>?) {
|
||||
fun case_2(a: Out<<!REDUNDANT_PROJECTION!>out<!> Out<out Out<out Out<out Out<out Out<out Int?>?>?>?>?>?>?) {
|
||||
if (a != null) {
|
||||
val b = <!DEBUG_INFO_EXPRESSION_TYPE("Out<out Out<out Out<out Out<out Out<out Out<out kotlin.Int?>?>?>?>?>?>? & Out<out Out<out Out<out Out<out Out<out Out<out kotlin.Int?>?>?>?>?>?>")!>a<!>.get()
|
||||
if (b != null) {
|
||||
@@ -75,7 +75,7 @@ fun case_3(a: Inv<out Int>?) {
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 4
|
||||
fun case_4(a: Out<out Int>?, b: Out<out Int> = if (a != null) <!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int>? & Out<out kotlin.Int>")!>a<!> else Out<Int>()) {
|
||||
fun case_4(a: Out<<!REDUNDANT_PROJECTION!>out<!> Int>?, b: Out<<!REDUNDANT_PROJECTION!>out<!> Int> = if (a != null) <!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int>? & Out<out kotlin.Int>")!>a<!> else Out<Int>()) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int>?")!>a<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int>")!>b<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int>")!>b<!>.equals(null)
|
||||
@@ -90,7 +90,7 @@ fun case_4(a: Out<out Int>?, b: Out<out Int> = if (a != null) <!DEBUG_INFO_EXPRE
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 5
|
||||
val x: Out<out Int>? = null
|
||||
val x: Out<<!REDUNDANT_PROJECTION!>out<!> Int>? = null
|
||||
|
||||
fun case_5() {
|
||||
if (x != null) {
|
||||
@@ -127,7 +127,7 @@ fun case_6() {
|
||||
|
||||
// TESTCASE NUMBER: 7
|
||||
fun case_7() {
|
||||
var x: Out<out Int>? = null
|
||||
var x: Out<<!REDUNDANT_PROJECTION!>out<!> Int>? = null
|
||||
|
||||
if (x != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Out<out kotlin.Int>? & Out<out kotlin.Int>")!>x<!>
|
||||
@@ -469,7 +469,7 @@ fun case_20(a: Inv<out Any?>) {
|
||||
* UNEXPECTED BEHAVIOUR
|
||||
* ISSUES: KT-28785
|
||||
*/
|
||||
fun case_21(a: Out<out Int?>) {
|
||||
fun case_21(a: Out<<!REDUNDANT_PROJECTION!>out<!> Int?>) {
|
||||
if (a.x != null) {
|
||||
a.x
|
||||
a.x.equals(null)
|
||||
@@ -489,7 +489,7 @@ fun case_21(a: Out<out Int?>) {
|
||||
* UNEXPECTED BEHAVIOUR
|
||||
* ISSUES: KT-28785
|
||||
*/
|
||||
fun case_22(a: Out<out Nothing?>) {
|
||||
fun case_22(a: Out<<!REDUNDANT_PROJECTION!>out<!> Nothing?>) {
|
||||
if (a.x != null) {
|
||||
a.x
|
||||
a.x.hashCode()
|
||||
@@ -501,7 +501,7 @@ fun case_22(a: Out<out Nothing?>) {
|
||||
* UNEXPECTED BEHAVIOUR
|
||||
* ISSUES: KT-28785
|
||||
*/
|
||||
fun case_23(a: Out<out Any?>) {
|
||||
fun case_23(a: Out<<!REDUNDANT_PROJECTION!>out<!> Any?>) {
|
||||
if (a.x != null) {
|
||||
a.x
|
||||
a.x.equals(null)
|
||||
|
||||
+7
@@ -1200,6 +1200,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.REDUNDANT_PROJECTION) { firDiagnostic ->
|
||||
RedundantProjectionImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED) { firDiagnostic ->
|
||||
VarianceOnTypeParameterNotAllowedImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
|
||||
+5
@@ -850,6 +850,11 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val type: KtType
|
||||
}
|
||||
|
||||
abstract class RedundantProjection : KtFirDiagnostic<KtTypeParameter>() {
|
||||
override val diagnosticClass get() = RedundantProjection::class
|
||||
abstract val type: KtType
|
||||
}
|
||||
|
||||
abstract class VarianceOnTypeParameterNotAllowed : KtFirDiagnostic<KtTypeParameter>() {
|
||||
override val diagnosticClass get() = VarianceOnTypeParameterNotAllowed::class
|
||||
}
|
||||
|
||||
+8
@@ -1370,6 +1370,14 @@ internal class ConflictingProjectionInTypealiasExpansionImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RedundantProjectionImpl(
|
||||
override val type: KtType,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RedundantProjection(), KtAbstractFirDiagnostic<KtTypeParameter> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class VarianceOnTypeParameterNotAllowedImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user