[FIR] Don't run FirFunctionReturnTypeMismatchChecker on only return statements of single expression bodies

This is needed not only as optimization, but also for cases, when
  inferred type of function may differ from type of single expression.
  Such situation may occur after next commit, which adds approximation
  of return type of all declarations:
```
interface A
interface B
interface C : A, B
interface D : A, B

class Inv<T>(val x: T, val y: T)

fun foo(c: C, d: D) /* : Inv<Any> */ = Inv(c, d) /*: Inv<A & B> */
// Inv<A & B> /<: Inv<Any>
// but there should be no error
```
This commit is contained in:
Dmitriy Novozhilov
2022-11-10 15:22:00 +02:00
committed by Space Team
parent 991d8c18aa
commit 0f70635fcb
@@ -6,9 +6,11 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtRealSourceElementKind
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.hasExplicitReturnType
import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeForTypeMismatch
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULL_FOR_NONNULL_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_TYPE_MISMATCH
@@ -16,6 +18,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SMARTCAST_IMPOSSI
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.types.*
@@ -26,6 +29,15 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
if (targetElement is FirErrorFunction || targetElement is FirAnonymousFunction && targetElement.isLambda) {
return
}
val sourceKind = expression.source?.kind
if (
!targetElement.symbol.hasExplicitReturnType &&
sourceKind != KtRealSourceElementKind &&
targetElement !is FirPropertyAccessor
) {
return
}
val resultExpression = expression.result
// To avoid duplications with NO_ELSE_IN_WHEN or INVALID_IF_AS_EXPRESSION
if (resultExpression is FirWhenExpression && !resultExpression.isExhaustive) return
@@ -35,7 +47,7 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
else
targetElement.returnTypeRef.coneType
if (targetElement is FirAnonymousFunction &&
expression.source?.kind is KtFakeSourceElementKind.ImplicitReturn.FromLastStatement &&
sourceKind is KtFakeSourceElementKind.ImplicitReturn.FromLastStatement &&
functionReturnType.isUnit
) {
return