From 4c08d10cce1a1af704a3454382ca83190a66253f Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Mon, 8 Mar 2021 23:53:21 -0800 Subject: [PATCH] FIR checker: report expression of nullable type parameter as LHS of class literals --- .../checkers/expression/FirGetClassCallChecker.kt | 14 +++++++++++++- .../expressionWithNullableType.fir.kt | 15 --------------- .../classLiteral/expressionWithNullableType.kt | 2 ++ .../classLiteral/expressionWithNullableType.txt | 1 + 4 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirGetClassCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirGetClassCallChecker.kt index 942f29bc384..58a43dbfa38 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirGetClassCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirGetClassCallChecker.kt @@ -6,7 +6,9 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeOfAny import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn @@ -15,6 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.scopes.impl.toConeType import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.lexer.KtTokens.QUEST @@ -38,7 +41,8 @@ object FirGetClassCallChecker : FirBasicExpressionChecker() { val argument = expression.argument val isNullable = markedNullable || (argument as? FirResolvedQualifier)?.isNullableLHSForCallableReference == true || - argument.typeRef.coneType.isMarkedNullable + argument.typeRef.coneType.isMarkedNullable || + argument.typeRef.coneType.isNullableTypeParameter(context.session) if (isNullable) { if (argument.canBeDoubleColonLHSAsType) { reporter.reportOn(source, FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, context) @@ -74,6 +78,14 @@ object FirGetClassCallChecker : FirBasicExpressionChecker() { } } + private fun ConeKotlinType.isNullableTypeParameter(session: FirSession): Boolean { + if (this !is ConeTypeParameterType) return false + val typeParameter = lookupTag.typeParameterSymbol.fir + return !typeParameter.isReified && + // E.g., fun f2(t: T): Any = t::class + !typeParameter.toConeType().isSubtypeOfAny(session) + } + private val FirExpression.canBeDoubleColonLHSAsType: Boolean get() { return this is FirResolvedQualifier || diff --git a/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.fir.kt b/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.fir.kt deleted file mode 100644 index 8aa29459a59..00000000000 --- a/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.fir.kt +++ /dev/null @@ -1,15 +0,0 @@ -// FILE: J.java - -public interface J { - String platformString(); -} - -// FILE: test.kt - -fun f1(x: Int?): Any = x::class -fun f2(t: T): Any = t::class -fun f3(s: S): Any = s::class -fun f4(u: U?): Any = u::class -fun f5(c: List<*>): Any = c[0]::class - -fun f6(j: J): Any = j.platformString()::class diff --git a/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.kt b/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.kt index 683a0c84d48..c4623c60434 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.kt +++ b/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: J.java public interface J { @@ -8,6 +9,7 @@ public interface J { fun f1(x: Int?): Any = x::class fun f2(t: T): Any = t::class +fun f21(t: T): Any where T : Any?, T : Comparable = t::class fun f3(s: S): Any = s::class fun f4(u: U?): Any = u::class fun f5(c: List<*>): Any = c[0]::class diff --git a/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.txt b/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.txt index 4aa69310a38..a44e6a5238e 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.txt +++ b/compiler/testData/diagnostics/tests/classLiteral/expressionWithNullableType.txt @@ -2,6 +2,7 @@ package public fun f1(/*0*/ x: kotlin.Int?): kotlin.Any public fun f2(/*0*/ t: T): kotlin.Any +public fun f21(/*0*/ t: T): kotlin.Any where T : kotlin.Comparable public fun f3(/*0*/ s: S): kotlin.Any public fun f4(/*0*/ u: U?): kotlin.Any public fun f5(/*0*/ c: kotlin.collections.List<*>): kotlin.Any