From 2812ed0a02256bcbcd8ec5d1dae685341fedd88e Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 26 May 2020 15:24:41 +0300 Subject: [PATCH] [NI] Use types and systems from return arguments instead of return type of lambda --- ...endDiagnosticsTestWithStdlibGenerated.java | 5 ++ .../tower/KotlinResolutionCallbacksImpl.kt | 8 +-- .../calls/tower/ResolvedAtomCompleter.kt | 6 ++- .../calls/components/ExternalComponents.kt | 2 - .../calls/components/KotlinCallCompleter.kt | 18 +++---- .../components/PostponeArgumentsChecks.kt | 8 +-- .../components/PostponedArgumentsAnalyzer.kt | 52 ++++++++++++------ .../resolve/calls/model/ResolutionAtoms.kt | 14 ++++- .../factoryPattern/multipleOverloads_3.fir.kt | 54 +++++++++++++++++++ .../factoryPattern/multipleOverloads_3.kt | 54 +++++++++++++++++++ .../factoryPattern/multipleOverloads_3.txt | 32 +++++++++++ .../overloadByLambdaReturnType_enabled.kt | 2 +- .../DiagnosticsTestWithStdLibGenerated.java | 5 ++ ...ticsTestWithStdLibUsingJavacGenerated.java | 5 ++ .../inspections/collections/FunctionUtils.kt | 3 +- 15 files changed, 225 insertions(+), 43 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.txt diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java index 050e76224e7..f2b331003c1 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java @@ -1815,6 +1815,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi 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") public void testOverloadByLambdaReturnType_disabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt index 6719bfdcbea..da7910a85bf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt @@ -96,7 +96,6 @@ class KotlinResolutionCallbacksImpl( expectedReturnType: UnwrappedType?, annotations: Annotations, stubsForPostponedVariables: Map, - shouldRunInIndependentContext: Boolean ): ReturnArgumentsAnalysisResult { val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument val outerCallContext = psiCallArgument.outerCallContext @@ -138,7 +137,7 @@ class KotlinResolutionCallbacksImpl( val lambdaInfo = LambdaInfo( 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 @@ -198,10 +197,8 @@ class KotlinResolutionCallbacksImpl( val functionTypeInfo = expressionTypingServices.getTypeInfo(psiCallArgument.expression, actualContext) (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) { - return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, inferedReturnType, hasInapplicableCallForBuilderInference = true) + return ReturnArgumentsAnalysisResult(ReturnArgumentsInfo.empty, coroutineSession, hasInapplicableCallForBuilderInference = true) } else { temporaryTrace?.commit() } @@ -249,7 +246,6 @@ class KotlinResolutionCallbacksImpl( returnArgumentFound ), coroutineSession, - inferedReturnType ) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index 5d2ed674d6e..d1cd7bfaec5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -181,6 +181,8 @@ class ResolvedAtomCompleter( private val ResolvedLambdaAtom.isCoercedToUnit: Boolean get() { + val resultArgumentsInfo = this.resultArgumentsInfo + ?: return (subResolvedAtoms!!.single() as ResolvedLambdaAtom).isCoercedToUnit val returnTypes = resultArgumentsInfo.nonErrorArguments.map { val type = it.safeAs()?.receiver?.receiverValue?.type ?: return@map null @@ -199,6 +201,8 @@ class ResolvedAtomCompleter( } private fun completeLambda(lambda: ResolvedLambdaAtom) { + val lambda = lambda.unwrap() + val resultArgumentsInfo = lambda.resultArgumentsInfo!! val returnType = if (lambda.isCoercedToUnit) { builtIns.unitType } else { @@ -213,7 +217,7 @@ class ResolvedAtomCompleter( ) updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType) - for (lambdaResult in lambda.resultArgumentsInfo.nonErrorArguments) { + for (lambdaResult in resultArgumentsInfo.nonErrorArguments) { val resultValueArgument = lambdaResult as? PSIKotlinCallArgument ?: continue val newContext = topLevelCallContext.replaceDataFlowInfo(resultValueArgument.dataFlowInfoAfterThisArgument) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt index 4717e4f4a50..0d2b02fc0c4 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt @@ -59,7 +59,6 @@ data class ReturnArgumentsInfo( data class ReturnArgumentsAnalysisResult( val returnArgumentsInfo: ReturnArgumentsInfo, val inferenceSession: InferenceSession?, - val lambdaReturnType: KotlinType? = null, 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 annotations: Annotations, stubsForPostponedVariables: Map, - shouldRunInIndependentContext: Boolean = false ): ReturnArgumentsAnalysisResult fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt index 44870a21fb5..1f121a7d446 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt @@ -105,7 +105,9 @@ class KotlinCallCompleter( val newAtoms = mutableMapOf() 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() @@ -116,18 +118,16 @@ class KotlinCallCompleter( resolutionCallbacks, firstAtom, 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()) { val (candidate, atom) = iterator.next() - atom.setAnalyzedResults(results.returnArgumentsInfo, firstAtom.subResolvedAtoms!!) - lambdas.getValue(candidate).setAnalyzedResults(results.returnArgumentsInfo, listOf(atom)) - candidate.csBuilder.addSubtypeConstraint(lambdaReturnType, atom.returnType, LambdaArgumentConstraintPosition(atom)) + postponedArgumentsAnalyzer.applyResultsOfAnalyzedLambdaToCandidateSystem( + candidate.getSystem().asPostponedArgumentsAnalyzerContext(), + atom, + results, + diagnosticHolderForLambda + ) } val errorCandidates = mutableSetOf() diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt index b101634ce91..85f5e8326b3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt @@ -226,16 +226,16 @@ fun ResolvedLambdaAtom.transformToResolvedLambda( expectedType: UnwrappedType, returnTypeVariable: TypeVariableForLambdaReturnType? = null ): ResolvedLambdaAtom { - val resolvedLambdaAtom = preprocessLambdaArgument( + return preprocessLambdaArgument( csBuilder, atom, expectedType, diagnosticsHolder, forceResolution = true, returnTypeVariable = returnTypeVariable - ) as ResolvedLambdaAtom - - return resolvedLambdaAtom + ).also { + this.setAnalyzedResults(null, listOf(it)) + } as ResolvedLambdaAtom } private fun preprocessCallableReference( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt index 402f7969050..bf3c6e3aa45 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt @@ -66,23 +66,33 @@ class PostponedArgumentsAnalyzer( } } + data class SubstitutorAndStubsForLambdaAnalysis( + val stubsForPostponedVariables: Map, + 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( c: Context, resolutionCallbacks: KotlinResolutionCallbacks, lambda: ResolvedLambdaAtom, diagnosticHolder: KotlinDiagnosticsHolder, - shouldRunInIndependentContext: Boolean = false ): ReturnArgumentsAnalysisResult { - val stubsForPostponedVariables = c.bindingStubsForPostponedVariables() - val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(c) }) - - fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(c, type) as UnwrappedType + val substitutorAndStubsForLambdaAnalysis = c.createSubstituteFunctorForLambdaAnalysis() + val substitute = substitutorAndStubsForLambdaAnalysis.substitute // Expected type has a higher priority against which lambda should be analyzed // Mostly, this is needed to report more specific diagnostics on lambda parameters fun expectedOrActualType(expected: UnwrappedType?, actual: UnwrappedType?): UnwrappedType? { - val expectedSubstituted = expected?.let(::substitute) - return if (expectedSubstituted != null && c.canBeProper(expectedSubstituted)) expectedSubstituted else actual?.let(::substitute) + val expectedSubstituted = expected?.let(substitute) + return if (expectedSubstituted != null && c.canBeProper(expectedSubstituted)) expectedSubstituted else actual?.let(substitute) } val builtIns = c.getBuilder().builtIns @@ -104,7 +114,7 @@ class PostponedArgumentsAnalyzer( val parameters = expectedParametersToMatchAgainst?.mapIndexed { index, expected -> expectedOrActualType(expected, lambda.parameters.getOrNull(index)) ?: builtIns.nothingType - } ?: lambda.parameters.map(::substitute) + } ?: lambda.parameters.map(substitute) val rawReturnType = lambda.returnType @@ -129,15 +139,25 @@ class PostponedArgumentsAnalyzer( parameters, expectedTypeForReturnArguments, convertedAnnotations ?: Annotations.EMPTY, - stubsForPostponedVariables.cast(), - shouldRunInIndependentContext + substitutorAndStubsForLambdaAnalysis.stubsForPostponedVariables.cast(), ) - 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 if (hasInapplicableCallForBuilderInference) { c.getBuilder().removePostponedVariables() - return returnArgumentsAnalysisResult + return } val returnArguments = returnArgumentsInfo.nonErrorArguments @@ -153,7 +173,7 @@ class PostponedArgumentsAnalyzer( val subResolvedKtPrimitives = allReturnArguments.map { resolveKtPrimitive( - c.getBuilder(), it, lambda.returnType.let(::substitute), + c.getBuilder(), it, lambda.returnType.let(substitute), diagnosticHolder, ReceiverInfo.notReceiver, convertedType = null, inferenceSession ) @@ -161,7 +181,7 @@ class PostponedArgumentsAnalyzer( if (!returnArgumentsInfo.returnArgumentsExist) { 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)) } @@ -173,7 +193,7 @@ class PostponedArgumentsAnalyzer( val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder) if (postponedVariables == null) { c.getBuilder().removePostponedVariables() - return returnArgumentsAnalysisResult + return } for ((constructor, resultType) in postponedVariables) { @@ -184,8 +204,6 @@ class PostponedArgumentsAnalyzer( c.getBuilder().addEqualityConstraint(variable.defaultType(c), resultType, CoroutinePosition()) } } - - return returnArgumentsAnalysisResult } private fun UnwrappedType?.receiver(): UnwrappedType? { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt index 37d642816ef..778061a9a6e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt @@ -135,11 +135,17 @@ class ResolvedLambdaAtom( val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?, override val expectedType: UnwrappedType? ) : 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 fun setAnalyzedResults( - resultArguments: ReturnArgumentsInfo, + resultArguments: ReturnArgumentsInfo?, subResolvedAtoms: List ) { this.resultArgumentsInfo = resultArguments @@ -150,6 +156,10 @@ class ResolvedLambdaAtom( override val outputType: UnwrappedType get() = returnType } +fun ResolvedLambdaAtom.unwrap(): ResolvedLambdaAtom { + return if (resultArgumentsInfo != null) this else subResolvedAtoms!!.single() as ResolvedLambdaAtom +} + abstract class ResolvedCallableReferenceAtom( override val atom: CallableReferenceKotlinCallArgument, override val expectedType: UnwrappedType? diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.fir.kt new file mode 100644 index 00000000000..e9c069e337e --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.fir.kt @@ -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 Iterable.myFlatMap(transform: (T) -> Iterable): List { + TODO() +} + +@OverloadResolutionByLambdaReturnType +@kotlin.jvm.JvmName("myFlatMapSequence") +public inline fun Iterable.myFlatMap(transform: (T) -> Sequence): List { + TODO() +} + +interface Name +interface DeclarationDescriptor { + val nextCandidates: List? + val nextCandidatesSeq: Sequence? + val name: Name +} + +fun test_1(name: Name, toplevelDescriptors: List): List { + val candidates = toplevelDescriptors.myFlatMap { container -> + val nextCandidates = container.nextCandidates ?: return@myFlatMap emptyList() + nextCandidates + } + return candidates +} + +fun test_2(name: Name, toplevelDescriptors: List): List { + val candidates = toplevelDescriptors.myFlatMap { container -> + val nextCandidates = container.nextCandidatesSeq ?: return@myFlatMap sequenceOf() + nextCandidates + } + return candidates +} + +fun test_3(name: Name, toplevelDescriptors: List): List { + val candidates = toplevelDescriptors.myFlatMap { container -> + val nextCandidates = container.nextCandidatesSeq!! + nextCandidates + } + return candidates +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt new file mode 100644 index 00000000000..4f11533e582 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.kt @@ -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 Iterable.myFlatMap(transform: (T) -> Iterable): List { + TODO() +} + +@OverloadResolutionByLambdaReturnType +@kotlin.jvm.JvmName("myFlatMapSequence") +public inline fun Iterable.myFlatMap(transform: (T) -> Sequence): List { + TODO() +} + +interface Name +interface DeclarationDescriptor { + val nextCandidates: List? + val nextCandidatesSeq: Sequence? + val name: Name +} + +fun test_1(name: Name, toplevelDescriptors: List): List { + val candidates = toplevelDescriptors.myFlatMap { container -> + val nextCandidates = container.nextCandidates ?: return@myFlatMap emptyList() + nextCandidates + } + return candidates +} + +fun test_2(name: Name, toplevelDescriptors: List): List { + val candidates = toplevelDescriptors.myFlatMap { container -> + val nextCandidates = container.nextCandidatesSeq ?: return@myFlatMap sequenceOf() + nextCandidates + } + return candidates +} + +fun test_3(name: Name, toplevelDescriptors: List): List { + val candidates = toplevelDescriptors.myFlatMap { container -> + val nextCandidates = container.nextCandidatesSeq!! + nextCandidates + } + return candidates +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.txt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.txt new file mode 100644 index 00000000000..cdba946cb20 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/multipleOverloads_3.txt @@ -0,0 +1,32 @@ +package + +public fun test_1(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List): kotlin.collections.List +public fun test_2(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List): kotlin.collections.List +public fun test_3(/*0*/ name: Name, /*1*/ toplevelDescriptors: kotlin.collections.List): kotlin.collections.List +public inline fun kotlin.collections.Iterable.myFlatMap(/*0*/ transform: (T) -> kotlin.collections.Iterable): kotlin.collections.List +@kotlin.OverloadResolutionByLambdaReturnType @kotlin.jvm.JvmName(name = "myFlatMapSequence") public inline fun kotlin.collections.Iterable.myFlatMap(/*0*/ transform: (T) -> kotlin.sequences.Sequence): kotlin.collections.List + +public interface DeclarationDescriptor { + public abstract val name: Name + public abstract val nextCandidates: kotlin.collections.List? + public abstract val nextCandidatesSeq: kotlin.sequences.Sequence? + 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 + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt index eec692256a8..a0200cd8f07 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_enabled.kt @@ -30,7 +30,7 @@ fun test_2() { } fun test_3() { - val x = create { 1.0 } + val x = create { 1.0 } } @OverloadResolutionByLambdaReturnType diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 34d19643ff9..9ae5e570849 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -2830,6 +2830,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW 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") public void testOverloadByLambdaReturnType_disabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 7fa263e5198..6264a49dd55 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -2830,6 +2830,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno 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") public void testOverloadByLambdaReturnType_disabled() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/overloadByLambdaReturnType_disabled.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.kt index 2be678274c3..b85d4b27eea 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.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.ResolvedCall 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.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.receiverValue @@ -76,7 +77,7 @@ fun ResolvedCall<*>.hasLastFunctionalParameterWithResult(context: BindingContext if (this is NewResolvedCallImpl<*>) { // TODO: looks like hack resolvedCallAtom.subResolvedAtoms?.firstOrNull { it is ResolvedLambdaAtom }.safeAs()?.let { lambdaAtom -> - return lambdaAtom.resultArgumentsInfo.nonErrorArguments.filterIsInstance().all { + return lambdaAtom.unwrap().resultArgumentsInfo!!.nonErrorArguments.filterIsInstance().all { val type = it.receiverValue?.type ?: return@all false predicate(type) }