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 af2705e85a1..d9e44b7cf8f 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 @@ -250,6 +250,10 @@ object DIAGNOSTICS_LIST : DiagnosticList() { parameter("expectedCount") parameter>("classifier") } + val NO_TYPE_ARGUMENTS_ON_RHS by error { + parameter("expectedCount") + parameter>("classifier") + } val TYPE_PARAMETERS_IN_OBJECT by error() val ILLEGAL_PROJECTION_USAGE by error() val TYPE_PARAMETERS_IN_ENUM 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 e0433baad2d..cc9e64a3b88 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 @@ -192,6 +192,7 @@ object FirErrors { val UPPER_BOUND_VIOLATED by error2() val TYPE_ARGUMENTS_NOT_ALLOWED by error0() val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2>() + val NO_TYPE_ARGUMENTS_ON_RHS by error2>() val TYPE_PARAMETERS_IN_OBJECT by error0() val ILLEGAL_PROJECTION_USAGE by error0() val TYPE_PARAMETERS_IN_ENUM by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 2db4cb0a8a3..7e2889b345a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -44,6 +44,8 @@ private fun ConeDiagnostic.toFirDiagnostic( is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.on(source, this.name.asString()) is ConeWrongNumberOfTypeArgumentsError -> FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifiedAccessSource ?: source, this.desiredCount, this.type) + is ConeNoTypeArgumentsOnRhsError -> + FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.on(qualifiedAccessSource ?: source, this.desiredCount, this.type) is ConeSimpleDiagnostic -> when { source.kind is FirFakeSourceElementKind -> null else -> this.getFactory().on(qualifiedAccessSource ?: source) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index 7f4857c7d5f..b3d19af86b6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -70,10 +70,22 @@ class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic() { override val reason: String get() = "Not a legal annotation: $name" } -class ConeWrongNumberOfTypeArgumentsError(val desiredCount: Int, val type: FirClassLikeSymbol<*>) : ConeDiagnostic() { +abstract class ConeUnmatchedTypeArgumentsError(val desiredCount: Int, val type: FirClassLikeSymbol<*>) : ConeDiagnostic() + +class ConeWrongNumberOfTypeArgumentsError( + desiredCount: Int, + type: FirClassLikeSymbol<*> +) : ConeUnmatchedTypeArgumentsError(desiredCount, type) { override val reason: String get() = "Wrong number of type arguments" } +class ConeNoTypeArgumentsOnRhsError( + desiredCount: Int, + type: FirClassLikeSymbol<*> +) : ConeUnmatchedTypeArgumentsError(desiredCount, type) { + override val reason: String get() = "No type arguments on RHS" +} + class ConeInstanceAccessBeforeSuperCall(val target: String) : ConeDiagnostic() { override val reason: String get() = "Cannot access ''${target}'' before superclass constructor has been called" } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 1f15e55bd08..1f823485e56 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -502,7 +502,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform val originalType = argument.typeRef.coneTypeSafe() ?: return this val newType = computeRepresentativeTypeForBareType(type, originalType) ?: return buildErrorTypeRef { source = this@withTypeArgumentsForBareType.source - diagnostic = ConeWrongNumberOfTypeArgumentsError(firClass.typeParameters.size, firClass.symbol) + diagnostic = ConeNoTypeArgumentsOnRhsError(firClass.typeParameters.size, firClass.symbol) } return if (newType.typeArguments.isEmpty()) this else withReplacedConeType(newType) } diff --git a/compiler/testData/diagnostics/tests/cast/bare/AsNullableNotEnough.fir.kt b/compiler/testData/diagnostics/tests/cast/bare/AsNullableNotEnough.fir.kt index b3c7ce638eb..09e12b59bcb 100644 --- a/compiler/testData/diagnostics/tests/cast/bare/AsNullableNotEnough.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/bare/AsNullableNotEnough.fir.kt @@ -4,7 +4,7 @@ interface Tr interface G fun test(tr: Tr) { - val v = tr as G? + val v = tr as G? // If v is not nullable, there will be a warning on this line: checkSubtype>(v!!) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/bare/NullableAsNotEnough.fir.kt b/compiler/testData/diagnostics/tests/cast/bare/NullableAsNotEnough.fir.kt index f85d147fc34..e28e2ab748d 100644 --- a/compiler/testData/diagnostics/tests/cast/bare/NullableAsNotEnough.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/bare/NullableAsNotEnough.fir.kt @@ -4,6 +4,6 @@ interface Tr interface G fun test(tr: Tr?) { - val v = tr as G + val v = tr as G checkSubtype>(v) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/bare/NullableAsNullableNotEnough.fir.kt b/compiler/testData/diagnostics/tests/cast/bare/NullableAsNullableNotEnough.fir.kt index d9f5de77af8..43ed0729518 100644 --- a/compiler/testData/diagnostics/tests/cast/bare/NullableAsNullableNotEnough.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/bare/NullableAsNullableNotEnough.fir.kt @@ -4,6 +4,6 @@ interface Tr interface G fun test(tr: Tr?) { - val v = tr as G? + val v = tr as G? checkSubtype>(v!!) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/bare/UnrelatedAs.fir.kt b/compiler/testData/diagnostics/tests/cast/bare/UnrelatedAs.fir.kt index 99ae494e82b..54347639674 100644 --- a/compiler/testData/diagnostics/tests/cast/bare/UnrelatedAs.fir.kt +++ b/compiler/testData/diagnostics/tests/cast/bare/UnrelatedAs.fir.kt @@ -4,6 +4,6 @@ interface Tr interface G fun test(tr: Tr) { - val v = tr as G + val v = tr as G checkSubtype>(v) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/bare/UnrelatedIs.fir.kt b/compiler/testData/diagnostics/tests/cast/bare/UnrelatedIs.fir.kt deleted file mode 100644 index 8d2b861fab7..00000000000 --- a/compiler/testData/diagnostics/tests/cast/bare/UnrelatedIs.fir.kt +++ /dev/null @@ -1,4 +0,0 @@ -interface Tr -interface G - -fun test(tr: Tr) = tr is G \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/bare/UnrelatedIs.kt b/compiler/testData/diagnostics/tests/cast/bare/UnrelatedIs.kt index a9b9a061eb8..c188f15f3b4 100644 --- a/compiler/testData/diagnostics/tests/cast/bare/UnrelatedIs.kt +++ b/compiler/testData/diagnostics/tests/cast/bare/UnrelatedIs.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface Tr interface G diff --git a/compiler/testData/diagnostics/tests/generics/RawTypeInIsExpression.fir.kt b/compiler/testData/diagnostics/tests/generics/RawTypeInIsExpression.fir.kt index 08648c657fb..f93981cb748 100644 --- a/compiler/testData/diagnostics/tests/generics/RawTypeInIsExpression.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/RawTypeInIsExpression.fir.kt @@ -2,13 +2,13 @@ package p public fun foo(a: Any) { a is Map - a is Map + a is Map a is Map a is Map<*, *> a is Map<> a is List - a is List + a is List a is Int - (a as Map) is Int + (a as Map) is Int } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/generics/RawTypeInIsPattern.fir.kt b/compiler/testData/diagnostics/tests/generics/RawTypeInIsPattern.fir.kt index 167c86b8c8e..09c35dc6f60 100644 --- a/compiler/testData/diagnostics/tests/generics/RawTypeInIsPattern.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/RawTypeInIsPattern.fir.kt @@ -1,12 +1,12 @@ public fun foo(a: Any, b: Map) { when (a) { is Map -> {} - is Map -> {} + is Map -> {} is Map -> {} is Map<*, *> -> {} is Map<> -> {} is List -> {} - is List -> {} + is List -> {} is Int -> {} else -> {} } diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.fir.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.fir.kt index 7eaeb08a95e..6659a53794c 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/bareTypesComplex.fir.kt @@ -8,7 +8,7 @@ class DerivedOuter : SuperOuter() { fun bare(x: SuperOuter<*>.SuperInner<*>, y: Any?) { if (x is SuperOuter.SuperInner) return - if (y is SuperOuter.SuperInner) { + if (y is SuperOuter.SuperInner) { return } } diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.fir.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.fir.kt index 6b1e7bd1725..079219d3a6b 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/innerUncheckedCast.fir.kt @@ -12,7 +12,7 @@ class Outer { x.prop.checkType { _() } } - if (y is Inner) return + if (y is Inner) return if (z is Inner) { z.prop.checkType { _() } @@ -26,7 +26,7 @@ class Outer { fun bar(x: InnerBase, y: Any?, z: Outer<*>.InnerBase) { x as Inner - y as Inner + y as Inner z as Inner } } diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt index b375a2a8c49..9b88f331a72 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasAsBareType.fir.kt @@ -14,8 +14,8 @@ fun testNL1(x: Collection?): Boolean = x is NL fun testNL2(x: Collection?): List? = x as NL fun testNL3(x: Collection?): List? = x as NL? -fun testLStar(x: Collection): List = x as LStar -fun testMyList(x: Collection): List = x as MyList +fun testLStar(x: Collection): List = x as LStar +fun testMyList(x: Collection): List = x as MyList typealias MMTT = MutableMap typealias Dictionary = MutableMap @@ -24,8 +24,8 @@ typealias ReadableList = MutableList fun testWrong1(x: Map) = x is MMTT fun testWrong2(x: Map) = x is Dictionary -fun testWrong3(x: Map) = x is WriteableMap -fun testWrong4(x: List) = x is ReadableList +fun testWrong3(x: Map) = x is WriteableMap +fun testWrong4(x: List) = x is ReadableList fun testLocal(x: Any) { class C 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 ff3c004a7c0..e805d395d7a 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 @@ -763,6 +763,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.NO_TYPE_ARGUMENTS_ON_RHS) { firDiagnostic -> + NoTypeArgumentsOnRhsImpl( + firDiagnostic.a, + firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b.fir as FirClass<*>), + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.TYPE_PARAMETERS_IN_OBJECT) { firDiagnostic -> TypeParametersInObjectImpl( 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 8965c8ff594..2588f991a29 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 @@ -546,6 +546,12 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val classifier: KtClassLikeSymbol } + abstract class NoTypeArgumentsOnRhs : KtFirDiagnostic() { + override val diagnosticClass get() = NoTypeArgumentsOnRhs::class + abstract val expectedCount: Int + abstract val classifier: KtClassLikeSymbol + } + abstract class TypeParametersInObject : KtFirDiagnostic() { override val diagnosticClass get() = TypeParametersInObject::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 9af26df0c66..8319d1204a1 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 @@ -874,6 +874,15 @@ internal class WrongNumberOfTypeArgumentsImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class NoTypeArgumentsOnRhsImpl( + override val expectedCount: Int, + override val classifier: KtClassLikeSymbol, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.NoTypeArgumentsOnRhs(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class TypeParametersInObjectImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt index 971f33dd7d9..a4b7599cfca 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt @@ -15,10 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertySymbol -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeOperatorAmbiguityError -import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeWrongNumberOfTypeArgumentsError +import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol @@ -51,7 +48,7 @@ internal object FirReferenceResolveHelper { val symbol = resolvedSymbol ?: run { val diagnostic = (this as? FirErrorTypeRef)?.diagnostic - (diagnostic as? ConeWrongNumberOfTypeArgumentsError)?.type + (diagnostic as? ConeUnmatchedTypeArgumentsError)?.type } return symbol?.fir?.buildSymbol(symbolBuilder)