FIR: Fix candidate receivers orders when choosing a context receiver
^KT-53257 Fixed
This commit is contained in:
+6
@@ -17182,6 +17182,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/propertyCompoundAssignment.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiversOrder.kt")
|
||||
public void testReceiversOrder() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/receiversOrder.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleCall.kt")
|
||||
public void testSimpleCall() throws Exception {
|
||||
|
||||
@@ -200,7 +200,7 @@ object CheckContextReceivers : ResolutionStage() {
|
||||
}?.takeUnless { it.isEmpty() } ?: return
|
||||
|
||||
val receiverGroups: List<List<ImplicitReceiverValue<*>>> =
|
||||
context.bodyResolveContext.towerDataContext.towerDataElements.mapNotNull { towerDataElement ->
|
||||
context.bodyResolveContext.towerDataContext.towerDataElements.asReversed().mapNotNull { towerDataElement ->
|
||||
towerDataElement.implicitReceiver?.let(::listOf) ?: towerDataElement.contextReceiverGroup
|
||||
}
|
||||
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// !LANGUAGE: +ContextReceivers
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
class A(val x: String)
|
||||
|
||||
var result = ""
|
||||
|
||||
context(A)
|
||||
fun foo() {
|
||||
result += x
|
||||
}
|
||||
|
||||
fun A.bar() {
|
||||
foo()
|
||||
baz {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
fun baz(a: A.() -> Unit) {
|
||||
a(A("K"))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
A("O").bar() // prints "1", "1" while "1", "2" is expected
|
||||
|
||||
return result
|
||||
}
|
||||
+1
-1
@@ -272,7 +272,7 @@ FILE fqName:<root> fileName:/iteratorOperator.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): <root>.CounterIterator declared in <root>.iterator'
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (_context_receiver_0: <root>.CounterConfig, counter: <root>.Counter) [primary] declared in <root>.CounterIterator' type=<root>.CounterIterator origin=null
|
||||
_context_receiver_0: GET_VAR '_context_receiver_0: <root>.CounterConfig declared in <root>.iterator' type=<root>.CounterConfig origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.CounterConfig declared in <root>.iterator.<anonymous>' type=<root>.CounterConfig origin=null
|
||||
counter: GET_VAR '<this>: <root>.Counter declared in <root>.iterator' type=<root>.Counter origin=null
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ class CounterIterator : Iterator<Int> {
|
||||
|
||||
operator fun Counter.iterator(_context_receiver_0: CounterConfig): CounterIterator {
|
||||
return with<CounterConfig, CounterIterator>(receiver = _context_receiver_0, block = local fun CounterConfig.<anonymous>(): CounterIterator {
|
||||
return CounterIterator(_context_receiver_0 = _context_receiver_0, counter = <this>)
|
||||
return CounterIterator(_context_receiver_0 = $this$with, counter = <this>)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+10
-10
@@ -60,9 +60,9 @@ FILE fqName:<root> fileName:/lazy.kt
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_1: GET_VAR '$this$with: <root>.Lazy<kotlin.CharSequence> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.CharSequence> origin=null
|
||||
CALL 'public final fun test2 <T> (_context_receiver_0: <root>.Lazy<T of <root>.test2>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: kotlin.Int
|
||||
<T>: kotlin.CharSequence
|
||||
$receiver: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.CharSequence> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.CharSequence> origin=null
|
||||
CALL 'public final fun with <T, R> (receiver: T of kotlin.StandardKt.with, block: @[ExtensionFunctionType] kotlin.Function1<T of kotlin.StandardKt.with, R of kotlin.StandardKt.with>): R of kotlin.StandardKt.with [inline] declared in kotlin.StandardKt' type=kotlin.Unit origin=null
|
||||
<T>: <root>.Lazy<kotlin.CharSequence>
|
||||
<R>: kotlin.Unit
|
||||
@@ -84,9 +84,9 @@ FILE fqName:<root> fileName:/lazy.kt
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_1: GET_VAR '$this$with: <root>.Lazy<kotlin.CharSequence> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.CharSequence> origin=null
|
||||
CALL 'public final fun test2 <T> (_context_receiver_0: <root>.Lazy<T of <root>.test2>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: kotlin.CharSequence
|
||||
<T>: kotlin.Int
|
||||
$receiver: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.CharSequence> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.CharSequence> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
CALL 'public final fun with <T, R> (receiver: T of kotlin.StandardKt.with, block: @[ExtensionFunctionType] kotlin.Function1<T of kotlin.StandardKt.with, R of kotlin.StandardKt.with>): R of kotlin.StandardKt.with [inline] declared in kotlin.StandardKt' type=kotlin.Unit origin=null
|
||||
<T>: <root>.Lazy<T of <root>.f>
|
||||
<R>: kotlin.Unit
|
||||
@@ -105,9 +105,9 @@ FILE fqName:<root> fileName:/lazy.kt
|
||||
$receiver: VALUE_PARAMETER name:$this$with type:<root>.Lazy<kotlin.Int>
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun test2 <T> (_context_receiver_0: <root>.Lazy<T of <root>.test2>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: T of <root>.f
|
||||
<T>: kotlin.Int
|
||||
$receiver: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<T of <root>.f> declared in <root>.f.<anonymous>' type=<root>.Lazy<T of <root>.f> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
CALL 'public final fun with <T, R> (receiver: T of kotlin.StandardKt.with, block: @[ExtensionFunctionType] kotlin.Function1<T of kotlin.StandardKt.with, R of kotlin.StandardKt.with>): R of kotlin.StandardKt.with [inline] declared in kotlin.StandardKt' type=kotlin.Unit origin=null
|
||||
<T>: <root>.Lazy<<root>.Lazy<T of <root>.f>>
|
||||
<R>: kotlin.Unit
|
||||
@@ -126,9 +126,9 @@ FILE fqName:<root> fileName:/lazy.kt
|
||||
$receiver: VALUE_PARAMETER name:$this$with type:<root>.Lazy<kotlin.Int>
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun test2 <T> (_context_receiver_0: <root>.Lazy<T of <root>.test2>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: <root>.Lazy<T of <root>.f>
|
||||
<T>: kotlin.Int
|
||||
$receiver: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<<root>.Lazy<T of <root>.f>> declared in <root>.f.<anonymous>' type=<root>.Lazy<<root>.Lazy<T of <root>.f>> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
CALL 'public final fun test3 <T> (_context_receiver_0: <root>.Lazy<<root>.Lazy<T of <root>.test3>>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: T of <root>.f
|
||||
$receiver: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
@@ -151,9 +151,9 @@ FILE fqName:<root> fileName:/lazy.kt
|
||||
$receiver: VALUE_PARAMETER name:$this$with type:<root>.Lazy<<root>.Lazy<T of <root>.f>>
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun test2 <T> (_context_receiver_0: <root>.Lazy<T of <root>.test2>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: kotlin.Int
|
||||
<T>: <root>.Lazy<T of <root>.f>
|
||||
$receiver: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: <root>.Lazy<<root>.Lazy<T of <root>.f>> declared in <root>.f.<anonymous>.<anonymous>' type=<root>.Lazy<<root>.Lazy<T of <root>.f>> origin=null
|
||||
CALL 'public final fun test3 <T> (_context_receiver_0: <root>.Lazy<<root>.Lazy<T of <root>.test3>>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: T of <root>.f
|
||||
$receiver: GET_VAR '$this$with: <root>.Lazy<kotlin.Int> declared in <root>.f.<anonymous>' type=<root>.Lazy<kotlin.Int> origin=null
|
||||
|
||||
@@ -15,7 +15,7 @@ fun <T : Any?> f(lazy1: Lazy<Int>, lazy2: Lazy<CharSequence>, lazyT: Lazy<T>, la
|
||||
with<Lazy<Int>, Unit>(receiver = lazy1, block = local fun Lazy<Int>.<anonymous>() {
|
||||
return with<Lazy<CharSequence>, Unit>(receiver = lazy2, block = local fun Lazy<CharSequence>.<anonymous>() {
|
||||
test1(_context_receiver_0 = $this$with, _context_receiver_1 = $this$with)
|
||||
$this$with.test2<Int>(_context_receiver_0 = $this$with)
|
||||
$this$with.test2<CharSequence>(_context_receiver_0 = $this$with)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -23,21 +23,21 @@ fun <T : Any?> f(lazy1: Lazy<Int>, lazy2: Lazy<CharSequence>, lazyT: Lazy<T>, la
|
||||
with<Lazy<CharSequence>, Unit>(receiver = lazy2, block = local fun Lazy<CharSequence>.<anonymous>() {
|
||||
return with<Lazy<Int>, Unit>(receiver = lazy1, block = local fun Lazy<Int>.<anonymous>() {
|
||||
test1(_context_receiver_0 = $this$with, _context_receiver_1 = $this$with)
|
||||
$this$with.test2<CharSequence>(_context_receiver_0 = $this$with)
|
||||
$this$with.test2<Int>(_context_receiver_0 = $this$with)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
with<Lazy<T>, Unit>(receiver = lazyT, block = local fun Lazy<T>.<anonymous>() {
|
||||
return with<Lazy<Int>, Unit>(receiver = lazy1, block = local fun Lazy<Int>.<anonymous>() {
|
||||
$this$with.test2<T>(_context_receiver_0 = $this$with)
|
||||
$this$with.test2<Int>(_context_receiver_0 = $this$with)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
with<Lazy<Lazy<T>>, Unit>(receiver = lazyLazyT, block = local fun Lazy<Lazy<T>>.<anonymous>() {
|
||||
return with<Lazy<Int>, Unit>(receiver = lazy1, block = local fun Lazy<Int>.<anonymous>() {
|
||||
$this$with.test2<Lazy<T>>(_context_receiver_0 = $this$with)
|
||||
$this$with.test2<Int>(_context_receiver_0 = $this$with)
|
||||
$this$with.test3<T>(_context_receiver_0 = $this$with)
|
||||
}
|
||||
)
|
||||
@@ -45,7 +45,7 @@ fun <T : Any?> f(lazy1: Lazy<Int>, lazy2: Lazy<CharSequence>, lazyT: Lazy<T>, la
|
||||
)
|
||||
with<Lazy<Int>, Unit>(receiver = lazy1, block = local fun Lazy<Int>.<anonymous>() {
|
||||
return with<Lazy<Lazy<T>>, Unit>(receiver = lazyLazyT, block = local fun Lazy<Lazy<T>>.<anonymous>() {
|
||||
$this$with.test2<Int>(_context_receiver_0 = $this$with)
|
||||
$this$with.test2<Lazy<T>>(_context_receiver_0 = $this$with)
|
||||
$this$with.test3<T>(_context_receiver_0 = $this$with)
|
||||
}
|
||||
)
|
||||
|
||||
+6
@@ -17182,6 +17182,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/propertyCompoundAssignment.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("receiversOrder.kt")
|
||||
public void testReceiversOrder() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/receiversOrder.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleCall.kt")
|
||||
public void testSimpleCall() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user