Generate specific type inference error
only for bounds from 'parameter' positions (receiver & value arguments). They can be marked as error (with red color) explicitly later. Replaced getSystemWithoutWeakConstraints() with filterConstraintsOut(TYPE_BOUND_POSITION)
This commit is contained in:
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
@@ -244,7 +245,7 @@ public object Renderers {
|
||||
LOG.assertTrue(status.hasViolatedUpperBound(),
|
||||
renderDebugMessage("Upper bound violated renderer is applied for incorrect status", inferenceErrorData))
|
||||
|
||||
val systemWithoutWeakConstraints = constraintSystem.getSystemWithoutWeakConstraints()
|
||||
val systemWithoutWeakConstraints = constraintSystem.filterConstraintsOut(ConstraintPositionKind.TYPE_BOUND_POSITION)
|
||||
val typeParameterDescriptor = inferenceErrorData.descriptor.getTypeParameters().firstOrNull {
|
||||
!ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, true)
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public fun CallableDescriptor.hasInferredReturnType(constraintSystem: Constraint
|
||||
if (hasReturnTypeDependentOnUninferredParams(constraintSystem)) return false
|
||||
|
||||
// Expected type mismatch was reported before as 'TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH'
|
||||
if (constraintSystem.getStatus().hasOnlyErrorsFromPosition(EXPECTED_TYPE_POSITION.position())) return false
|
||||
if (constraintSystem.getStatus().hasOnlyErrorsDerivedFrom(EXPECTED_TYPE_POSITION)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -208,12 +208,12 @@ public abstract class AbstractTracingStrategy implements TracingStrategy {
|
||||
// (it's useful, when the arguments, e.g. lambdas or calls are incomplete)
|
||||
return;
|
||||
}
|
||||
if (status.hasOnlyErrorsFromPosition(EXPECTED_TYPE_POSITION.position())) {
|
||||
if (status.hasOnlyErrorsDerivedFrom(EXPECTED_TYPE_POSITION)) {
|
||||
JetType declaredReturnType = data.descriptor.getReturnType();
|
||||
if (declaredReturnType == null) return;
|
||||
|
||||
ConstraintSystem systemWithoutExpectedTypeConstraint =
|
||||
((ConstraintSystemImpl) constraintSystem).filterConstraintsOut(EXPECTED_TYPE_POSITION.position());
|
||||
((ConstraintSystemImpl) constraintSystem).filterConstraintsOut(EXPECTED_TYPE_POSITION);
|
||||
JetType substitutedReturnType = systemWithoutExpectedTypeConstraint.getResultingSubstitutor().substitute(
|
||||
declaredReturnType, Variance.OUT_VARIANCE);
|
||||
assert substitutedReturnType != null; //todo
|
||||
|
||||
+1
-1
@@ -375,7 +375,7 @@ public class ControlStructureTypingUtils {
|
||||
return;
|
||||
}
|
||||
JetExpression expression = (JetExpression) call.getCallElement();
|
||||
if (status.hasOnlyErrorsFromPosition(EXPECTED_TYPE_POSITION.position()) || status.hasConflictingConstraints()) {
|
||||
if (status.hasOnlyErrorsDerivedFrom(EXPECTED_TYPE_POSITION) || status.hasConflictingConstraints()) {
|
||||
expression.accept(checkTypeVisitor, new CheckTypeContext(trace, data.expectedType));
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ status:
|
||||
-hasConflictingConstraints: false
|
||||
-hasContradiction: true
|
||||
-hasErrorInConstrainingTypes: false
|
||||
-hasTypeConstructorMismatch: true
|
||||
-hasTypeConstructorMismatch: false
|
||||
-hasTypeInferenceIncorporationError: true
|
||||
-hasUnknownParameters: true
|
||||
-hasViolatedUpperBound: false
|
||||
|
||||
+1
-1
@@ -31,4 +31,4 @@ class TypeInferenceError(constraintPosition: ConstraintPosition): ConstraintErro
|
||||
class CannotCapture(constraintPosition: ConstraintPosition, val typeVariable: TypeParameterDescriptor): ConstraintError(constraintPosition)
|
||||
|
||||
fun newTypeInferenceOrConstructorMismatchError(constraintPosition: ConstraintPosition) =
|
||||
if (constraintPosition is CompoundConstraintPosition) TypeInferenceError(constraintPosition) else TypeConstructorMismatch(constraintPosition)
|
||||
if (constraintPosition.isParameter()) TypeConstructorMismatch(constraintPosition) else TypeInferenceError(constraintPosition)
|
||||
+4
-4
@@ -44,7 +44,7 @@ public trait ConstraintPosition {
|
||||
|
||||
fun isStrong(): Boolean = kind != TYPE_BOUND_POSITION
|
||||
|
||||
fun isCaptureAllowed(): Boolean = kind in setOf(VALUE_PARAMETER_POSITION, RECEIVER_POSITION)
|
||||
fun isParameter(): Boolean = kind in setOf(VALUE_PARAMETER_POSITION, RECEIVER_POSITION)
|
||||
}
|
||||
|
||||
private open data class ConstraintPositionImpl(override val kind: ConstraintPositionKind) : ConstraintPosition {
|
||||
@@ -58,13 +58,13 @@ class CompoundConstraintPosition(
|
||||
vararg positions: ConstraintPosition
|
||||
) : ConstraintPositionImpl(ConstraintPositionKind.COMPOUND_CONSTRAINT_POSITION) {
|
||||
val positions: Collection<ConstraintPosition> =
|
||||
positions.flatMap { if (it is CompoundConstraintPosition) it.positions else listOf(it) }.toCollection(LinkedHashSet<ConstraintPosition>())
|
||||
positions.flatMap { if (it is CompoundConstraintPosition) it.positions else listOf(it) }.toSet()
|
||||
|
||||
override fun isStrong() = positions.any { it.isStrong() }
|
||||
|
||||
override fun toString() = "$kind(${positions.joinToString()})"
|
||||
}
|
||||
|
||||
fun ConstraintPosition.equalsOrContains(position: ConstraintPosition): Boolean {
|
||||
return if (this !is CompoundConstraintPosition) this == position else positions.any { it == position }
|
||||
fun ConstraintPosition.derivedFrom(kind: ConstraintPositionKind): Boolean {
|
||||
return if (this !is CompoundConstraintPosition) this.kind == kind else positions.any { it.kind == kind }
|
||||
}
|
||||
+8
-22
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.CompoundC
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.equalsOrContains
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.ErrorUtils.FunctionPlaceholderTypeConstructor
|
||||
@@ -84,7 +84,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
override fun hasContradiction() = hasTypeConstructorMismatch() || hasConflictingConstraints()
|
||||
|| hasCannotCaptureTypesError() || hasTypeInferenceIncorporationError()
|
||||
|
||||
override fun hasViolatedUpperBound() = !isSuccessful() && getSystemWithoutWeakConstraints().getStatus().isSuccessful()
|
||||
override fun hasViolatedUpperBound() = !isSuccessful() && filterConstraintsOut(TYPE_BOUND_POSITION).getStatus().isSuccessful()
|
||||
|
||||
override fun hasConflictingConstraints() = typeParameterBounds.values().any { it.values.size() > 1 }
|
||||
|
||||
@@ -92,10 +92,10 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
|
||||
override fun hasTypeConstructorMismatch() = errors.any { it is TypeConstructorMismatch }
|
||||
|
||||
override fun hasOnlyErrorsFromPosition(constraintPosition: ConstraintPosition): Boolean {
|
||||
override fun hasOnlyErrorsDerivedFrom(kind: ConstraintPositionKind): Boolean {
|
||||
if (isSuccessful()) return false
|
||||
if (filterConstraintsOut(constraintPosition).getStatus().isSuccessful()) return true
|
||||
return errors.isNotEmpty() && errors.all { it.constraintPosition.equalsOrContains(constraintPosition) }
|
||||
if (filterConstraintsOut(kind).getStatus().isSuccessful()) return true
|
||||
return errors.isNotEmpty() && errors.all { it.constraintPosition.derivedFrom(kind) }
|
||||
}
|
||||
|
||||
override fun hasErrorInConstrainingTypes() = errors.any { it is ErrorInConstrainingType }
|
||||
@@ -175,22 +175,8 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
|
||||
public fun copy(): ConstraintSystem = createNewConstraintSystemFromThis { true }
|
||||
|
||||
public fun filterConstraintsOut(excludePosition: ConstraintPosition): ConstraintSystem {
|
||||
return filterConstraints { !it.equalsOrContains(excludePosition) }
|
||||
}
|
||||
|
||||
public fun filterConstraints(condition: (ConstraintPosition) -> Boolean): ConstraintSystem {
|
||||
return createNewConstraintSystemFromThis(condition)
|
||||
}
|
||||
|
||||
public fun getSystemWithoutWeakConstraints(): ConstraintSystem {
|
||||
return filterConstraints(fun (constraintPosition): Boolean {
|
||||
if (constraintPosition !is CompoundConstraintPosition) return constraintPosition.isStrong()
|
||||
|
||||
// 'isStrong' for compound means 'has some strong constraints'
|
||||
// but for testing absence of weak constraints we need 'has only strong constraints' here
|
||||
return constraintPosition.positions.all { it.isStrong() }
|
||||
})
|
||||
public fun filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {
|
||||
return createNewConstraintSystemFromThis { !it.derivedFrom(excludePositionKind) }
|
||||
}
|
||||
|
||||
private fun createNewConstraintSystemFromThis(
|
||||
@@ -252,7 +238,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
if (isMyTypeVariable(typeProjection.getType())) return false
|
||||
val myTypeVariable = getMyTypeVariable(typeVariable)
|
||||
|
||||
if (myTypeVariable != null && constraintPosition.isCaptureAllowed()) {
|
||||
if (myTypeVariable != null && constraintPosition.isParameter()) {
|
||||
if (depth > 0) {
|
||||
errors.add(CannotCapture(constraintPosition, myTypeVariable))
|
||||
}
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference
|
||||
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
|
||||
public trait ConstraintSystemStatus {
|
||||
/**
|
||||
@@ -69,7 +69,7 @@ public trait ConstraintSystemStatus {
|
||||
* Returns <tt>true</tt> if there is type constructor mismatch only in constraintPosition or
|
||||
* constraint system is successful without constraints from this position.
|
||||
*/
|
||||
public fun hasOnlyErrorsFromPosition(constraintPosition: ConstraintPosition): Boolean
|
||||
public fun hasOnlyErrorsDerivedFrom(kind: ConstraintPositionKind): Boolean
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if there is an error in constraining types. <p/>
|
||||
|
||||
Reference in New Issue
Block a user