[NI] Use types and systems from return arguments instead of return type of lambda

This commit is contained in:
Dmitriy Novozhilov
2020-05-26 15:24:41 +03:00
parent f76b57d260
commit 2812ed0a02
15 changed files with 225 additions and 43 deletions
@@ -1815,6 +1815,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt");
} }
@TestMetadata("multipleOverloads_3.kt")
public void testMultipleOverloads_3() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt");
}
@TestMetadata("overloadByLambdaReturnType_disabled.kt") @TestMetadata("overloadByLambdaReturnType_disabled.kt")
public void testOverloadByLambdaReturnType_disabled() throws Exception { public void testOverloadByLambdaReturnType_disabled() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
@@ -96,7 +96,6 @@ class KotlinResolutionCallbacksImpl(
expectedReturnType: UnwrappedType?, expectedReturnType: UnwrappedType?,
annotations: Annotations, annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>, stubsForPostponedVariables: Map<NewTypeVariable, StubType>,
shouldRunInIndependentContext: Boolean
): ReturnArgumentsAnalysisResult { ): ReturnArgumentsAnalysisResult {
val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument
val outerCallContext = psiCallArgument.outerCallContext val outerCallContext = psiCallArgument.outerCallContext
@@ -138,7 +137,7 @@ class KotlinResolutionCallbacksImpl(
val lambdaInfo = LambdaInfo( val lambdaInfo = LambdaInfo(
expectedReturnType ?: TypeUtils.NO_EXPECTED_TYPE, expectedReturnType ?: TypeUtils.NO_EXPECTED_TYPE,
if (expectedReturnType != null || shouldRunInIndependentContext) ContextDependency.INDEPENDENT else ContextDependency.DEPENDENT if (expectedReturnType == null) ContextDependency.DEPENDENT else ContextDependency.INDEPENDENT
) )
val builtIns = outerCallContext.scope.ownerDescriptor.builtIns val builtIns = outerCallContext.scope.ownerDescriptor.builtIns
@@ -198,10 +197,8 @@ class KotlinResolutionCallbacksImpl(
val functionTypeInfo = expressionTypingServices.getTypeInfo(psiCallArgument.expression, actualContext) val functionTypeInfo = expressionTypingServices.getTypeInfo(psiCallArgument.expression, actualContext)
(temporaryTrace ?: trace).record(BindingContext.NEW_INFERENCE_LAMBDA_INFO, psiCallArgument.ktFunction, LambdaInfo.STUB_EMPTY) (temporaryTrace ?: trace).record(BindingContext.NEW_INFERENCE_LAMBDA_INFO, psiCallArgument.ktFunction, LambdaInfo.STUB_EMPTY)
val inferedReturnType = functionTypeInfo.type?.arguments?.last()?.type?.takeIf { functionTypeInfo.type?.isFunctionTypeOrSubtype == true }
if (coroutineSession?.hasInapplicableCall() == true) { if (coroutineSession?.hasInapplicableCall() == true) {
return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, inferedReturnType, hasInapplicableCallForBuilderInference = true) return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, hasInapplicableCallForBuilderInference = true)
} else { } else {
temporaryTrace?.commit() temporaryTrace?.commit()
} }
@@ -249,7 +246,6 @@ class KotlinResolutionCallbacksImpl(
returnArgumentFound returnArgumentFound
), ),
coroutineSession, coroutineSession,
inferedReturnType
) )
} }
@@ -181,6 +181,8 @@ class ResolvedAtomCompleter(
private val ResolvedLambdaAtom.isCoercedToUnit: Boolean private val ResolvedLambdaAtom.isCoercedToUnit: Boolean
get() { get() {
val resultArgumentsInfo = this.resultArgumentsInfo
?: return (subResolvedAtoms!!.single() as ResolvedLambdaAtom).isCoercedToUnit
val returnTypes = val returnTypes =
resultArgumentsInfo.nonErrorArguments.map { resultArgumentsInfo.nonErrorArguments.map {
val type = it.safeAs<SimpleKotlinCallArgument>()?.receiver?.receiverValue?.type ?: return@map null val type = it.safeAs<SimpleKotlinCallArgument>()?.receiver?.receiverValue?.type ?: return@map null
@@ -199,6 +201,8 @@ class ResolvedAtomCompleter(
} }
private fun completeLambda(lambda: ResolvedLambdaAtom) { private fun completeLambda(lambda: ResolvedLambdaAtom) {
val lambda = lambda.unwrap()
val resultArgumentsInfo = lambda.resultArgumentsInfo!!
val returnType = if (lambda.isCoercedToUnit) { val returnType = if (lambda.isCoercedToUnit) {
builtIns.unitType builtIns.unitType
} else { } else {
@@ -213,7 +217,7 @@ class ResolvedAtomCompleter(
) )
updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType) updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType)
for (lambdaResult in lambda.resultArgumentsInfo.nonErrorArguments) { for (lambdaResult in resultArgumentsInfo.nonErrorArguments) {
val resultValueArgument = lambdaResult as? PSIKotlinCallArgument ?: continue val resultValueArgument = lambdaResult as? PSIKotlinCallArgument ?: continue
val newContext = val newContext =
topLevelCallContext.replaceDataFlowInfo(resultValueArgument.dataFlowInfoAfterThisArgument) topLevelCallContext.replaceDataFlowInfo(resultValueArgument.dataFlowInfoAfterThisArgument)
@@ -59,7 +59,6 @@ data class ReturnArgumentsInfo(
data class ReturnArgumentsAnalysisResult( data class ReturnArgumentsAnalysisResult(
val returnArgumentsInfo: ReturnArgumentsInfo, val returnArgumentsInfo: ReturnArgumentsInfo,
val inferenceSession: InferenceSession?, val inferenceSession: InferenceSession?,
val lambdaReturnType: KotlinType? = null,
val hasInapplicableCallForBuilderInference: Boolean = false val hasInapplicableCallForBuilderInference: Boolean = false
) )
@@ -73,7 +72,6 @@ interface KotlinResolutionCallbacks {
expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables
annotations: Annotations, annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>, stubsForPostponedVariables: Map<NewTypeVariable, StubType>,
shouldRunInIndependentContext: Boolean = false
): ReturnArgumentsAnalysisResult ): ReturnArgumentsAnalysisResult
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom) fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
@@ -105,7 +105,9 @@ class KotlinCallCompleter(
val newAtoms = mutableMapOf<KotlinResolutionCandidate, ResolvedLambdaAtom>() val newAtoms = mutableMapOf<KotlinResolutionCandidate, ResolvedLambdaAtom>()
for ((candidate, atom) in lambdas.entries) { for ((candidate, atom) in lambdas.entries) {
newAtoms[candidate] = kotlinConstraintSystemCompleter.prepareLambdaAtomForFactoryPattern(atom, candidate, candidate) val newAtom = kotlinConstraintSystemCompleter.prepareLambdaAtomForFactoryPattern(atom, candidate, candidate)
newAtoms[candidate] = newAtom
candidate.addResolvedKtPrimitive(newAtom)
} }
val diagnosticHolderForLambda = KotlinDiagnosticsHolder.SimpleHolder() val diagnosticHolderForLambda = KotlinDiagnosticsHolder.SimpleHolder()
@@ -116,18 +118,16 @@ class KotlinCallCompleter(
resolutionCallbacks, resolutionCallbacks,
firstAtom, firstAtom,
diagnosticHolderForLambda, diagnosticHolderForLambda,
shouldRunInIndependentContext = true
) )
val lambdaReturnType = results.lambdaReturnType ?: return candidates
lambdas.getValue(firstCandidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(firstAtom))
firstCandidate.csBuilder.addSubtypeConstraint(lambdaReturnType, firstAtom.returnType, LambdaArgumentConstraintPosition(firstAtom))
while (iterator.hasNext()) { while (iterator.hasNext()) {
val (candidate, atom) = iterator.next() val (candidate, atom) = iterator.next()
atom.setAnalyzedResults(results.returnArgumentsInfo, firstAtom.subResolvedAtoms!!) postponedArgumentsAnalyzer.applyResultsOfAnalyzedLambdaToCandidateSystem(
lambdas.getValue(candidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(atom)) candidate.getSystem().asPostponedArgumentsAnalyzerContext(),
candidate.csBuilder.addSubtypeConstraint(lambdaReturnType, atom.returnType, LambdaArgumentConstraintPosition(atom)) atom,
results,
diagnosticHolderForLambda
)
} }
val errorCandidates = mutableSetOf<KotlinResolutionCandidate>() val errorCandidates = mutableSetOf<KotlinResolutionCandidate>()
@@ -226,16 +226,16 @@ fun ResolvedLambdaAtom.transformToResolvedLambda(
expectedType: UnwrappedType, expectedType: UnwrappedType,
returnTypeVariable: TypeVariableForLambdaReturnType? = null returnTypeVariable: TypeVariableForLambdaReturnType? = null
): ResolvedLambdaAtom { ): ResolvedLambdaAtom {
val resolvedLambdaAtom = preprocessLambdaArgument( return preprocessLambdaArgument(
csBuilder, csBuilder,
atom, atom,
expectedType, expectedType,
diagnosticsHolder, diagnosticsHolder,
forceResolution = true, forceResolution = true,
returnTypeVariable = returnTypeVariable returnTypeVariable = returnTypeVariable
) as ResolvedLambdaAtom ).also {
this.setAnalyzedResults(null, listOf(it))
return resolvedLambdaAtom } as ResolvedLambdaAtom
} }
private fun preprocessCallableReference( private fun preprocessCallableReference(
@@ -66,23 +66,33 @@ class PostponedArgumentsAnalyzer(
} }
} }
data class SubstitutorAndStubsForLambdaAnalysis(
val stubsForPostponedVariables: Map<TypeVariableMarker, StubTypeMarker>,
val substitute: (KotlinType) -> UnwrappedType
)
fun Context.createSubstituteFunctorForLambdaAnalysis(): SubstitutorAndStubsForLambdaAnalysis {
val stubsForPostponedVariables = bindingStubsForPostponedVariables()
val currentSubstitutor = buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(this) })
return SubstitutorAndStubsForLambdaAnalysis(stubsForPostponedVariables) {
currentSubstitutor.safeSubstitute(this, it) as UnwrappedType
}
}
fun analyzeLambda( fun analyzeLambda(
c: Context, c: Context,
resolutionCallbacks: KotlinResolutionCallbacks, resolutionCallbacks: KotlinResolutionCallbacks,
lambda: ResolvedLambdaAtom, lambda: ResolvedLambdaAtom,
diagnosticHolder: KotlinDiagnosticsHolder, diagnosticHolder: KotlinDiagnosticsHolder,
shouldRunInIndependentContext: Boolean = false
): ReturnArgumentsAnalysisResult { ): ReturnArgumentsAnalysisResult {
val stubsForPostponedVariables = c.bindingStubsForPostponedVariables() val substitutorAndStubsForLambdaAnalysis = c.createSubstituteFunctorForLambdaAnalysis()
val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(c) }) val substitute = substitutorAndStubsForLambdaAnalysis.substitute
fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(c, type) as UnwrappedType
// Expected type has a higher priority against which lambda should be analyzed // Expected type has a higher priority against which lambda should be analyzed
// Mostly, this is needed to report more specific diagnostics on lambda parameters // Mostly, this is needed to report more specific diagnostics on lambda parameters
fun expectedOrActualType(expected: UnwrappedType?, actual: UnwrappedType?): UnwrappedType? { fun expectedOrActualType(expected: UnwrappedType?, actual: UnwrappedType?): UnwrappedType? {
val expectedSubstituted = expected?.let(::substitute) val expectedSubstituted = expected?.let(substitute)
return if (expectedSubstituted != null && c.canBeProper(expectedSubstituted)) expectedSubstituted else actual?.let(::substitute) return if (expectedSubstituted != null && c.canBeProper(expectedSubstituted)) expectedSubstituted else actual?.let(substitute)
} }
val builtIns = c.getBuilder().builtIns val builtIns = c.getBuilder().builtIns
@@ -104,7 +114,7 @@ class PostponedArgumentsAnalyzer(
val parameters = val parameters =
expectedParametersToMatchAgainst?.mapIndexed { index, expected -> expectedParametersToMatchAgainst?.mapIndexed { index, expected ->
expectedOrActualType(expected, lambda.parameters.getOrNull(index)) ?: builtIns.nothingType expectedOrActualType(expected, lambda.parameters.getOrNull(index)) ?: builtIns.nothingType
} ?: lambda.parameters.map(::substitute) } ?: lambda.parameters.map(substitute)
val rawReturnType = lambda.returnType val rawReturnType = lambda.returnType
@@ -129,15 +139,25 @@ class PostponedArgumentsAnalyzer(
parameters, parameters,
expectedTypeForReturnArguments, expectedTypeForReturnArguments,
convertedAnnotations ?: Annotations.EMPTY, convertedAnnotations ?: Annotations.EMPTY,
stubsForPostponedVariables.cast(), substitutorAndStubsForLambdaAnalysis.stubsForPostponedVariables.cast(),
shouldRunInIndependentContext
) )
val (returnArgumentsInfo, inferenceSession, inferedReturnType, hasInapplicableCallForBuilderInference) = applyResultsOfAnalyzedLambdaToCandidateSystem(c, lambda, returnArgumentsAnalysisResult, diagnosticHolder, substitute)
return returnArgumentsAnalysisResult
}
fun applyResultsOfAnalyzedLambdaToCandidateSystem(
c: Context,
lambda: ResolvedLambdaAtom,
returnArgumentsAnalysisResult: ReturnArgumentsAnalysisResult,
diagnosticHolder: KotlinDiagnosticsHolder,
substitute: (KotlinType) -> UnwrappedType = c.createSubstituteFunctorForLambdaAnalysis().substitute
) {
val (returnArgumentsInfo, inferenceSession, hasInapplicableCallForBuilderInference) =
returnArgumentsAnalysisResult returnArgumentsAnalysisResult
if (hasInapplicableCallForBuilderInference) { if (hasInapplicableCallForBuilderInference) {
c.getBuilder().removePostponedVariables() c.getBuilder().removePostponedVariables()
return returnArgumentsAnalysisResult return
} }
val returnArguments = returnArgumentsInfo.nonErrorArguments val returnArguments = returnArgumentsInfo.nonErrorArguments
@@ -153,7 +173,7 @@ class PostponedArgumentsAnalyzer(
val subResolvedKtPrimitives = allReturnArguments.map { val subResolvedKtPrimitives = allReturnArguments.map {
resolveKtPrimitive( resolveKtPrimitive(
c.getBuilder(), it, lambda.returnType.let(::substitute), c.getBuilder(), it, lambda.returnType.let(substitute),
diagnosticHolder, ReceiverInfo.notReceiver, convertedType = null, diagnosticHolder, ReceiverInfo.notReceiver, convertedType = null,
inferenceSession inferenceSession
) )
@@ -161,7 +181,7 @@ class PostponedArgumentsAnalyzer(
if (!returnArgumentsInfo.returnArgumentsExist) { if (!returnArgumentsInfo.returnArgumentsExist) {
val unitType = lambda.returnType.builtIns.unitType val unitType = lambda.returnType.builtIns.unitType
val lambdaReturnType = lambda.returnType.let(::substitute) val lambdaReturnType = lambda.returnType.let(substitute)
c.getBuilder().addSubtypeConstraint(unitType, lambdaReturnType, LambdaArgumentConstraintPosition(lambda)) c.getBuilder().addSubtypeConstraint(unitType, lambdaReturnType, LambdaArgumentConstraintPosition(lambda))
} }
@@ -173,7 +193,7 @@ class PostponedArgumentsAnalyzer(
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder) val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder)
if (postponedVariables == null) { if (postponedVariables == null) {
c.getBuilder().removePostponedVariables() c.getBuilder().removePostponedVariables()
return returnArgumentsAnalysisResult return
} }
for ((constructor, resultType) in postponedVariables) { for ((constructor, resultType) in postponedVariables) {
@@ -184,8 +204,6 @@ class PostponedArgumentsAnalyzer(
c.getBuilder().addEqualityConstraint(variable.defaultType(c), resultType, CoroutinePosition()) c.getBuilder().addEqualityConstraint(variable.defaultType(c), resultType, CoroutinePosition())
} }
} }
return returnArgumentsAnalysisResult
} }
private fun UnwrappedType?.receiver(): UnwrappedType? { private fun UnwrappedType?.receiver(): UnwrappedType? {
@@ -135,11 +135,17 @@ class ResolvedLambdaAtom(
val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?, val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?,
override val expectedType: UnwrappedType? override val expectedType: UnwrappedType?
) : PostponedResolvedAtom() { ) : PostponedResolvedAtom() {
lateinit var resultArgumentsInfo: ReturnArgumentsInfo /**
* [resultArgumentsInfo] can be null only if lambda was analyzed in process of resolve
* ambiguity by lambda return type
* There is a contract that [resultArgumentsInfo] will be not null for unwrapped lambda atom
* (see [unwrap])
*/
var resultArgumentsInfo: ReturnArgumentsInfo? = null
private set private set
fun setAnalyzedResults( fun setAnalyzedResults(
resultArguments: ReturnArgumentsInfo, resultArguments: ReturnArgumentsInfo?,
subResolvedAtoms: List<ResolvedAtom> subResolvedAtoms: List<ResolvedAtom>
) { ) {
this.resultArgumentsInfo = resultArguments this.resultArgumentsInfo = resultArguments
@@ -150,6 +156,10 @@ class ResolvedLambdaAtom(
override val outputType: UnwrappedType get() = returnType override val outputType: UnwrappedType get() = returnType
} }
fun ResolvedLambdaAtom.unwrap(): ResolvedLambdaAtom {
return if (resultArgumentsInfo != null) this else subResolvedAtoms!!.single() as ResolvedLambdaAtom
}
abstract class ResolvedCallableReferenceAtom( abstract class ResolvedCallableReferenceAtom(
override val atom: CallableReferenceKotlinCallArgument, override val atom: CallableReferenceKotlinCallArgument,
override val expectedType: UnwrappedType? override val expectedType: UnwrappedType?
@@ -0,0 +1,54 @@
// !LANGUAGE: +NewInference +FactoryPatternResolution
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
// ISSUE: KT-11265
// FILE: OverloadResolutionByLambdaReturnType.kt
package kotlin
annotation class OverloadResolutionByLambdaReturnType
// FILE: main.kt
import kotlin.OverloadResolutionByLambdaReturnType
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Iterable<R>): List<R> {
TODO()
}
@OverloadResolutionByLambdaReturnType
@kotlin.jvm.JvmName("myFlatMapSequence")
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Sequence<R>): List<R> {
TODO()
}
interface Name
interface DeclarationDescriptor {
val nextCandidates: List<DeclarationDescriptor>?
val nextCandidatesSeq: Sequence<DeclarationDescriptor>?
val name: Name
}
fun test_1(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.<!AMBIGUITY!>myFlatMap<!> { container ->
val nextCandidates = container.<!UNRESOLVED_REFERENCE!>nextCandidates<!> ?: return@myFlatMap emptyList()
nextCandidates
}
return candidates
}
fun test_2(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.<!AMBIGUITY!>myFlatMap<!> { container ->
val nextCandidates = container.<!UNRESOLVED_REFERENCE!>nextCandidatesSeq<!> ?: return@myFlatMap sequenceOf()
nextCandidates
}
return candidates
}
fun test_3(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.<!AMBIGUITY!>myFlatMap<!> { container ->
val nextCandidates = container.<!UNRESOLVED_REFERENCE!>nextCandidatesSeq<!>!!
nextCandidates
}
return candidates
}
@@ -0,0 +1,54 @@
// !LANGUAGE: +NewInference +FactoryPatternResolution
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
// ISSUE: KT-11265
// FILE: OverloadResolutionByLambdaReturnType.kt
package kotlin
annotation class OverloadResolutionByLambdaReturnType
// FILE: main.kt
import kotlin.OverloadResolutionByLambdaReturnType
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Iterable<R>): List<R> {
TODO()
}
@OverloadResolutionByLambdaReturnType
@kotlin.jvm.JvmName("myFlatMapSequence")
public inline fun <T, R> Iterable<T>.myFlatMap(transform: (T) -> Sequence<R>): List<R> {
TODO()
}
interface Name
interface DeclarationDescriptor {
val nextCandidates: List<DeclarationDescriptor>?
val nextCandidatesSeq: Sequence<DeclarationDescriptor>?
val name: Name
}
fun test_1(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.myFlatMap { container ->
val nextCandidates = container.nextCandidates ?: return@myFlatMap emptyList()
nextCandidates
}
return candidates
}
fun test_2(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.myFlatMap { container ->
val nextCandidates = container.nextCandidatesSeq ?: return@myFlatMap sequenceOf()
nextCandidates
}
return candidates
}
fun test_3(name: Name, toplevelDescriptors: List<DeclarationDescriptor>): List<DeclarationDescriptor> {
val candidates = toplevelDescriptors.myFlatMap { container ->
val nextCandidates = container.nextCandidatesSeq!!
nextCandidates
}
return candidates
}
@@ -0,0 +1,32 @@
package
public fun test_1(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List<DeclarationDescriptor>): kotlin.collections.List<DeclarationDescriptor>
public fun test_2(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List<DeclarationDescriptor>): kotlin.collections.List<DeclarationDescriptor>
public fun test_3(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List<DeclarationDescriptor>): kotlin.collections.List<DeclarationDescriptor>
public inline fun </*0*/ T, /*1*/ R> kotlin.collections.Iterable<T>.myFlatMap(/*0*/ transform: (T) -> kotlin.collections.Iterable<R>): kotlin.collections.List<R>
@kotlin.OverloadResolutionByLambdaReturnType @kotlin.jvm.JvmName(name = "myFlatMapSequence") public inline fun </*0*/ T, /*1*/ R> kotlin.collections.Iterable<T>.myFlatMap(/*0*/ transform: (T) -> kotlin.sequences.Sequence<R>): kotlin.collections.List<R>
public interface DeclarationDescriptor {
public abstract val name: Name
public abstract val nextCandidates: kotlin.collections.List<DeclarationDescriptor>?
public abstract val nextCandidatesSeq: kotlin.sequences.Sequence<DeclarationDescriptor>?
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Name {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package kotlin {
public final annotation class OverloadResolutionByLambdaReturnType : kotlin.Annotation {
public constructor OverloadResolutionByLambdaReturnType()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -30,7 +30,7 @@ fun test_2() {
} }
fun test_3() { fun test_3() {
val x = <!CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION!>create <!TYPE_MISMATCH!>{ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> }<!><!> val x = <!CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION!>create { <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> }<!>
} }
@OverloadResolutionByLambdaReturnType @OverloadResolutionByLambdaReturnType
@@ -2830,6 +2830,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt");
} }
@TestMetadata("multipleOverloads_3.kt")
public void testMultipleOverloads_3() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt");
}
@TestMetadata("overloadByLambdaReturnType_disabled.kt") @TestMetadata("overloadByLambdaReturnType_disabled.kt")
public void testOverloadByLambdaReturnType_disabled() throws Exception { public void testOverloadByLambdaReturnType_disabled() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
@@ -2830,6 +2830,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_2.kt");
} }
@TestMetadata("multipleOverloads_3.kt")
public void testMultipleOverloads_3() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt");
}
@TestMetadata("overloadByLambdaReturnType_disabled.kt") @TestMetadata("overloadByLambdaReturnType_disabled.kt")
public void testOverloadByLambdaReturnType_disabled() throws Exception { public void testOverloadByLambdaReturnType_disabled() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt");
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.resolve.calls.model.ReceiverKotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.ReceiverKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedLambdaAtom import org.jetbrains.kotlin.resolve.calls.model.ResolvedLambdaAtom
import org.jetbrains.kotlin.resolve.calls.model.unwrap
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
import org.jetbrains.kotlin.resolve.calls.tower.receiverValue import org.jetbrains.kotlin.resolve.calls.tower.receiverValue
@@ -76,7 +77,7 @@ fun ResolvedCall<*>.hasLastFunctionalParameterWithResult(context: BindingContext
if (this is NewResolvedCallImpl<*>) { if (this is NewResolvedCallImpl<*>) {
// TODO: looks like hack // TODO: looks like hack
resolvedCallAtom.subResolvedAtoms?.firstOrNull { it is ResolvedLambdaAtom }.safeAs<ResolvedLambdaAtom>()?.let { lambdaAtom -> resolvedCallAtom.subResolvedAtoms?.firstOrNull { it is ResolvedLambdaAtom }.safeAs<ResolvedLambdaAtom>()?.let { lambdaAtom ->
return lambdaAtom.resultArgumentsInfo.nonErrorArguments.filterIsInstance<ReceiverKotlinCallArgument>().all { return lambdaAtom.unwrap().resultArgumentsInfo!!.nonErrorArguments.filterIsInstance<ReceiverKotlinCallArgument>().all {
val type = it.receiverValue?.type ?: return@all false val type = it.receiverValue?.type ?: return@all false
predicate(type) predicate(type)
} }