From 3c698992e0f6ca4fbc60a8bf2cef2bd94e2493e3 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 7 Jul 2015 21:26:20 +0300 Subject: [PATCH] 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) --- .../kotlin/diagnostics/rendering/Renderers.kt | 3 +- .../kotlin/resolve/calls/CallResolverUtil.kt | 2 +- .../calls/tasks/AbstractTracingStrategy.java | 4 +-- .../ControlStructureTypingUtils.java | 2 +- .../typeConstructorMismatch.bounds | 2 +- .../calls/inference/ConstraintError.kt | 2 +- .../calls/inference/ConstraintPosition.kt | 8 ++--- .../calls/inference/ConstraintSystemImpl.kt | 30 +++++-------------- .../calls/inference/ConstraintSystemStatus.kt | 4 +-- 9 files changed, 22 insertions(+), 35 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt index 46879fbc1b0..a3becd143a2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt @@ -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) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt index b2243f1ed0f..f37ae53f661 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolverUtil.kt @@ -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 } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java index 69f1fec7b05..27db5955597 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java index ea78d9cf643..24c4ac42f9f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java @@ -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; } diff --git a/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds b/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds index d3c1d075e01..21e95269ed0 100644 --- a/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds +++ b/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds @@ -10,7 +10,7 @@ status: -hasConflictingConstraints: false -hasContradiction: true -hasErrorInConstrainingTypes: false --hasTypeConstructorMismatch: true +-hasTypeConstructorMismatch: false -hasTypeInferenceIncorporationError: true -hasUnknownParameters: true -hasViolatedUpperBound: false diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt index 2f73688f0b1..d657c6bd3df 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt @@ -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) \ No newline at end of file + if (constraintPosition.isParameter()) TypeConstructorMismatch(constraintPosition) else TypeInferenceError(constraintPosition) \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintPosition.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintPosition.kt index ca4b957f452..3c454600843 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintPosition.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintPosition.kt @@ -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 = - positions.flatMap { if (it is CompoundConstraintPosition) it.positions else listOf(it) }.toCollection(LinkedHashSet()) + 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 } } \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index d8dbe991601..5d8ea25b72c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -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)) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemStatus.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemStatus.kt index 1b403fb513a..458b8bcc0c3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemStatus.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemStatus.kt @@ -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 true 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 true if there is an error in constraining types.