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
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt
index 9ea75ac..4bd11b6 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt
@@ -31,6 +31,7 @@
 import org.jetbrains.kotlin.resolve.calls.results.*
 import org.jetbrains.kotlin.types.model.KotlinTypeMarker
 import org.jetbrains.kotlin.types.model.requireOrDescribe
+import org.jetbrains.kotlin.types.model.safeSubstitute
 import org.jetbrains.kotlin.utils.addIfNotNull
 import org.jetbrains.kotlin.utils.addToStdlib.runIf
 import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
@@ -191,16 +192,16 @@
     ): List<TypeWithConversion> {
         return buildList {
             val session = inferenceComponents.session
-            addIfNotNull(called.receiverParameter?.typeRef?.coneType?.fullyExpandedType(session)?.let { TypeWithConversion(it) })
+            addIfNotNull(called.receiverParameter?.typeRef?.coneType?.prepareType(session, call)?.let { TypeWithConversion(it) })
             val typeForCallableReference = call.resultingTypeForCallableReference
             if (typeForCallableReference != null) {
                 // Return type isn't needed here       v
                 typeForCallableReference.typeArguments.dropLast(1)
                     .mapTo(this) {
-                        TypeWithConversion((it as ConeKotlinType).fullyExpandedType(session).removeTypeVariableTypes(session.typeContext))
+                        TypeWithConversion((it as ConeKotlinType).prepareType(session, call).removeTypeVariableTypes(session.typeContext))
                     }
             } else {
-                called.contextReceivers.mapTo(this) { TypeWithConversion(it.typeRef.coneType.fullyExpandedType(session)) }
+                called.contextReceivers.mapTo(this) { TypeWithConversion(it.typeRef.coneType.prepareType(session, call)) }
                 call.argumentMapping?.mapTo(this) { (_, parameter) ->
                     parameter.toTypeWithConversion(session, call)
                 }
@@ -222,7 +223,7 @@
     }
 
     private fun FirValueParameter.toTypeWithConversion(session: FirSession, call: Candidate): TypeWithConversion {
-        val argumentType = argumentType().fullyExpandedType(session)
+        val argumentType = argumentType().prepareType(session, call)
         val functionTypeForSam = toFunctionTypeForSamOrNull(call)
         return if (functionTypeForSam == null) {
             TypeWithConversion(argumentType)
@@ -231,6 +232,25 @@
         }
     }
 
+    private fun ConeKotlinType.prepareType(session: FirSession, candidate: Candidate): ConeKotlinType {
+        val expanded = fullyExpandedType(session)
+        if (!candidate.system.usesOuterCs) return expanded
+        // For resolving overloads in PCLA of the following form:
+        //  fun foo(vararg values: Tv)
+        //  fun foo(x: A<Tv>)
+        // In K1, all Tv variables have been replaced with relevant stub types
+        // Thus, both of the overloads were considered as not less specific than other (stubTypesAreEqualToAnything=true)
+        // And after that the one with A<Tv> is chosen because it was discriminated via [ConeOverloadConflictResolver.exactMaxWith]
+        // as not containing varargs.
+        // Thus we reproduce K1 behavior with stub types (even though we don't like then much, but it's very local)
+        //
+        // But this behavior looks quite hacky because it seems that the second overload should win even without varargs
+        // on the first one.
+        // TODO: Get rid of hacky K1 behavior (KT-67947)
+        return candidate.system.buildNotFixedVariablesToStubTypesSubstitutor()
+            .safeSubstitute(session.typeContext, expanded) as ConeKotlinType
+    }
+
     private fun FirValueParameter.toFunctionTypeForSamOrNull(call: Candidate): ConeKotlinType? {
         val functionTypesOfSamConversions = call.functionTypesOfSamConversions ?: return null
         return call.argumentMapping?.entries?.firstNotNullOfOrNull {
diff --git a/compiler/testData/diagnostics/tests/builderInference/issues/kt67875.fir.kt b/compiler/testData/diagnostics/tests/builderInference/issues/kt67875.fir.kt
deleted file mode 100644
index b45ec67..0000000
--- a/compiler/testData/diagnostics/tests/builderInference/issues/kt67875.fir.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-// WITH_STDLIB
-// ISSUE: KT-67875
-
-// FILE: MyClass.java
-public class MyClass<T> {}
-
-// FILE: MyClassBuilder.java
-public class MyClassBuilder<T> {
-    public MyClassBuilder<T> makeClass(T... values) {}
-
-    public MyClassBuilder<T> makeClass(Iterable<? extends T> it) {}
-
-    public MyClass<T> build() { return null; }
-}
-
-// FILE: main.kt
-inline fun <T: Any> myClassOf(
-    init: MyClassBuilder<T>.() -> Unit
-): MyClass<T> = MyClassBuilder<T>().apply(init).build()
-
-object Foo {
-    val myClass = <!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>myClassOf<!> {
-        <!OVERLOAD_RESOLUTION_AMBIGUITY!>makeClass<!>(listOf("a", "b"))
-    }
-
-    private val myClassType: MyClass<String> = myClass
-}
\ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/builderInference/issues/kt67875.kt b/compiler/testData/diagnostics/tests/builderInference/issues/kt67875.kt
index ae85781..e74a886 100644
--- a/compiler/testData/diagnostics/tests/builderInference/issues/kt67875.kt
+++ b/compiler/testData/diagnostics/tests/builderInference/issues/kt67875.kt
@@ -1,3 +1,4 @@
+// FIR_IDENTICAL
 // WITH_STDLIB
 // ISSUE: KT-67875
 
diff --git a/compiler/testData/diagnostics/tests/builderInference/overloadResolutionWithTypeVariables.fir.kt b/compiler/testData/diagnostics/tests/builderInference/overloadResolutionWithTypeVariables.fir.kt
index 3c3dbab..3f8e1f1 100644
--- a/compiler/testData/diagnostics/tests/builderInference/overloadResolutionWithTypeVariables.fir.kt
+++ b/compiler/testData/diagnostics/tests/builderInference/overloadResolutionWithTypeVariables.fir.kt
@@ -27,12 +27,12 @@
 fun <E> generate(f: Controller<E>.() -> Unit) {}
 
 fun bar(inv: Inv<String>, out: Out<String>, i: In<CharSequence>, cs: CharSequence) {
-    <!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
-        <!OVERLOAD_RESOLUTION_AMBIGUITY!>foo1<!>(inv)
+    generate {
+        foo1(inv)
     }
 
-    <!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
-        <!OVERLOAD_RESOLUTION_AMBIGUITY!>foo2<!>(out)
+    generate {
+        foo2(out)
     }
 
     <!CANNOT_INFER_PARAMETER_TYPE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {