@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.StandardClassIds.UShort
29
29
import org.jetbrains.kotlin.resolve.calls.results.*
30
30
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
31
31
import org.jetbrains.kotlin.types.model.requireOrDescribe
32
+ import org.jetbrains.kotlin.types.model.safeSubstitute
32
33
import org.jetbrains.kotlin.utils.addIfNotNull
33
34
import org.jetbrains.kotlin.utils.addToStdlib.runIf
34
35
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
@@ -179,16 +180,16 @@ abstract class AbstractConeCallConflictResolver(
179
180
): List <TypeWithConversion > {
180
181
return buildList {
181
182
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) })
183
184
val typeForCallableReference = call.resultingTypeForCallableReference
184
185
if (typeForCallableReference != null ) {
185
186
// Return type isn't needed here v
186
187
typeForCallableReference.typeArguments.dropLast(1 )
187
188
.mapTo(this ) {
188
- TypeWithConversion ((it as ConeKotlinType ).fullyExpandedType (session).removeTypeVariableTypes(session.typeContext))
189
+ TypeWithConversion ((it as ConeKotlinType ).prepareType (session, call ).removeTypeVariableTypes(session.typeContext))
189
190
}
190
191
} else {
191
- called.contextReceivers.mapTo(this ) { TypeWithConversion (it.typeRef.coneType.fullyExpandedType (session)) }
192
+ called.contextReceivers.mapTo(this ) { TypeWithConversion (it.typeRef.coneType.prepareType (session, call )) }
192
193
call.argumentMapping?.mapTo(this ) { (_, parameter) ->
193
194
parameter.toTypeWithConversion(session, call)
194
195
}
@@ -210,7 +211,7 @@ abstract class AbstractConeCallConflictResolver(
210
211
}
211
212
212
213
private fun FirValueParameter.toTypeWithConversion (session : FirSession , call : Candidate ): TypeWithConversion {
213
- val argumentType = argumentType().fullyExpandedType (session)
214
+ val argumentType = argumentType().prepareType (session, call )
214
215
val functionTypeForSam = toFunctionTypeForSamOrNull(call)
215
216
return if (functionTypeForSam == null ) {
216
217
TypeWithConversion (argumentType)
@@ -219,6 +220,25 @@ abstract class AbstractConeCallConflictResolver(
219
220
}
220
221
}
221
222
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
+
222
242
private fun FirValueParameter.toFunctionTypeForSamOrNull (call : Candidate ): ConeKotlinType ? {
223
243
val functionTypesOfSamConversions = call.functionTypesOfSamConversions ? : return null
224
244
return call.argumentMapping?.entries?.firstNotNullOfOrNull {
0 commit comments