diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingProjection.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingProjection.kt index 6a8c9c63771..7420d066b10 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingProjection.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingProjection.kt @@ -7,12 +7,12 @@ fun a2(value: None) {} fun a3(value: None) {} fun a4(value: In) {} -fun a5(value: In) {} +fun a5(value: In<in Int>) {} fun a6(value: In<out Int>) {} fun a7(value: Out) {} fun a8(value: Out<in Int>) {} -fun a9(value: Out) {} +fun a9(value: Out<out Int>) {} typealias A1 = None typealias A2 = None @@ -27,28 +27,28 @@ typealias A8<out K> = None typealias A9<out K> = None typealias A10 = In -typealias A11 = In +typealias A11 = In<in K> typealias A12 = In<out K> typealias A13<in K> = In -typealias A14<in K> = In +typealias A14<in K> = In<in K> typealias A15<in K> = In<out K> typealias A16<out K> = In -typealias A17<out K> = In +typealias A17<out K> = In<in K> typealias A18<out K> = In<out K> typealias A19 = Out typealias A20 = Out<in K> -typealias A21 = Out +typealias A21 = Out<out K> typealias A22<in K> = Out typealias A23<in K> = Out<in K> -typealias A24<in K> = Out +typealias A24<in K> = Out<out K> typealias A25<out K> = Out typealias A26<out K> = Out<in K> -typealias A27<out K> = Out +typealias A27<out K> = Out<out K> class Outer { inner class Intermediate { @@ -82,16 +82,16 @@ class InOuter { fun test10(): InOuter.OutIntermediate.InInner = InOuter().OutIntermediate().InInner() -fun test11(): InOuter.OutIntermediate.InInner = InOuter().OutIntermediate().InInner() +fun test11(): InOuter<in Int>.OutIntermediate.InInner = InOuter().OutIntermediate().InInner() fun test12(): InOuter<out Int>.OutIntermediate.InInner = InOuter().OutIntermediate().InInner() fun test13(): InOuter.OutIntermediate<in String>.InInner = InOuter().OutIntermediate().InInner() -fun test14(): InOuter.OutIntermediate.InInner = InOuter().OutIntermediate().InInner() +fun test14(): InOuter.OutIntermediate<out String>.InInner = InOuter().OutIntermediate().InInner() -fun test15(): InOuter.OutIntermediate.InInner = InOuter().OutIntermediate().InInner() +fun test15(): InOuter.OutIntermediate.InInner<in Char> = InOuter().OutIntermediate().InInner() fun test16(): InOuter.OutIntermediate.InInner<out Char> = InOuter().OutIntermediate().InInner() -fun test17(): InOuter.OutIntermediate.InInner = InOuter().OutIntermediate().InInner() +fun test17(): InOuter<in Int>.OutIntermediate<out String>.InInner = InOuter().OutIntermediate().InInner() fun test18(): InOuter.OutIntermediate<in String>.InInner<out Char> = InOuter().OutIntermediate().InInner() class TwoParametersOuter { diff --git a/compiler/fir/analysis-tests/testData/resolve/fromBuilder/typeParameters.kt b/compiler/fir/analysis-tests/testData/resolve/fromBuilder/typeParameters.kt index 33ba23f33c2..23f5085fe70 100644 --- a/compiler/fir/analysis-tests/testData/resolve/fromBuilder/typeParameters.kt +++ b/compiler/fir/analysis-tests/testData/resolve/fromBuilder/typeParameters.kt @@ -4,7 +4,7 @@ interface List { infix fun concat(other: List<T>): List } -typealias StringList = List +typealias StringList = List<out String> typealias AnyList = List<*> abstract class AbstractList : List diff --git a/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt b/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt index 1e260168afd..3284a8adb33 100644 --- a/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt +++ b/compiler/fir/analysis-tests/testData/resolve/typeAliasWithTypeArguments.kt @@ -71,13 +71,13 @@ typealias Out1 = Out typealias Invariant1 = Invariant -fun test_5(a: A, in1: In1, in2: In1, in3: In1<out A>) { +fun test_5(a: A, in1: In1, in2: In1<in A>, in3: In1<out A>) { in1.take(a) in2.take(a) in3.take(a) } -fun test_6(a: A, out1: Out1, out2: Out1<in A>, out3: Out1) { +fun test_6(a: A, out1: Out1, out2: Out1<in A>, out3: Out1<out A>) { out1.value().foo() out2.value().foo() out3.value().foo() diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 653bdfb8c1f..271e79df24c 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -386,6 +386,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION by error(PositioningStrategy.VARIANCE_MODIFIER) { parameter("type") } + val REDUNDANT_PROJECTION by warning(PositioningStrategy.VARIANCE_MODIFIER) { + parameter("type") + } val VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED by error(PositioningStrategy.VARIANCE_MODIFIER) val CATCH_PARAMETER_WITH_DEFAULT_VALUE by error() diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index f0b0043b757..ca038204b85 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -276,6 +276,7 @@ object FirErrors { val TYPE_PARAMETERS_IN_ENUM by error0() val CONFLICTING_PROJECTION by error1(SourceElementPositioningStrategies.VARIANCE_MODIFIER) val CONFLICTING_PROJECTION_IN_TYPEALIAS_EXPANSION by error1(SourceElementPositioningStrategies.VARIANCE_MODIFIER) + val REDUNDANT_PROJECTION by warning1(SourceElementPositioningStrategies.VARIANCE_MODIFIER) val VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED by error0(SourceElementPositioningStrategies.VARIANCE_MODIFIER) val CATCH_PARAMETER_WITH_DEFAULT_VALUE by error0() val REIFIED_TYPE_IN_CATCH_CLAUSE by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 7010cc4feac..190563c7f88 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -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 get() = setOf( FirModifierChecker, FirConflictsChecker, - FirConflictingProjectionChecker, + FirProjectionRelationChecker, FirTypeConstraintsChecker, FirReservedUnderscoreDeclarationChecker ) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirProjectionRelationChecker.kt similarity index 59% rename from compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt rename to compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirProjectionRelationChecker.kt index 8dd79479ced..6b25a52743e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirProjectionRelationChecker.kt @@ -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? = 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 } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 6f3863f0e6a..db846fa1a37 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -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" diff --git a/compiler/testData/diagnostics/tests/declarationChecks/ConflictingAndRedundantProjections.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/ConflictingAndRedundantProjections.fir.kt deleted file mode 100644 index 107683a2e03..00000000000 --- a/compiler/testData/diagnostics/tests/declarationChecks/ConflictingAndRedundantProjections.fir.kt +++ /dev/null @@ -1,20 +0,0 @@ -class In -class Out -class Inv -class X - -fun f1(p: In) {} -fun f2(p: In<out X>) {} -fun f3(p: In) {} - -fun f4(p: Out) {} -fun f5(p: Out<in X>) {} -fun f6(p: Out) {} - -fun f6(p: Inv) {} -fun f7(p: Inv) {} -fun f8(p: Inv) {} - -fun f9(p: In<*>) {} -fun f10(p: Out<*>) {} -fun f11(p: Inv<*>) {} diff --git a/compiler/testData/diagnostics/tests/declarationChecks/ConflictingAndRedundantProjections.kt b/compiler/testData/diagnostics/tests/declarationChecks/ConflictingAndRedundantProjections.kt index 746da40db8c..e08fb9e1e20 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/ConflictingAndRedundantProjections.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/ConflictingAndRedundantProjections.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class In class Out class Inv diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt index 32741c4edf6..d7561d83ff1 100644 --- a/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt @@ -2,11 +2,11 @@ typealias Action = (@UnsafeVariance K) -> Unit typealias Action2 = (@UnsafeVariance K) -> K data class Tag(val action: Action) -data class Tag2(val action: Action) +data class Tag2(val action: Action<in L>) data class Tag3(val action: Action) -data class Tag4(val action: Action) +data class Tag4(val action: Action<in L>) data class Tag5(val action: Action2) -data class Tag6(val action: Action) +data class Tag6(val action: Action<in L>) data class Tag7(val action: Action) data class Tag8(val action: Action2) diff --git a/compiler/testData/diagnostics/tests/regressions/OutProjections.fir.kt b/compiler/testData/diagnostics/tests/regressions/OutProjections.fir.kt index 7f0fb514060..f645dbbd820 100644 --- a/compiler/testData/diagnostics/tests/regressions/OutProjections.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/OutProjections.fir.kt @@ -13,7 +13,7 @@ fun foo() : G { class Out() {} -fun fout(expression : T) : Out = Out() +fun fout(expression : T) : Out<out T> = Out() fun fooout() : Out { val p = Point(); diff --git a/compiler/testData/diagnostics/tests/typealias/substitutionVariance.fir.kt b/compiler/testData/diagnostics/tests/typealias/substitutionVariance.fir.kt index 13c04c13877..a66ba100b71 100644 --- a/compiler/testData/diagnostics/tests/typealias/substitutionVariance.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/substitutionVariance.fir.kt @@ -5,13 +5,13 @@ class Out class Inv typealias In1 = In -typealias In2 = In +typealias In2 = In<in T> typealias In3 = In<out T> typealias In4 = In<*> typealias Out1 = Out typealias Out2 = Out<in T> -typealias Out3 = Out +typealias Out3 = Out<out T> typealias Out4 = Out<*> typealias Inv1 = Inv @@ -22,12 +22,12 @@ typealias Inv4 = Inv<*> val inv1: Inv1 = Inv() fun inInv_Inv(x: In1) = x -fun inInv_In(x: In1) = x +fun inInv_In(x: In1<in Int>) = x fun inInv_Out(x: In1<out Int>) = x fun inInv_Star(x: In1<*>) = x fun inIn_Inv(x: In2) = x -fun inIn_In(x: In2) = x +fun inIn_In(x: In2<in Int>) = x fun inIn_Out(x: In2<out Int>) = x fun inIn_Star(x: In2<*>) = x @@ -38,7 +38,7 @@ fun inOut_Star(x: In3<*>) = x fun outInv_Inv(x: Out1) = x fun outInv_In(x: Out1<in Int>) = x -fun outInv_Out(x: Out1) = x +fun outInv_Out(x: Out1<out Int>) = x fun outInv_Star(x: Out1<*>) = x fun outIn_Inv(x: Out2) = x @@ -48,7 +48,7 @@ fun outIn_Star(x: Out2<*>) = x fun outOut_Inv(x: Out3) = x fun outOut_In(x: Out3<in Int>) = x -fun outOut_Out(x: Out3) = x +fun outOut_Out(x: Out3<out Int>) = x fun outOut_Star(x: Out3<*>) = x fun invInv_Inv(x: Inv1) = x diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.fir.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.fir.kt index 34d52277449..95c4d4badec 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasForProjectionInSuperInterfaces.fir.kt @@ -8,11 +8,11 @@ typealias InvOut = Inv typealias InvT = Inv typealias OutStar = Out<*> -typealias OutOut = Out +typealias OutOut = Out<out Int> typealias OutT = Out typealias InStar = In<*> -typealias InIn = In +typealias InIn = In<in Int> typealias InT = In class Test1 : InvStar @@ -24,9 +24,9 @@ class Test5 : InvT> class Test6 : OutStar class Test7 : OutOut class Test8 : OutT -class Test9 : OutT +class Test9 : OutT<out Int> class Test10 : InStar class Test11 : InIn class Test12 : InT -class Test13 : InT \ No newline at end of file +class Test13 : InT<in Int> diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt index 484f872b425..4060ccbd849 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt @@ -2525,7 +2525,7 @@ fun case_37(x: Map?) { } // TESTCASE NUMBER: 38 -fun case_38(x: Map<*, out T>?) { +fun case_38(x: Map<*, out T>?) { if (x != null) { ? & kotlin.collections.Map<*, out T>")!>x ? & kotlin.collections.Map<*, out T>")!>x.equals(null) @@ -2731,7 +2731,7 @@ fun case_40(x: InterfaceWithTwoTypeParameters?) { } // TESTCASE NUMBER: 41 -fun case_41(x: Map?) { +fun case_41(x: Mapout T>?) { if (x != null) { ? & kotlin.collections.Map")!>x ? & kotlin.collections.Map")!>x.equals(null) @@ -2803,7 +2803,7 @@ fun case_41(x: Map?) { } // TESTCASE NUMBER: 42 -fun case_42(x: Map?) { +fun case_42(x: Mapout T>?) { if (x != null) { ? & kotlin.collections.Map")!>x ? & kotlin.collections.Map")!>x.equals(null) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/9.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/9.fir.kt index f6479804ae3..a2b6f12e658 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/9.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/9.fir.kt @@ -3,7 +3,7 @@ // SKIP_TXT // TESTCASE NUMBER: 1 -fun case_1(x: Out?) { +fun case_1(x: Out<out Int?>?) { if (x != null) { ? & Out")!>x ? & Out")!>x.equals(null) @@ -23,7 +23,7 @@ fun case_1(x: Out?) { * UNEXPECTED BEHAVIOUR * ISSUES: KT-28598 */ -fun case_2(a: Out?>?>?>?>?>?) { +fun case_2(a: Out<out Out?>?>?>?>?>?) { if (a != null) { val b = ?>?>?>?>?>? & Out?>?>?>?>?>")!>a.get() if (b != null) { @@ -75,7 +75,7 @@ fun case_3(a: Inv?) { } // TESTCASE NUMBER: 4 -fun case_4(a: Out?, b: Out = if (a != null) ? & Out")!>a else Out()) { +fun case_4(a: Out<out Int>?, b: Out<out Int> = if (a != null) ? & Out")!>a else Out()) { ?")!>a ")!>b ")!>b.equals(null) @@ -90,7 +90,7 @@ fun case_4(a: Out?, b: Out = if (a != null) ? = null +val x: Out<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? = null + var x: Out<out Int>? = null if (x != null) { ? & Out")!>x @@ -469,7 +469,7 @@ fun case_20(a: Inv) { * UNEXPECTED BEHAVIOUR * ISSUES: KT-28785 */ -fun case_21(a: Out) { +fun case_21(a: Out<out Int?>) { if (a.x != null) { a.x a.x.equals(null) @@ -489,7 +489,7 @@ fun case_21(a: Out) { * UNEXPECTED BEHAVIOUR * ISSUES: KT-28785 */ -fun case_22(a: Out) { +fun case_22(a: Out<out Nothing?>) { if (a.x != null) { a.x a.x.hashCode() @@ -501,7 +501,7 @@ fun case_22(a: Out) { * UNEXPECTED BEHAVIOUR * ISSUES: KT-28785 */ -fun case_23(a: Out) { +fun case_23(a: Out<out Any?>) { if (a.x != null) { a.x a.x.equals(null) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 5f3f1c00693..5f364455b75 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -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<*>, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 2b46411aa10..6d9366f470f 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -850,6 +850,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val type: KtType } + abstract class RedundantProjection : KtFirDiagnostic() { + override val diagnosticClass get() = RedundantProjection::class + abstract val type: KtType + } + abstract class VarianceOnTypeParameterNotAllowed : KtFirDiagnostic() { override val diagnosticClass get() = VarianceOnTypeParameterNotAllowed::class } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index ecdec42eb22..72527ea5471 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -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 { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class VarianceOnTypeParameterNotAllowedImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken,