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 027d2522827..4eec28ba9b4 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 @@ -96,7 +96,7 @@ class KotlinCallCompleter( kotlinConstraintSystemCompleter.runCompletion( constraintSystem.asConstraintSystemCompleterContext(), completionMode, - resolvedCallAtom, + listOf(resolvedCallAtom), returnType ) { if (collectAllCandidatesMode) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index e72b5c2c406..0d61d793b37 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.resolve.calls.inference.components @@ -50,22 +39,22 @@ class KotlinConstraintSystemCompleter( fun runCompletion( c: Context, completionMode: ConstraintSystemCompletionMode, - topLevelPrimitive: ResolvedAtom, + topLevelAtoms: List, topLevelType: UnwrappedType, analyze: (PostponedResolvedAtom) -> Unit ) { while (true) { - if (analyzePostponeArgumentIfPossible(c, topLevelPrimitive, analyze)) continue + if (analyzePostponeArgumentIfPossible(c, topLevelAtoms, analyze)) continue - val allTypeVariables = getOrderedAllTypeVariables(c, topLevelPrimitive) - val postponedKtPrimitives = getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive) + val allTypeVariables = getOrderedAllTypeVariables(c, topLevelAtoms) + val postponedKtPrimitives = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms) val variableForFixation = variableFixationFinder.findFirstVariableForFixation( c, allTypeVariables, postponedKtPrimitives, completionMode, topLevelType ) if (shouldForceCallableReferenceOrLambdaResolution(completionMode, variableForFixation)) { - if (forcePostponedAtomResolution(topLevelPrimitive, analyze)) continue - if (forcePostponedAtomResolution(topLevelPrimitive, analyze)) continue + if (forcePostponedAtomResolution(topLevelAtoms, analyze)) continue + if (forcePostponedAtomResolution(topLevelAtoms, analyze)) continue } if (variableForFixation != null) { @@ -85,7 +74,7 @@ class KotlinConstraintSystemCompleter( if (completionMode == ConstraintSystemCompletionMode.FULL) { // force resolution for all not-analyzed argument's - getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive).forEach(analyze) + getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze) } } @@ -102,10 +91,10 @@ class KotlinConstraintSystemCompleter( // true if we do analyze private fun analyzePostponeArgumentIfPossible( c: Context, - topLevelPrimitive: ResolvedAtom, + topLevelAtoms: List, analyze: (PostponedResolvedAtom) -> Unit ): Boolean { - for (argument in getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive)) { + for (argument in getOrderedNotAnalyzedPostponedArguments(topLevelAtoms)) { if (canWeAnalyzeIt(c, argument)) { analyze(argument) return true @@ -116,15 +105,15 @@ class KotlinConstraintSystemCompleter( // true if we find some callable reference and run resolution for it. Note that such resolution can be unsuccessful private inline fun forcePostponedAtomResolution( - topLevelPrimitive: ResolvedAtom, + topLevelAtoms: List, analyze: (PostponedResolvedAtom) -> Unit ): Boolean { - val postponedArgument = getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive).firstIsInstanceOrNull() ?: return false + val postponedArgument = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).firstIsInstanceOrNull() ?: return false analyze(postponedArgument) return true } - private fun getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive: ResolvedAtom): List { + private fun getOrderedNotAnalyzedPostponedArguments(topLevelAtoms: List): List { fun ResolvedAtom.process(to: MutableList) { to.addIfNotNull(this.safeAs()?.takeUnless { it.analyzed }) @@ -132,11 +121,17 @@ class KotlinConstraintSystemCompleter( subResolvedAtoms.forEach { it.process(to) } } } - return arrayListOf().apply { topLevelPrimitive.process(this) } + + val notAnalyzedArguments = arrayListOf() + for (primitive in topLevelAtoms) { + primitive.process(notAnalyzedArguments) + } + + return notAnalyzedArguments } - private fun getOrderedAllTypeVariables(c: Context, topLevelPrimitive: ResolvedAtom): List { - fun ResolvedAtom.process(to: MutableList) { + private fun getOrderedAllTypeVariables(c: Context, topLevelAtoms: List): List { + fun ResolvedAtom.process(to: LinkedHashSet) { val typeVariables = when (this) { is ResolvedCallAtom -> substitutor.freshVariables is ResolvedCallableReferenceAtom -> candidate?.freshSubstitutor?.freshVariables.orEmpty() @@ -153,14 +148,18 @@ class KotlinConstraintSystemCompleter( } } - val result = arrayListOf().apply { topLevelPrimitive.process(this) } + // Note that it's important to use Set here, because several atoms can share the same type variable + val result = linkedSetOf() + for (primitive in topLevelAtoms) { + primitive.process(result) + } assert(result.size == c.notFixedTypeVariables.size) { val notFoundTypeVariables = c.notFixedTypeVariables.keys.toMutableSet().removeAll(result) "Not all type variables found: $notFoundTypeVariables" } - return result + return result.toList() }