Skip to content

Commit 3ea4595

Browse files
dzharkovSpace Team
authored and
Space Team
committed
K2: Fix false-positive OVERLOAD_RESOLUTION_AMBIGUITY with PCLA
Mostly, the idea of this change is reproducing K1 behavior with stub types ^KT-67875 Fixed ^KT-67947 Related
1 parent d295f9c commit 3ea4595

File tree

4 files changed

+33
-39
lines changed

4 files changed

+33
-39
lines changed

compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.StandardClassIds.UShort
2929
import org.jetbrains.kotlin.resolve.calls.results.*
3030
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
3131
import org.jetbrains.kotlin.types.model.requireOrDescribe
32+
import org.jetbrains.kotlin.types.model.safeSubstitute
3233
import org.jetbrains.kotlin.utils.addIfNotNull
3334
import org.jetbrains.kotlin.utils.addToStdlib.runIf
3435
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
@@ -179,16 +180,16 @@ abstract class AbstractConeCallConflictResolver(
179180
): List<TypeWithConversion> {
180181
return buildList {
181182
val session = inferenceComponents.session
182-
addIfNotNull(called.receiverParameter?.typeRef?.coneType?.fullyExpandedType(session)?.let { TypeWithConversion(it) })
183+
addIfNotNull(called.receiverParameter?.typeRef?.coneType?.prepareType(session, call)?.let { TypeWithConversion(it) })
183184
val typeForCallableReference = call.resultingTypeForCallableReference
184185
if (typeForCallableReference != null) {
185186
// Return type isn't needed here v
186187
typeForCallableReference.typeArguments.dropLast(1)
187188
.mapTo(this) {
188-
TypeWithConversion((it as ConeKotlinType).fullyExpandedType(session).removeTypeVariableTypes(session.typeContext))
189+
TypeWithConversion((it as ConeKotlinType).prepareType(session, call).removeTypeVariableTypes(session.typeContext))
189190
}
190191
} else {
191-
called.contextReceivers.mapTo(this) { TypeWithConversion(it.typeRef.coneType.fullyExpandedType(session)) }
192+
called.contextReceivers.mapTo(this) { TypeWithConversion(it.typeRef.coneType.prepareType(session, call)) }
192193
call.argumentMapping?.mapTo(this) { (_, parameter) ->
193194
parameter.toTypeWithConversion(session, call)
194195
}
@@ -210,7 +211,7 @@ abstract class AbstractConeCallConflictResolver(
210211
}
211212

212213
private fun FirValueParameter.toTypeWithConversion(session: FirSession, call: Candidate): TypeWithConversion {
213-
val argumentType = argumentType().fullyExpandedType(session)
214+
val argumentType = argumentType().prepareType(session, call)
214215
val functionTypeForSam = toFunctionTypeForSamOrNull(call)
215216
return if (functionTypeForSam == null) {
216217
TypeWithConversion(argumentType)
@@ -219,6 +220,25 @@ abstract class AbstractConeCallConflictResolver(
219220
}
220221
}
221222

223+
private fun ConeKotlinType.prepareType(session: FirSession, candidate: Candidate): ConeKotlinType {
224+
val expanded = fullyExpandedType(session)
225+
if (!candidate.system.usesOuterCs) return expanded
226+
// For resolving overloads in PCLA of the following form:
227+
// fun foo(vararg values: Tv)
228+
// fun foo(x: A<Tv>)
229+
// In K1, all Tv variables have been replaced with relevant stub types
230+
// Thus, both of the overloads were considered as not less specific than other (stubTypesAreEqualToAnything=true)
231+
// And after that the one with A<Tv> is chosen because it was discriminated via [ConeOverloadConflictResolver.exactMaxWith]
232+
// as not containing varargs.
233+
// Thus we reproduce K1 behavior with stub types (even though we don't like then much, but it's very local)
234+
//
235+
// But this behavior looks quite hacky because it seems that the second overload should win even without varargs
236+
// on the first one.
237+
// TODO: Get rid of hacky K1 behavior (KT-67947)
238+
return candidate.system.buildNotFixedVariablesToStubTypesSubstitutor()
239+
.safeSubstitute(session.typeContext, expanded) as ConeKotlinType
240+
}
241+
222242
private fun FirValueParameter.toFunctionTypeForSamOrNull(call: Candidate): ConeKotlinType? {
223243
val functionTypesOfSamConversions = call.functionTypesOfSamConversions ?: return null
224244
return call.argumentMapping?.entries?.firstNotNullOfOrNull {

compiler/testData/diagnostics/tests/builderInference/issues/kt67875.fir.kt

Lines changed: 0 additions & 27 deletions
This file was deleted.

compiler/testData/diagnostics/tests/builderInference/issues/kt67875.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// FIR_IDENTICAL
12
// WITH_STDLIB
23
// ISSUE: KT-67875
34

compiler/testData/diagnostics/tests/builderInference/overloadResolutionWithTypeVariables.fir.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ fun <T2> Controller<T2>.fooExt(x: Inv<T2>) {}
2727
fun <E> generate(f: Controller<E>.() -> Unit) {}
2828

2929
fun bar(inv: Inv<String>, out: Out<String>, i: In<CharSequence>, cs: CharSequence) {
30-
<!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
31-
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo1<!>(inv)
30+
generate {
31+
foo1(inv)
3232
}
3333

34-
<!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
35-
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo2<!>(out)
34+
generate {
35+
foo2(out)
3636
}
3737

38-
<!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
38+
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
3939
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo3<!>(inv)
4040
}
4141

42-
<!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
42+
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
4343
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo4<!>(i)
4444
}
4545

@@ -49,7 +49,7 @@ fun bar(inv: Inv<String>, out: Out<String>, i: In<CharSequence>, cs: CharSequenc
4949
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo4<!>(i)
5050
}
5151

52-
<!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
52+
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
5353
<!OVERLOAD_RESOLUTION_AMBIGUITY!>fooExt<!>(inv)
5454
}
55-
}
55+
}

0 commit comments

Comments
 (0)