Add expected type constraints in a builder inference call
This commit is contained in:
+8
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.reportTrailingLambdaErrorOr
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceExpectedTypeConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
@@ -396,6 +397,13 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
}
|
||||
}
|
||||
|
||||
(position as? BuilderInferenceExpectedTypeConstraintPosition)?.let {
|
||||
val inferredType =
|
||||
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
|
||||
else error.upperKotlinType.makeNullable()
|
||||
trace.report(TYPE_MISMATCH.on(it.topLevelCall, error.upperKotlinType, inferredType))
|
||||
}
|
||||
|
||||
(position as? ExplicitTypeParameterConstraintPositionImpl)?.let {
|
||||
val typeArgumentReference = (it.typeArgument as SimpleTypeArgumentImpl).typeReference
|
||||
val diagnosticFactory = if (error.isWarning) UPPER_BOUND_VIOLATED_WARNING else UPPER_BOUND_VIOLATED
|
||||
|
||||
+19
@@ -324,6 +324,23 @@ class BuilderInferenceSession(
|
||||
return introducedConstraint
|
||||
}
|
||||
|
||||
fun addExpectedTypeConstraint(
|
||||
callExpression: KtExpression,
|
||||
a: KotlinType,
|
||||
b: KotlinType
|
||||
) {
|
||||
val nonFixedToVariablesSubstitutor: NewTypeSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
||||
val (lower, upper) = substituteNotFixedVariables(a, b, nonFixedToVariablesSubstitutor)
|
||||
val position = BuilderInferenceExpectedTypeConstraintPosition(callExpression)
|
||||
val currentSubstitutor = commonSystem.buildCurrentSubstitutor()
|
||||
|
||||
commonSystem.addSubtypeConstraint(
|
||||
currentSubstitutor.safeSubstitute(commonSystem.typeSystemContext, lower),
|
||||
currentSubstitutor.safeSubstitute(commonSystem.typeSystemContext, upper),
|
||||
position
|
||||
)
|
||||
}
|
||||
|
||||
private fun substituteNotFixedVariables(
|
||||
lowerType: KotlinType,
|
||||
upperType: KotlinType,
|
||||
@@ -530,3 +547,5 @@ class ComposedSubstitutor(val left: NewTypeSubstitutor, val right: NewTypeSubsti
|
||||
|
||||
override val isEmpty: Boolean get() = left.isEmpty && right.isEmpty
|
||||
}
|
||||
|
||||
class BuilderInferenceExpectedTypeConstraintPosition(callElement: KtExpression) : ExpectedTypeConstraintPosition<KtExpression>(callElement)
|
||||
|
||||
@@ -35,15 +35,14 @@ import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.*;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.KotlinTypeKt;
|
||||
import org.jetbrains.kotlin.types.TypeConstructor;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
|
||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -287,6 +286,11 @@ public class DataFlowAnalyzer {
|
||||
@NotNull Ref<Boolean> hasError,
|
||||
boolean reportErrorForTypeMismatch
|
||||
) {
|
||||
if (!noExpectedType(c.expectedType) && TypeUtilsKt.contains(expressionType, (type) -> type instanceof StubType)) {
|
||||
if (c.inferenceSession instanceof BuilderInferenceSession) {
|
||||
((BuilderInferenceSession) c.inferenceSession).addExpectedTypeConstraint(expression, expressionType, c.expectedType);
|
||||
}
|
||||
}
|
||||
if (noExpectedType(c.expectedType) || !c.expectedType.getConstructor().isDenotable() ||
|
||||
kotlinTypeChecker.isSubtypeOf(expressionType, c.expectedType)) {
|
||||
return expressionType;
|
||||
|
||||
Reference in New Issue
Block a user