FIR: Fix overload resolution with context receivers
This commit is contained in:
+8
@@ -161,6 +161,10 @@ interface FirDeclarationPresenter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun represent(it: FirSimpleFunction) = buildString {
|
fun represent(it: FirSimpleFunction) = buildString {
|
||||||
|
it.contextReceivers.forEach {
|
||||||
|
appendRepresentation(it)
|
||||||
|
append(',')
|
||||||
|
}
|
||||||
append('<')
|
append('<')
|
||||||
it.typeParameters.forEach {
|
it.typeParameters.forEach {
|
||||||
appendRepresentation(it)
|
appendRepresentation(it)
|
||||||
@@ -195,6 +199,10 @@ interface FirDeclarationPresenter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun represent(it: FirConstructor, owner: FirRegularClass) = buildString {
|
fun represent(it: FirConstructor, owner: FirRegularClass) = buildString {
|
||||||
|
it.contextReceivers.forEach {
|
||||||
|
appendRepresentation(it)
|
||||||
|
append(',')
|
||||||
|
}
|
||||||
append('<')
|
append('<')
|
||||||
it.typeParameters.forEach {
|
it.typeParameters.forEach {
|
||||||
appendRepresentation(it)
|
appendRepresentation(it)
|
||||||
|
|||||||
+7
-3
@@ -41,6 +41,9 @@ abstract class AbstractConeCallConflictResolver(
|
|||||||
if (!call1.isExpect && call2.isExpect) return true
|
if (!call1.isExpect && call2.isExpect) return true
|
||||||
if (call1.isExpect && !call2.isExpect) return false
|
if (call1.isExpect && !call2.isExpect) return false
|
||||||
|
|
||||||
|
if (call1.contextReceiverCount > call2.contextReceiverCount) return true
|
||||||
|
if (call1.contextReceiverCount < call2.contextReceiverCount) return false
|
||||||
|
|
||||||
return createEmptyConstraintSystem().isSignatureNotLessSpecific(
|
return createEmptyConstraintSystem().isSignatureNotLessSpecific(
|
||||||
call1,
|
call1,
|
||||||
call2,
|
call2,
|
||||||
@@ -114,7 +117,7 @@ abstract class AbstractConeCallConflictResolver(
|
|||||||
(variable as? FirProperty)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(),
|
(variable as? FirProperty)?.typeParameters?.map { it.symbol.toLookupTag() }.orEmpty(),
|
||||||
computeSignatureTypes(call, variable),
|
computeSignatureTypes(call, variable),
|
||||||
variable.receiverTypeRef != null,
|
variable.receiverTypeRef != null,
|
||||||
0, // TODO
|
variable.contextReceivers.size,
|
||||||
false,
|
false,
|
||||||
0,
|
0,
|
||||||
(variable as? FirProperty)?.isExpect == true,
|
(variable as? FirProperty)?.isExpect == true,
|
||||||
@@ -129,7 +132,7 @@ abstract class AbstractConeCallConflictResolver(
|
|||||||
computeSignatureTypes(call, constructor),
|
computeSignatureTypes(call, constructor),
|
||||||
//constructor.receiverTypeRef != null,
|
//constructor.receiverTypeRef != null,
|
||||||
false,
|
false,
|
||||||
0, // TODO
|
constructor.contextReceivers.size,
|
||||||
constructor.valueParameters.any { it.isVararg },
|
constructor.valueParameters.any { it.isVararg },
|
||||||
call.numDefaults,
|
call.numDefaults,
|
||||||
constructor.isExpect,
|
constructor.isExpect,
|
||||||
@@ -143,7 +146,7 @@ abstract class AbstractConeCallConflictResolver(
|
|||||||
function.typeParameters.map { it.symbol.toLookupTag() },
|
function.typeParameters.map { it.symbol.toLookupTag() },
|
||||||
computeSignatureTypes(call, function),
|
computeSignatureTypes(call, function),
|
||||||
function.receiverTypeRef != null,
|
function.receiverTypeRef != null,
|
||||||
0, // TODO
|
function.contextReceivers.size,
|
||||||
function.valueParameters.any { it.isVararg },
|
function.valueParameters.any { it.isVararg },
|
||||||
call.numDefaults,
|
call.numDefaults,
|
||||||
function.isExpect,
|
function.isExpect,
|
||||||
@@ -171,6 +174,7 @@ abstract class AbstractConeCallConflictResolver(
|
|||||||
(it as ConeKotlinType).removeTypeVariableTypes(inferenceComponents.session.typeContext)
|
(it as ConeKotlinType).removeTypeVariableTypes(inferenceComponents.session.typeContext)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
called.contextReceivers.mapTo(this) { it.typeRef.coneType }
|
||||||
call.argumentMapping?.mapTo(this) { it.value.argumentType() }
|
call.argumentMapping?.mapTo(this) { it.value.argumentType() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/extensions/contextReceivers/conflictingWithDifferentOrder.fir.kt
Vendored
+2
-2
@@ -10,9 +10,9 @@ fun f(): Unit<!> = TODO()
|
|||||||
fun f(): Unit<!> = TODO()
|
fun f(): Unit<!> = TODO()
|
||||||
|
|
||||||
fun test(a: A, b: B) {
|
fun test(a: A, b: B) {
|
||||||
with(a) {
|
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>with<!>(a) {
|
||||||
with(b) {
|
with(b) {
|
||||||
f()
|
<!ARGUMENT_TYPE_MISMATCH!><!OVERLOAD_RESOLUTION_AMBIGUITY!>f<!>()<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
// !LANGUAGE: +ContextReceivers
|
|
||||||
|
|
||||||
class Context
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>context(Context)
|
|
||||||
fun f(): String<!> = TODO()
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>fun f(): Any<!> = TODO()
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
with(Context()) {
|
|
||||||
f().length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +ContextReceivers
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
|
||||||
class Context
|
class Context
|
||||||
|
|||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
// !LANGUAGE: +ContextReceivers
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>context(Int, String)
|
|
||||||
fun foo(): Int<!> {
|
|
||||||
return this@Int + 42
|
|
||||||
}
|
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>context(Int)
|
|
||||||
fun foo(): Int<!> {
|
|
||||||
return this@Int + 42
|
|
||||||
}
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
with(42) {
|
|
||||||
foo()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +ContextReceivers
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
|
||||||
context(Int, String)
|
context(Int, String)
|
||||||
|
|||||||
+3
-3
@@ -5,16 +5,16 @@ class B(val b: Any)
|
|||||||
class C(val c: Any)
|
class C(val c: Any)
|
||||||
|
|
||||||
context(A<String>) fun A<Int>.f() {
|
context(A<String>) fun A<Int>.f() {
|
||||||
this@A.a.length
|
this@A.a.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>context(A<String>, B) fun f()<!> {
|
context(A<String>, B) fun f() {
|
||||||
this@A.a.length
|
this@A.a.length
|
||||||
this@B.b
|
this@B.b
|
||||||
<!NO_THIS!>this<!>
|
<!NO_THIS!>this<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!CONFLICTING_OVERLOADS!>context(A<Int>, A<String>, B) fun f()<!> {
|
context(A<Int>, A<String>, B) fun f() {
|
||||||
this@A.a.length
|
this@A.a.length
|
||||||
this@B.b
|
this@B.b
|
||||||
<!NO_THIS!>this<!>
|
<!NO_THIS!>this<!>
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ class A {
|
|||||||
fun useWithContextReceivers() {
|
fun useWithContextReceivers() {
|
||||||
with(42) {
|
with(42) {
|
||||||
with("") {
|
with("") {
|
||||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>f<!>({}, 42)
|
f({}, 42)
|
||||||
sameAsFWithoutNonContextualCounterpart({}, 42)
|
sameAsFWithoutNonContextualCounterpart({}, 42)
|
||||||
p
|
p
|
||||||
val a = A()
|
val a = A()
|
||||||
|
|||||||
Reference in New Issue
Block a user