PSI2IR: Post-process return expressions based on expected return type

Consider the following example:

Java:
  public class J {
    public static String foo() { return null; }
  }

Kotlin:
  fun check(fn: () -> Any) = fn()
  fun test() = check { J.foo() }

When a lambda expression returns a value of platform type ('String!'),
corresponding lambda has platform type in its return type, which is
approximated to corresponding nullable type ('String?') in IR.
However, the lambda itself could occur in position with a functional
expected type ('() -> Any'). This implies an extra implicit cast on a
return value of lambda expression ('J.foo()'), although it conforms to
the return type of lambda.
This commit is contained in:
Dmitry Petrov
2019-12-30 19:38:52 +03:00
parent 0e4e5ac287
commit 8054e2960e
7 changed files with 241 additions and 59 deletions
@@ -1,49 +1,5 @@
// KOTLIN_CONFIGURATION_FLAGS: +JVM.DISABLE_PARAM_ASSERTIONS
// IGNORE_BACKEND: JVM_IR
// Missing IMPLICIT_NOTNULL casts
// FILE: A.java
import org.jetbrains.annotations.NotNull;
public class A {
@NotNull
public final String NULL = null;
@NotNull
public static final String STATIC_NULL = null;
public String foo() {
return null;
}
public static String staticFoo() {
return null;
}
public A plus(A a) {
return null;
}
public A inc() {
return null;
}
public Object get(Object o) {
return null;
}
public A a() { return this; }
public static class B {
public static B b() { return null; }
}
public static class C {
public static C c() { return null; }
}
}
// FILE: AssertionChecker.kt
// FILE: callAssertions.kt
class AssertionChecker(val illegalStateExpected: Boolean) {
operator fun invoke(name: String, f: () -> Any) {
@@ -124,3 +80,46 @@ fun box(): String {
checkAssertions(true)
return "OK"
}
// FILE: A.java
import org.jetbrains.annotations.NotNull;
public class A {
@NotNull
public final String NULL = null;
@NotNull
public static final String STATIC_NULL = null;
public String foo() {
return null;
}
public static String staticFoo() {
return null;
}
public A plus(A a) {
return null;
}
public A inc() {
return null;
}
public Object get(Object o) {
return null;
}
public A a() { return this; }
public static class B {
public static B b() { return null; }
}
public static class C {
public static C c() { return null; }
}
}