[NI] Preserve annotations during type substitution

#KT-31346 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2019-05-07 17:55:03 +03:00
parent 2c26dc3af6
commit c283e15425
14 changed files with 31 additions and 27 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
@@ -41,6 +42,7 @@ interface KotlinResolutionCallbacks {
receiverType: UnwrappedType?,
parameters: List<UnwrappedType>,
expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables
annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>
): Pair<List<KotlinCallArgument>, InferenceSession?>
@@ -140,7 +140,7 @@ class KotlinCallCompleter(
private fun KotlinResolutionCandidate.returnTypeWithSmartCastInfo(resolutionCallbacks: KotlinResolutionCallbacks): UnwrappedType? {
val returnType = resolvedCall.candidateDescriptor.returnType?.unwrap() ?: return null
val returnTypeWithSmartCastInfo = computeReturnTypeWithSmartCastInfo(returnType, resolutionCallbacks)
return resolvedCall.substitutor.substituteKeepAnnotations(returnTypeWithSmartCastInfo)
return resolvedCall.substitutor.safeSubstitute(returnTypeWithSmartCastInfo)
}
private fun KotlinResolutionCandidate.addExpectedTypeConstraint(
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.addSubsystemFromArgument
import org.jetbrains.kotlin.resolve.calls.inference.model.*
@@ -105,6 +106,7 @@ class PostponedArgumentsAnalyzer(
receiver,
parameters,
expectedTypeForReturnArguments,
lambda.expectedType?.annotations ?: Annotations.EMPTY,
stubsForPostponedVariables.cast()
)
@@ -290,7 +290,7 @@ private fun KotlinResolutionCandidate.prepareExpectedType(
callComponents.languageVersionSettings
)
val resultType = knownTypeParametersResultingSubstitutor?.substitute(argumentType) ?: argumentType
return resolvedCall.substitutor.substituteKeepAnnotations(resultType)
return resolvedCall.substitutor.safeSubstitute(resultType)
}
private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
import org.jetbrains.kotlin.types.*
@@ -17,9 +18,7 @@ import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
interface NewTypeSubstitutor: TypeSubstitutorMarker {
fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType?
fun safeSubstitute(type: UnwrappedType): UnwrappedType = substitute(type, runCapturedChecks = true, keepAnnotation = false) ?: type
fun substituteKeepAnnotations(type: UnwrappedType): UnwrappedType =
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
@@ -114,7 +113,7 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
// simple classifier type
var replacement = substituteNotNullTypeWithConstructor(typeConstructor) ?: return null
if (keepAnnotation) {
replacement = replacement.replaceAnnotations(type.annotations)
replacement = replacement.replaceAnnotations(CompositeAnnotations(replacement.annotations, type.annotations))
}
if (type.isMarkedNullable) {
replacement = replacement.makeNullableAsSpecified(true)