[NI] Support @OnlyInputTypes annotation. #KT-29307 fixed
This commit is contained in:
+15
@@ -8,9 +8,14 @@ package org.jetbrains.kotlin.resolve.calls.inference.model
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.trimToSize
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||
import org.jetbrains.kotlin.types.typeUtil.unCapture
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.LinkedHashMap
|
||||
|
||||
@@ -27,6 +32,16 @@ class MutableVariableWithConstraints(
|
||||
return simplifiedConstraints!!
|
||||
}
|
||||
|
||||
// see @OnlyInputTypes annotation
|
||||
val projectedInputCallTypes: Collection<UnwrappedType>
|
||||
get() =
|
||||
mutableConstraints.filter {
|
||||
val position = it.position.from
|
||||
position is ArgumentConstraintPosition || position is ReceiverConstraintPosition || position is ExpectedTypeConstraintPosition
|
||||
}.map {
|
||||
(it.type as KotlinType).unCapture().unwrap()
|
||||
}
|
||||
|
||||
private val mutableConstraints = ArrayList(constraints)
|
||||
|
||||
private var simplifiedConstraints: List<Constraint>? = null
|
||||
|
||||
+26
-2
@@ -9,12 +9,16 @@ import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||
import org.jetbrains.kotlin.resolve.calls.model.OnlyInputTypesDiagnostic
|
||||
import org.jetbrains.kotlin.types.IntersectionTypeConstructor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import kotlin.math.max
|
||||
|
||||
class NewConstraintSystemImpl(
|
||||
@@ -247,7 +251,8 @@ class NewConstraintSystemImpl(
|
||||
checkState(State.BUILDING, State.COMPLETION)
|
||||
|
||||
constraintInjector.addInitialEqualityConstraint(this, variable.defaultType(), resultType, FixVariableConstraintPosition(variable))
|
||||
notFixedTypeVariables.remove(variable.freshTypeConstructor())
|
||||
val variableWithConstraints = notFixedTypeVariables.remove(variable.freshTypeConstructor())
|
||||
checkOnlyInputTypesAnnotation(variableWithConstraints, resultType)
|
||||
|
||||
for (variableWithConstraint in notFixedTypeVariables.values) {
|
||||
variableWithConstraint.removeConstrains {
|
||||
@@ -258,6 +263,25 @@ class NewConstraintSystemImpl(
|
||||
storage.fixedTypeVariables[variable.freshTypeConstructor()] = resultType
|
||||
}
|
||||
|
||||
private fun checkOnlyInputTypesAnnotation(
|
||||
variableWithConstraints: MutableVariableWithConstraints?,
|
||||
resultType: KotlinTypeMarker
|
||||
) {
|
||||
if (resultType !is KotlinType) return
|
||||
if (variableWithConstraints == null || variableWithConstraints.typeVariable.safeAs<NewTypeVariable>()?.hasOnlyInputTypesAnnotation() != true ) return
|
||||
val projectedInputCallTypes = variableWithConstraints.projectedInputCallTypes
|
||||
val resultTypeIsInputType = projectedInputCallTypes.any { inputType ->
|
||||
val constructor = inputType.constructor
|
||||
if (constructor is IntersectionTypeConstructor)
|
||||
constructor.supertypes.any { NewKotlinTypeChecker.equalTypes(resultType, it) }
|
||||
else
|
||||
NewKotlinTypeChecker.equalTypes(resultType, inputType)
|
||||
}
|
||||
if (!resultTypeIsInputType) {
|
||||
addError(OnlyInputTypesDiagnostic(variableWithConstraints.typeVariable as NewTypeVariable))
|
||||
}
|
||||
}
|
||||
|
||||
// KotlinConstraintSystemCompleter.Context, PostponedArgumentsAnalyzer.Context
|
||||
override fun canBeProper(type: KotlinTypeMarker): Boolean {
|
||||
checkState(State.BUILDING, State.COMPLETION)
|
||||
|
||||
+9
-2
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.calls.model.LambdaKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
@@ -53,15 +54,21 @@ sealed class NewTypeVariable(builtIns: KotlinBuiltIns, name: String) : TypeVaria
|
||||
nullable = false, memberScope = builtIns.any.unsubstitutedMemberScope
|
||||
)
|
||||
|
||||
abstract fun hasOnlyInputTypesAnnotation(): Boolean
|
||||
|
||||
override fun toString() = freshTypeConstructor.toString()
|
||||
}
|
||||
|
||||
class TypeVariableFromCallableDescriptor(
|
||||
val originalTypeParameter: TypeParameterDescriptor
|
||||
) : NewTypeVariable(originalTypeParameter.builtIns, originalTypeParameter.name.identifier)
|
||||
) : NewTypeVariable(originalTypeParameter.builtIns, originalTypeParameter.name.identifier) {
|
||||
override fun hasOnlyInputTypesAnnotation(): Boolean = originalTypeParameter.hasOnlyInputTypesAnnotation()
|
||||
}
|
||||
|
||||
class TypeVariableForLambdaReturnType(
|
||||
val lambdaArgument: LambdaKotlinCallArgument,
|
||||
builtIns: KotlinBuiltIns,
|
||||
name: String
|
||||
) : NewTypeVariable(builtIns, name)
|
||||
) : NewTypeVariable(builtIns, name) {
|
||||
override fun hasOnlyInputTypesAnnotation(): Boolean = false
|
||||
}
|
||||
|
||||
+7
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceCandidate
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.*
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
@@ -195,4 +196,10 @@ class ArgumentTypeMismatchDiagnostic(
|
||||
override fun report(reporter: DiagnosticReporter) {
|
||||
reporter.onCallArgument(expressionArgument, this)
|
||||
}
|
||||
}
|
||||
|
||||
class OnlyInputTypesDiagnostic(val typeVariable: NewTypeVariable) : KotlinCallDiagnostic(INAPPLICABLE) {
|
||||
override fun report(reporter: DiagnosticReporter) {
|
||||
reporter.onCall(this)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user