[FIR] Report type-aliased 'Nothing' as return type

This warning was issued in K1, but lost in K2

^KT-59420 Fixed
^KT-59429 Fixed
This commit is contained in:
Alejandro Serrano Mena
2023-10-02 14:11:52 +02:00
committed by Space Team
parent f6b2c642c2
commit 310e89f100
10 changed files with 70 additions and 6 deletions
@@ -2360,6 +2360,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.ABBREVIATED_NOTHING_RETURN_TYPE) { firDiagnostic ->
AbbreviatedNothingReturnTypeImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.ABBREVIATED_NOTHING_PROPERTY_TYPE) { firDiagnostic ->
AbbreviatedNothingPropertyTypeImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.CYCLIC_GENERIC_UPPER_BOUND) { firDiagnostic ->
CyclicGenericUpperBoundImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -1678,6 +1678,14 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = ImplicitNothingPropertyType::class
}
interface AbbreviatedNothingReturnType : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = AbbreviatedNothingReturnType::class
}
interface AbbreviatedNothingPropertyType : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = AbbreviatedNothingPropertyType::class
}
interface CyclicGenericUpperBound : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = CyclicGenericUpperBound::class
}
@@ -2017,6 +2017,16 @@ internal class ImplicitNothingPropertyTypeImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.ImplicitNothingPropertyType
internal class AbbreviatedNothingReturnTypeImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.AbbreviatedNothingReturnType
internal class AbbreviatedNothingPropertyTypeImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.AbbreviatedNothingPropertyType
internal class CyclicGenericUpperBoundImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
@@ -768,6 +768,13 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val IMPLICIT_NOTHING_RETURN_TYPE by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val IMPLICIT_NOTHING_PROPERTY_TYPE by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val ABBREVIATED_NOTHING_RETURN_TYPE by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER) {
isSuppressible = true
}
val ABBREVIATED_NOTHING_PROPERTY_TYPE by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER) {
isSuppressible = true
}
val CYCLIC_GENERIC_UPPER_BOUND by error<PsiElement>()
val FINITE_BOUNDS_VIOLATION by error<PsiElement>()
@@ -456,6 +456,8 @@ object FirErrors {
val RETURN_TYPE_MISMATCH by error4<KtExpression, ConeKotlinType, ConeKotlinType, FirFunction, Boolean>(SourceElementPositioningStrategies.WHOLE_ELEMENT)
val IMPLICIT_NOTHING_RETURN_TYPE by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val IMPLICIT_NOTHING_PROPERTY_TYPE by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val ABBREVIATED_NOTHING_RETURN_TYPE by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val ABBREVIATED_NOTHING_PROPERTY_TYPE by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val CYCLIC_GENERIC_UPPER_BOUND by error0<PsiElement>()
val FINITE_BOUNDS_VIOLATION by error0<PsiElement>()
val FINITE_BOUNDS_VIOLATION_IN_JAVA by error1<PsiElement, List<FirBasedSymbol<*>>>()
@@ -14,16 +14,33 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.UnexpandedTypeCheck
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isNothing
object FirImplicitNothingReturnTypeChecker : FirCallableDeclarationChecker() {
override fun check(declaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirSimpleFunction && declaration !is FirProperty) return
if (declaration is FirProperty && declaration.isLocal) return
if (declaration.isOverride) return
if (declaration.symbol.hasExplicitReturnType) return
if (declaration.origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty) return
if (declaration.symbol.hasExplicitReturnType) {
val notDeclaredAsNothing =
@OptIn(UnexpandedTypeCheck::class) !declaration.returnTypeRef.isNothing
val expandedNothing =
declaration.returnTypeRef.coneType.fullyExpandedType(context.session).isNothing
if (notDeclaredAsNothing && expandedNothing) {
val factory = when (declaration) {
is FirSimpleFunction -> FirErrors.ABBREVIATED_NOTHING_RETURN_TYPE
is FirProperty -> FirErrors.ABBREVIATED_NOTHING_PROPERTY_TYPE
else -> error("Should not be here")
}
reporter.reportOn(declaration.source, factory, context)
}
return
}
if (declaration.returnTypeRef.coneType.isNothing) {
val factory = when (declaration) {
is FirSimpleFunction -> FirErrors.IMPLICIT_NOTHING_RETURN_TYPE
@@ -43,6 +43,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMB
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS_ON_NEWLINE_WITH_INDENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.VARIABLE_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.WHEN_MISSING_CASES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABBREVIATED_NOTHING_PROPERTY_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABBREVIATED_NOTHING_RETURN_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_VALUE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_DELEGATED_PROPERTY
@@ -1410,6 +1412,9 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(IMPLICIT_NOTHING_RETURN_TYPE, "Return type 'Nothing' needs to be specified explicitly.")
map.put(IMPLICIT_NOTHING_PROPERTY_TYPE, "Property type 'Nothing' needs to be specified explicitly.")
map.put(ABBREVIATED_NOTHING_RETURN_TYPE, "'Nothing' return type can't be specified with type alias.")
map.put(ABBREVIATED_NOTHING_PROPERTY_TYPE, "'Nothing' property type can't be specified with type alias.")
map.put(CYCLIC_GENERIC_UPPER_BOUND, "Type parameter has cyclic upper bounds.")
map.put(FINITE_BOUNDS_VIOLATION, "This type parameter violates the Finite Bound Restriction.")
@@ -1,5 +0,0 @@
typealias N = Nothing
fun testFun(): N = null!!
val testVal: N = null!!
val testValWithGetter: N get() = null!!
@@ -1,5 +1,10 @@
// FIR_IDENTICAL
typealias N = Nothing
fun <!ABBREVIATED_NOTHING_RETURN_TYPE!>testFun<!>(): N = null!!
val <!ABBREVIATED_NOTHING_PROPERTY_TYPE!>testVal<!>: N = null!!
val <!ABBREVIATED_NOTHING_PROPERTY_TYPE!>testValWithGetter<!>: N get() = null!!
fun testFunN(): Nothing = null!!
val testValN: Nothing = null!!
val testValWithGetterN: Nothing get() = null!!
@@ -1,6 +1,9 @@
package
public val testVal: N /* = kotlin.Nothing */
public val testValN: kotlin.Nothing
public val testValWithGetter: N /* = kotlin.Nothing */
public val testValWithGetterN: kotlin.Nothing
public fun testFun(): N /* = kotlin.Nothing */
public fun testFunN(): kotlin.Nothing
public typealias N = kotlin.Nothing