Introduce FirFunctionReturnTypeMismatchChecker

This commit is contained in:
vldf
2021-04-03 22:58:19 +03:00
committed by Mikhail Glukhikh
parent 24f1f1221e
commit 57d2eb5da2
80 changed files with 501 additions and 238 deletions
@@ -1,5 +1,5 @@
<!CONFLICTING_OVERLOADS!>fun bar(x: String): Int<!> = 1
<!CONFLICTING_OVERLOADS!>fun bar(x: String): Double<!> = 1
<!CONFLICTING_OVERLOADS!>fun bar(x: String): Double<!> = <!RETURN_TYPE_MISMATCH!>1<!>
fun baz(x: String): Int = 1
fun <T, R> foobaz(x: T): R = TODO()
@@ -5,7 +5,7 @@ fun checkNotNull(x: Any?) {
returns(true) implies (x != null)
returns(false) implies (x == null)
}
return x != null
return <!RETURN_TYPE_MISMATCH!>x != null<!>
}
fun trickyRequireNotNull(x: Any?) {
@@ -5,7 +5,7 @@ fun checkIsString(x: Any) {
returns(true) implies (x is String)
returns(false) implies (x !is String)
}
return x is String
return <!RETURN_TYPE_MISMATCH!>x is String<!>
}
fun test(x: Any) {
@@ -0,0 +1,77 @@
FILE: basic.kt
public final fun illegalReturnIf(): R|kotlin/Char| {
^illegalReturnIf when () {
CMP(<, Int(1).R|kotlin/Int.compareTo|(Int(2))) -> {
Char(a)
}
else -> {
Int(1)
}
}
}
public final fun foo(): R|kotlin/String| {
^foo Int(1)
}
public final fun ok(): R|kotlin/Int| {
^ok Int(1)
}
public final fun okOneLineFunction(): R|kotlin/Int| {
^okOneLineFunction Int(10).R|kotlin/Int.plus|(Int(1))
}
public final fun errorOneLineFunction(): R|kotlin/String| {
^errorOneLineFunction Int(10).R|kotlin/Int.plus|(Int(1))
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun bar(): R|kotlin/Unit| {
}
}
public final infix fun R|() -> kotlin/Unit|.foo(x: R|A.() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun okWithLambda(): R|kotlin/String| {
foo@fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
^@foo Unit
}
.R|/foo|(foo@fun R|A|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|/A.bar|()
^@foo Unit
}
)
^okWithLambda String()
}
public final fun errorWithLambda(): R|kotlin/String| {
foo@fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
^@foo Unit
}
.R|/foo|(foo@fun R|A|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|/A.bar|()
^@foo Int(10)
}
)
^errorWithLambda String()
}
public final fun blockReturnValueTypeMatch1(): R|kotlin/Int| {
when () {
CMP(>, Int(1).R|kotlin/Int.compareTo|(Int(2))) -> {
^blockReturnValueTypeMatch1 Double(1.0)
}
}
^blockReturnValueTypeMatch1 Double(2.0)
}
public final fun blockReturnValueTypeMatch2(): R|kotlin/Int| {
when () {
CMP(>, Int(1).R|kotlin/Int.compareTo|(Int(2))) -> {
}
else -> {
^blockReturnValueTypeMatch2 Double(1.0)
}
}
^blockReturnValueTypeMatch2 Double(2.0)
}
@@ -0,0 +1,55 @@
// bug: type of the expression in return statement is Char
fun illegalReturnIf(): Char {
return if (1 < 2) 'a' else { 1 }
}
fun foo(): String {
return <!RETURN_TYPE_MISMATCH!>1<!>
}
fun ok(): Int {
return 1
}
fun okOneLineFunction(): Int = 10 + 1
fun errorOneLineFunction(): String = <!RETURN_TYPE_MISMATCH!>10 + 1<!>
class A {
fun bar() {}
}
infix fun (() -> Unit).foo(x: A.() -> Unit) {}
fun okWithLambda(): String {
{
return@foo
} foo {
bar()
return@foo
}
return ""
}
// no report due bad returns in lambda
fun errorWithLambda(): String {
{
return@foo
} foo {
bar()
return@foo 10
}
return ""
}
fun blockReturnValueTypeMatch1() : Int {
if (1 > 2)
return <!RETURN_TYPE_MISMATCH!>1.0<!>
return <!RETURN_TYPE_MISMATCH!>2.0<!>
}
fun blockReturnValueTypeMatch2() : Int {
if (1 > 2)
else return <!RETURN_TYPE_MISMATCH!>1.0<!>
return <!RETURN_TYPE_MISMATCH!>2.0<!>
}