KT-9835 Completion thinks receiver is nullable when it is not

#KT-9835 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-10-11 17:12:41 +03:00
parent 7b12dd498f
commit 0399772ee6
10 changed files with 73 additions and 10 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.StrictEqualityTypeChecker
import org.jetbrains.kotlin.types.typeUtil.*
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.*
fun CallableDescriptor.fuzzyReturnType() = returnType?.toFuzzyType(typeParameters)
@@ -170,13 +171,20 @@ class FuzzyType(
if (otherSubstitutedType.isError) return TypeSubstitutor.EMPTY
if (!substitutedType.checkInheritance(otherSubstitutedType)) return null
val substitution = constraintSystem.typeVariables.map { it.originalTypeParameter }.associateBy({ it.typeConstructor }) {
val type = it.defaultType
val solution = substitutor.substitute(type, Variance.INVARIANT)
TypeProjectionImpl(if (solution != null && !ErrorUtils.containsUninferredParameter(solution)) solution else type)
}
val substitutorToKeepCapturedTypes = object : DelegatedTypeSubstitution(substitutor.substitution) {
override fun approximateCapturedTypes() = false
}.buildSubstitutor()
return TypeSubstitutor.create(TypeConstructorSubstitution.createByConstructorsMap(substitution))
val substitutionMap: Map<TypeConstructor, TypeProjection> = constraintSystem.typeVariables
.map { it.originalTypeParameter }
.associateBy(
keySelector = { it.typeConstructor },
valueTransform = {
val typeProjection = TypeProjectionImpl(Variance.INVARIANT, it.defaultType)
val substitutedProjection = substitutorToKeepCapturedTypes.substitute(typeProjection)
substitutedProjection?.check { !ErrorUtils.containsUninferredParameter(it.type) } ?: typeProjection
})
return TypeConstructorSubstitution.createByConstructorsMap(substitutionMap, approximateCapturedTypes = true).buildSubstitutor()
}
}
@@ -27,8 +27,8 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.TypeNullability
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
@@ -95,7 +95,9 @@ fun <TCallable : CallableDescriptor> TCallable.substituteExtensionIfCallable(
return if (substitutors.any()) listOf(this) else listOf()
}
else {
return substitutors.map { @Suppress("UNCHECKED_CAST") (substitute(it) as TCallable) }.toList()
return substitutors
.mapNotNull { @Suppress("UNCHECKED_CAST") (substitute(it) as TCallable?) }
.toList()
}
}