From cb494c46d7c1403da97ec8df1b7296c7c562cef3 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Thu, 4 May 2017 00:22:45 +0300 Subject: [PATCH] [NI] Add initial constraint to IncorporationConstraintPosition --- .../DiagnosticReporterByTrackingStrategy.kt | 5 +-- .../components/ConstraintIncorporator.kt | 33 +++++++++---------- .../components/ConstraintInjector.kt | 25 +++++++------- .../model/ConstraintPositionAndErrors.kt | 6 ++-- .../inference/model/ConstraintStorage.kt | 2 +- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index 5110f418d89..fd74e06f523 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -150,12 +150,13 @@ class DiagnosticReporterByTrackingStrategy( when (diagnostic.javaClass) { NewConstraintError::class.java -> { val constraintError = diagnostic as NewConstraintError - (constraintError.position as? ArgumentConstraintPosition)?.let { + val position = constraintError.position.from + (position as? ArgumentConstraintPosition)?.let { val expression = it.argument.psiExpression ?: return if (reportConstantTypeMismatch(constraintError, expression)) return trace.report(Errors.TYPE_MISMATCH.on(expression, constraintError.upperType, constraintError.lowerType)) } - (constraintError.position as? ExplicitTypeParameterConstraintPosition)?.let { + (position as? ExplicitTypeParameterConstraintPosition)?.let { val typeArgumentReference = (it.typeArgument as SimpleTypeArgumentImpl).typeReference trace.report(UPPER_BOUND_VIOLATED.on(typeArgumentReference, constraintError.upperType, constraintError.lowerType)) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt index caf210aac11..fde647fe881 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt @@ -16,8 +16,6 @@ package org.jetbrains.kotlin.resolve.calls.inference.components -import org.jetbrains.kotlin.types.TypeApproximator -import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.resolve.calls.inference.model.* import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.CaptureStatus @@ -40,26 +38,26 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) { fun getConstraintsForVariable(typeVariable: NewTypeVariable): Collection - fun addNewIncorporatedConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: IncorporationConstraintPosition) + fun addNewIncorporatedConstraint(lowerType: UnwrappedType, upperType: UnwrappedType) } // \alpha is typeVariable, \beta -- other type variable registered in ConstraintStorage - fun incorporate(c: Context, typeVariable: NewTypeVariable, constraint: Constraint, position: IncorporationConstraintPosition) { + fun incorporate(c: Context, typeVariable: NewTypeVariable, constraint: Constraint) { // we shouldn't incorporate recursive constraint -- It is too dangerous if (constraint.type.contains { it.constructor == typeVariable.freshTypeConstructor }) return - directWithVariable(c, typeVariable, constraint, position) - otherInsideMyConstraint(c, typeVariable, constraint, position) - insideOtherConstraint(c, typeVariable, constraint, position) + directWithVariable(c, typeVariable, constraint) + otherInsideMyConstraint(c, typeVariable, constraint) + insideOtherConstraint(c, typeVariable, constraint) } // A <:(=) \alpha <:(=) B => A <: B - private fun directWithVariable(c: Context, typeVariable: NewTypeVariable, constraint: Constraint, position: IncorporationConstraintPosition) { + private fun directWithVariable(c: Context, typeVariable: NewTypeVariable, constraint: Constraint) { // \alpha <: constraint.type if (constraint.kind != ConstraintKind.LOWER) { c.getConstraintsForVariable(typeVariable).forEach { if (it.kind != ConstraintKind.UPPER) { - c.addNewIncorporatedConstraint(it.type, constraint.type, position) + c.addNewIncorporatedConstraint(it.type, constraint.type) } } } @@ -68,14 +66,14 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) { if (constraint.kind != ConstraintKind.UPPER) { c.getConstraintsForVariable(typeVariable).forEach { if (it.kind != ConstraintKind.LOWER) { - c.addNewIncorporatedConstraint(constraint.type, it.type, position) + c.addNewIncorporatedConstraint(constraint.type, it.type) } } } } // \alpha <: Inv<\beta>, \beta <: Number => \alpha <: Inv - private fun otherInsideMyConstraint(c: Context, typeVariable: NewTypeVariable, constraint: Constraint, position: IncorporationConstraintPosition) { + private fun otherInsideMyConstraint(c: Context, typeVariable: NewTypeVariable, constraint: Constraint) { val otherInMyConstraint = SmartSet.create() constraint.type.contains { otherInMyConstraint.addIfNotNull(c.getTypeVariable(it.constructor)) @@ -86,19 +84,19 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) { // to avoid ConcurrentModificationException val otherConstraints = ArrayList(c.getConstraintsForVariable(otherTypeVariable)) for (otherConstraint in otherConstraints) { - generateNewConstraint(c, typeVariable, constraint, otherTypeVariable, otherConstraint, position) + generateNewConstraint(c, typeVariable, constraint, otherTypeVariable, otherConstraint) } } } // \alpha <: Number, \beta <: Inv<\alpha> => \beta <: Inv - private fun insideOtherConstraint(c: Context, typeVariable: NewTypeVariable, constraint: Constraint, position: IncorporationConstraintPosition) { + private fun insideOtherConstraint(c: Context, typeVariable: NewTypeVariable, constraint: Constraint) { for (typeVariableWithConstraint in c.allTypeVariablesWithConstraints) { val constraintsWhichConstraintMyVariable = typeVariableWithConstraint.constraints.filter { it.type.contains { it.constructor == typeVariable.freshTypeConstructor } } constraintsWhichConstraintMyVariable.forEach { - generateNewConstraint(c, typeVariableWithConstraint.typeVariable, it, typeVariable, constraint, position) + generateNewConstraint(c, typeVariableWithConstraint.typeVariable, it, typeVariable, constraint) } } } @@ -108,8 +106,7 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) { targetVariable: NewTypeVariable, baseConstraint: Constraint, otherVariable: NewTypeVariable, - otherConstraint: Constraint, - position: IncorporationConstraintPosition + otherConstraint: Constraint ) { val typeForApproximation = when (otherConstraint.kind) { ConstraintKind.EQUALITY -> { @@ -134,10 +131,10 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) { } if (baseConstraint.kind != ConstraintKind.UPPER) { - c.addNewIncorporatedConstraint(approximateCapturedTypes(typeForApproximation, toSuper = false), targetVariable.defaultType, position) + c.addNewIncorporatedConstraint(approximateCapturedTypes(typeForApproximation, toSuper = false), targetVariable.defaultType) } if (baseConstraint.kind != ConstraintKind.LOWER) { - c.addNewIncorporatedConstraint(targetVariable.defaultType, approximateCapturedTypes(typeForApproximation, toSuper = true), position) + c.addNewIncorporatedConstraint(targetVariable.defaultType, approximateCapturedTypes(typeForApproximation, toSuper = true)) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt index 0da3d6ab6d8..97313d0f590 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt @@ -40,25 +40,28 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val } fun addInitialSubtypeConstraint(c: Context, lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) { - c.addInitialConstraint(InitialConstraint(lowerType, upperType, ConstraintKind.UPPER, position)) + val initialConstraint = InitialConstraint(lowerType, upperType, ConstraintKind.UPPER, position) + val incorporationPosition = IncorporationConstraintPosition(position, initialConstraint) + c.addInitialConstraint(initialConstraint) updateAllowedTypeDepth(c, lowerType) updateAllowedTypeDepth(c, upperType) - addSubTypeConstraintAndIncorporateIt(c, lowerType, upperType, position) + addSubTypeConstraintAndIncorporateIt(c, lowerType, upperType, incorporationPosition) } fun addInitialEqualityConstraint(c: Context, a: UnwrappedType, b: UnwrappedType, position: ConstraintPosition) { - c.addInitialConstraint(InitialConstraint(a, b, ConstraintKind.EQUALITY, position)) + val initialConstraint = InitialConstraint(a, b, ConstraintKind.EQUALITY, position) + val incorporationPosition = IncorporationConstraintPosition(position, initialConstraint) + c.addInitialConstraint(initialConstraint) updateAllowedTypeDepth(c, a) updateAllowedTypeDepth(c, b) - addSubTypeConstraintAndIncorporateIt(c, a, b, position) - addSubTypeConstraintAndIncorporateIt(c, b, a, position) + addSubTypeConstraintAndIncorporateIt(c, a, b, incorporationPosition) + addSubTypeConstraintAndIncorporateIt(c, b, a, incorporationPosition) } - private fun addSubTypeConstraintAndIncorporateIt(c: Context, lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) { - val incorporatePosition = IncorporationConstraintPosition(position) + private fun addSubTypeConstraintAndIncorporateIt(c: Context, lowerType: UnwrappedType, upperType: UnwrappedType, incorporatePosition: IncorporationConstraintPosition) { val possibleNewConstraints = Stack>() - val typeCheckerContext = TypeCheckerContext(c, position, lowerType, upperType, possibleNewConstraints) + val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints) typeCheckerContext.runIsSubtypeOf(lowerType, upperType) while (possibleNewConstraints.isNotEmpty()) { @@ -67,7 +70,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val // it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints constraints.addConstraint(constraint)?.let { - constraintIncorporator.incorporate(typeCheckerContext, typeVariable, it, incorporatePosition) + constraintIncorporator.incorporate(typeCheckerContext, typeVariable, it) } } } @@ -94,7 +97,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val private inner class TypeCheckerContext( val c: Context, - val position: ConstraintPosition, + val position: IncorporationConstraintPosition, val baseLowerType: UnwrappedType, val baseUpperType: UnwrappedType, val possibleNewConstraints: MutableList> = ArrayList() @@ -159,7 +162,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val } // from ConstraintIncorporator.Context - override fun addNewIncorporatedConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: IncorporationConstraintPosition) { + override fun addNewIncorporatedConstraint(lowerType: UnwrappedType, upperType: UnwrappedType) { if (c.isAllowedType(lowerType) && c.isAllowedType(upperType)) { runIsSubtypeOf(lowerType, upperType) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt index ca46a6e97d1..a2503300367 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt @@ -40,15 +40,15 @@ class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintP override fun toString() = "Fix variable $variable" } -class IncorporationConstraintPosition(val from: ConstraintPosition) : ConstraintPosition() { - override fun toString() = "Incorporate $from" +class IncorporationConstraintPosition(val from: ConstraintPosition, val initialConstraint: InitialConstraint) : ConstraintPosition() { + override fun toString() = "Incorporate $initialConstraint from position $from" } @Deprecated("Should be used only in SimpleConstraintSystemImpl") object SimpleConstraintSystemConstraintPosition : ConstraintPosition() -class NewConstraintError(val lowerType: UnwrappedType, val upperType: UnwrappedType, val position: ConstraintPosition): +class NewConstraintError(val lowerType: UnwrappedType, val upperType: UnwrappedType, val position: IncorporationConstraintPosition): KotlinCallDiagnostic(ResolutionCandidateApplicability.INAPPLICABLE) { override fun report(reporter: DiagnosticReporter) = reporter.constraintError(this) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt index da10af33336..37cb12c4ad3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt @@ -78,7 +78,7 @@ enum class ConstraintKind { class Constraint( val kind: ConstraintKind, val type: UnwrappedType, // flexible types here is allowed - val position: ConstraintPosition, + val position: IncorporationConstraintPosition, val typeHashCode: Int = type.hashCode() ) { override fun equals(other: Any?): Boolean {