FIR resolve: add partial support of extension lambda calls

Here we introduce ONLY_IMPLICIT_RECEIVER tower level
to support extension lambda calls on local variables,
and soften extension receiver checks to make such extensions visible & applicable.
Also here we try to map arguments twice for functional types
This commit is contained in:
Mikhail Glukhikh
2019-12-23 15:56:50 +03:00
parent 49e94f1ee3
commit de50f8aef3
65 changed files with 292 additions and 144 deletions
@@ -2,7 +2,7 @@
fun foo(a: Any, f: ()->Int) = f()
fun foo(a: Any, f: (Any)->Int) = f(a)
fun foo(i: Int, f: Int.()->Int) = i.<!UNRESOLVED_REFERENCE!>f<!>()
fun foo(i: Int, f: Int.()->Int) = i.f()
fun test1() {
<!AMBIGUITY!>foo<!>(1) { ->
@@ -12,17 +12,17 @@ typealias XBar = Bar
typealias XXBar = XBar
fun Foo.foo(body: Foo.() -> Unit) = <!INAPPLICABLE_CANDIDATE!>body<!>()
fun Foo.xbar(body: XBar.() -> Unit) = Bar().<!UNRESOLVED_REFERENCE!>body<!>()
fun Foo.xxbar(body: XXBar.() -> Unit) = Bar().<!UNRESOLVED_REFERENCE!>body<!>()
fun Foo.foo(body: Foo.() -> Unit) = body()
fun Foo.xbar(body: XBar.() -> Unit) = Bar().body()
fun Foo.xxbar(body: XXBar.() -> Unit) = Bar().body()
fun test() {
Foo().foo {
<!UNRESOLVED_REFERENCE!>xbar<!> {
<!UNRESOLVED_REFERENCE!>foo<!> {}
xbar {
foo {}
}
<!UNRESOLVED_REFERENCE!>xxbar<!> {
<!UNRESOLVED_REFERENCE!>foo<!> {}
xxbar {
foo {}
}
}
}
@@ -12,13 +12,13 @@ class Bar
typealias YBar = ZBar
typealias ZBar = <!OTHER_ERROR!>YBar<!>
fun Foo.foo(body: Foo.() -> Unit) = <!INAPPLICABLE_CANDIDATE!>body<!>()
fun Foo.zbar(body: ZBar.() -> Unit) = Bar().<!UNRESOLVED_REFERENCE!>body<!>()
fun Foo.foo(body: Foo.() -> Unit) = body()
fun Foo.zbar(body: ZBar.() -> Unit) = Bar().body()
fun test() {
Foo().foo {
<!UNRESOLVED_REFERENCE!>zbar<!> {
<!UNRESOLVED_REFERENCE!>foo<!> {}
zbar {
foo {}
}
}
}
@@ -20,14 +20,14 @@ package test
import a.A
fun <T, R> T.with(f: T.() -> R) = <!INAPPLICABLE_CANDIDATE!>f<!>()
fun <T, R> T.with(f: T.() -> R) = f()
fun A.extFun1() = b.length
// fun A.extFun2() = c.length // TODO fix KT-9953
val x1 = A("").with { b.<!UNRESOLVED_REFERENCE!>length<!> }
val x1 = A("").with { b.length }
// val x2 = A("").with { c.length } // TODO fix KT-9953
val x3 = A.with { c.<!UNRESOLVED_REFERENCE!>length<!> }
val x3 = A.with { c.length }
@@ -24,10 +24,10 @@ fun test(c: () -> String, e: Int.() -> String) {
c()
(c)()
3.<!UNRESOLVED_REFERENCE!>e<!>()
3.(<!UNRESOLVED_REFERENCE!>e<!>)()
3.e()
3.(e)()
with(3) {
<!INAPPLICABLE_CANDIDATE!>e<!>()
(<!INAPPLICABLE_CANDIDATE!>e<!>)()
e()
(e)()
}
}
@@ -15,8 +15,8 @@ fun test(a: A) {
a.<!INAPPLICABLE_CANDIDATE!>x<!>()
<!INAPPLICABLE_CANDIDATE!>(a.x)()<!>
if (a.x != null) {
a.<!INAPPLICABLE_CANDIDATE!>x<!>() // todo
<!INAPPLICABLE_CANDIDATE!>(a.x)()<!>
a.x() // todo
(a.x)()
}
}
}
@@ -8,5 +8,5 @@ fun test(a: A, foo: Foo) {
}
fun test(a: Int, foo: Int.()->Unit) {
a.<!UNRESOLVED_REFERENCE!>foo<!>()
a.foo()
}
@@ -55,21 +55,21 @@ fun test(a: A, b: B) {
a.foo(b)
with(a) {
b.<!UNRESOLVED_REFERENCE!>foo<!>()
b.foo()
b.(<!UNRESOLVED_REFERENCE!>foo<!>)()
b.(foo)()
<!UNRESOLVED_REFERENCE!>(b.<!UNRESOLVED_REFERENCE!>foo<!>)()<!>
(b.foo)()
foo(b)
(foo)(b)
}
with(b) {
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
a.(<!INAPPLICABLE_CANDIDATE!>foo<!>)()
a.foo()
a.(foo)()
<!INAPPLICABLE_CANDIDATE!>(a.foo)()<!>
(a.foo)()
(a.foo)(this)
a.foo(this)
@@ -77,8 +77,8 @@ fun test(a: A, b: B) {
with(a) {
with(b) {
<!INAPPLICABLE_CANDIDATE!>foo<!>()
(<!INAPPLICABLE_CANDIDATE!>foo<!>)()
foo()
(foo)()
}
}
}
@@ -6,11 +6,11 @@ class B
fun test(a: A, b: B) {
with(b) {
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // here must be error, because a is not extension receiver
a.foo() // here must be error, because a is not extension receiver
a.foo(this)
<!INAPPLICABLE_CANDIDATE!>(a.foo)()<!>
(a.foo)()
(a.foo)(this)
}
@@ -1,9 +1,9 @@
interface A
fun foo(invoke: A.()->Unit, a: A) {
a.<!UNRESOLVED_REFERENCE!>invoke<!>()
a.invoke()
}
fun bar(invoke: Any.()->Any, a: Any) {
a.<!UNRESOLVED_REFERENCE!>invoke<!>()
a.invoke()
}
@@ -12,7 +12,7 @@ fun test(a: A, b: B) {
b.(a)()
with(b) {
val y: Int = <!UNRESOLVED_REFERENCE!>a<!>()
(<!UNRESOLVED_REFERENCE!>a<!>)()
val y: Int = a()
(a)()
}
}
@@ -9,7 +9,7 @@ class B {
fun test(foo: A.() -> Int) {
with(A()) {
<!INAPPLICABLE_CANDIDATE!>foo<!>() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
foo() checkType { _<Int>() }
with(B()) {
foo() checkType { _<B>() }
this.foo() checkType { _<B>() }