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 ff7b6cec515..7e011158e1b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt @@ -381,7 +381,7 @@ public object Renderers { val renderedBound = arrow + renderer.renderType(bound.constrainingType) + if (!bound.isProper) "*" else "" if (short) renderedBound else renderedBound + '(' + bound.position + ')' } - val typeVariableName = typeBounds.typeVariable.getName() + val typeVariableName = typeBounds.typeVariable.name return if (typeBounds.bounds.isEmpty()) { typeVariableName.asString() } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt index 106a4194aed..f44a117aef8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintError.kt @@ -28,7 +28,7 @@ class ErrorInConstrainingType(constraintPosition: ConstraintPosition): Constrain class TypeInferenceError(constraintPosition: ConstraintPosition): ConstraintError(constraintPosition) -class CannotCapture(constraintPosition: ConstraintPosition, val typeVariable: TypeParameterDescriptor): ConstraintError(constraintPosition) +class CannotCapture(constraintPosition: ConstraintPosition, val typeVariable: TypeVariable): ConstraintError(constraintPosition) fun newTypeInferenceOrParameterConstraintError(constraintPosition: ConstraintPosition) = if (constraintPosition.isParameter()) ParameterConstraintError(constraintPosition) else TypeInferenceError(constraintPosition) \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt index c11719773fc..4d60b0fd70b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt @@ -32,17 +32,17 @@ interface ConstraintSystem { /** * Returns a set of all registered type variables. */ - val typeVariables: Set + val typeVariables: Set - fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeParameterDescriptor + fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable - fun variableToDescriptor(typeVariable: TypeParameterDescriptor): TypeParameterDescriptor + fun variableToDescriptor(typeVariable: TypeVariable): TypeParameterDescriptor /** * Returns the resulting type constraints of solving the constraint system for specific type parameter descriptor. * Throws IllegalArgumentException if the type parameter descriptor is not known to the system. */ - fun getTypeBounds(typeVariable: TypeParameterDescriptor): TypeBounds + fun getTypeBounds(typeVariable: TypeVariable): TypeBounds /** * Returns the result of solving the constraint system (mapping from the type variable to the resulting type projection). diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt index c886720c9c2..c8bde492eaf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.hasNoInferAnnotation -import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure @@ -47,22 +46,20 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { EQUAL(EXACT_BOUND) } - internal val allTypeParameterBounds = LinkedHashMap() - internal val externalTypeParameters = HashSet() - internal val cachedTypeForVariable = HashMap() - internal val usedInBounds = HashMap>() + internal val allTypeParameterBounds = LinkedHashMap() + internal val usedInBounds = HashMap>() internal val errors = ArrayList() internal val initialConstraints = ArrayList() - internal val descriptorToVariable = LinkedHashMap() - internal val variableToDescriptor = LinkedHashMap() + internal val descriptorToVariable = LinkedHashMap() + internal val variableToDescriptor = LinkedHashMap() private val descriptorToVariableSubstitutor: TypeSubstitutor by lazy { TypeSubstitutor.create(object : TypeConstructorSubstitution() { override fun get(key: TypeConstructor): TypeProjection? { val descriptor = key.declarationDescriptor if (descriptor !is TypeParameterDescriptor) return null - val typeParameterDescriptor = descriptorToVariable[descriptor] ?: return null - return TypeProjectionImpl(typeParameterDescriptor.defaultType) + val typeVariable = descriptorToVariable[descriptor] ?: return null + return TypeProjectionImpl(typeVariable.type) } }) } @@ -70,14 +67,15 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { override fun registerTypeVariables(typeParameters: Collection, external: Boolean): TypeSubstitutor { if (typeParameters.isEmpty()) return TypeSubstitutor.EMPTY - val typeVariables = if (external) { - externalTypeParameters.addAll(typeParameters) + val typeVariables = (if (external) { typeParameters.toList() } else ArrayList(typeParameters.size).apply { DescriptorSubstitutor.substituteTypeParameters( typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, this ) + }).map { typeParameter -> + TypeVariable(typeParameter, external) } for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) { @@ -87,29 +85,28 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { } for ((typeVariable, typeBounds) in allTypeParameterBounds) { - for (declaredUpperBound in typeVariable.upperBounds) { + for (declaredUpperBound in typeVariable.freshTypeParameter.upperBounds) { if (declaredUpperBound.isDefaultBound()) continue //todo remove this line (?) - val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.index)) + val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.freshTypeParameter.index)) addBound(typeVariable, declaredUpperBound, UPPER_BOUND, context) } } return TypeSubstitutor.create(TypeConstructorSubstitution.createByParametersMap( - typeParameters.zip(TypeUtils.getDefaultTypeProjections(typeVariables)).toMap() + typeParameters.zip(TypeUtils.getDefaultTypeProjections(typeVariables.map { it.freshTypeParameter })).toMap() )) } - internal val TypeParameterDescriptor.correspondingType: KotlinType - get() = cachedTypeForVariable.getOrPut(this) { - KotlinTypeImpl.create(Annotations.EMPTY, typeConstructor, false, listOf(), MemberScope.Empty) - } - private fun KotlinType.isProper() = !TypeUtils.containsSpecialType(this) { type -> type.constructor.declarationDescriptor.let { it is TypeParameterDescriptor && isMyTypeVariable(it) } } - internal fun getNestedTypeVariables(type: KotlinType): List = - type.getNestedTypeParameters().filter { isMyTypeVariable(it) } + internal fun getNestedTypeVariables(type: KotlinType): List { + val allTypeVariables = allTypeParameterBounds.keys + return type.getNestedTypeParameters().map { nestedTypeParameter -> + allTypeVariables.find { it.freshTypeParameter == nestedTypeParameter } + }.filterNotNull() + } override fun addSupertypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) { val newSubjectType = descriptorToVariableSubstitutor.substitute(subjectType, Variance.INVARIANT) @@ -248,7 +245,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { } internal fun addBound( - typeVariable: TypeParameterDescriptor, + typeVariable: TypeVariable, constrainingType: KotlinType, kind: TypeBounds.BoundKind, constraintContext: ConstraintContext @@ -315,13 +312,13 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { } private fun generateTypeParameterCaptureConstraint( - typeVariable: TypeParameterDescriptor, + typeVariable: TypeVariable, constrainingTypeProjection: TypeProjection, constraintContext: ConstraintContext, isTypeMarkedNullable: Boolean ) { - if (!typeVariable.upperBounds.let { it.size == 1 && it.single().isDefaultBound() } && - constrainingTypeProjection.projectionKind == Variance.IN_VARIANCE) { + if (!typeVariable.freshTypeParameter.upperBounds.let { it.size == 1 && it.single().isDefaultBound() } && + constrainingTypeProjection.projectionKind == Variance.IN_VARIANCE) { errors.add(CannotCapture(constraintContext.position, typeVariable)) } val typeProjection = if (isTypeMarkedNullable) { @@ -334,31 +331,30 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { addBound(typeVariable, capturedType, EXACT_BOUND, constraintContext) } - internal fun getBoundsUsedIn(typeVariable: TypeParameterDescriptor): List = usedInBounds[typeVariable] ?: emptyList() + internal fun getBoundsUsedIn(typeVariable: TypeVariable): List = usedInBounds[typeVariable] ?: emptyList() - internal fun getTypeBounds(descriptor: TypeParameterDescriptor): TypeBoundsImpl { - val variable = descriptorToVariable[descriptor] - if (variable != null && variable != descriptor) { - return getTypeBounds(variable) - } - return allTypeParameterBounds[descriptor] ?: - throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $descriptor") + internal fun getTypeBounds(variable: TypeVariable): TypeBoundsImpl { + return allTypeParameterBounds[variable] ?: + throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $variable") } - private fun isMyTypeVariable(typeVariable: TypeParameterDescriptor) = allTypeParameterBounds.contains(typeVariable) + private fun isMyTypeVariable(typeParameter: TypeParameterDescriptor) = + allTypeParameterBounds.keys.any { it.freshTypeParameter == typeParameter } internal fun isMyTypeVariable(type: KotlinType): Boolean = getMyTypeVariable(type) != null - internal fun getMyTypeVariable(type: KotlinType): TypeParameterDescriptor? { + internal fun getMyTypeVariable(type: KotlinType): TypeVariable? { val typeParameterDescriptor = type.constructor.declarationDescriptor as? TypeParameterDescriptor - return if (typeParameterDescriptor != null && isMyTypeVariable(typeParameterDescriptor)) typeParameterDescriptor else null + return if (typeParameterDescriptor != null) + allTypeParameterBounds.keys.find { it.freshTypeParameter == typeParameterDescriptor } + else null } private fun storeInitialConstraint(constraintKind: ConstraintKind, subType: KotlinType, superType: KotlinType, position: ConstraintPosition) { initialConstraints.add(Constraint(constraintKind, subType, superType, position)) } - private fun fixVariable(typeVariable: TypeParameterDescriptor) { + private fun fixVariable(typeVariable: TypeVariable) { val typeBounds = getTypeBounds(typeVariable) if (typeBounds.isFixed) return typeBounds.setFixed() @@ -373,14 +369,15 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { override fun fixVariables() { // todo variables should be fixed in the right order - val (external, functionTypeParameters) = allTypeParameterBounds.keys.partition { it in externalTypeParameters } + val (external, functionTypeParameters) = allTypeParameterBounds.keys.partition { it.isExternal } external.forEach { fixVariable(it) } functionTypeParameters.forEach { fixVariable(it) } } override fun build(): ConstraintSystem { - return ConstraintSystemImpl(allTypeParameterBounds, externalTypeParameters, usedInBounds, errors, initialConstraints, - descriptorToVariable, variableToDescriptor) + return ConstraintSystemImpl( + allTypeParameterBounds, usedInBounds, errors, initialConstraints, descriptorToVariable, variableToDescriptor + ) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index b9f114acaba..014ecc823c3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Constrain import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom import org.jetbrains.kotlin.resolve.descriptorUtil.hasInternalAnnotationForResolve -import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.isInternalAnnotationForResolve import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE @@ -35,17 +34,15 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import java.util.* internal class ConstraintSystemImpl( - private val allTypeParameterBounds: Map, - private val externalTypeParameters: Set, - private val usedInBounds: Map>, + private val allTypeParameterBounds: Map, + private val usedInBounds: Map>, private val errors: List, private val initialConstraints: List, - private val descriptorToVariable: Map, - private val variableToDescriptor: Map + private val descriptorToVariable: Map, + private val variableToDescriptor: Map ) : ConstraintSystem { - private val localTypeParameterBounds: Map - get() = if (externalTypeParameters.isEmpty()) allTypeParameterBounds - else allTypeParameterBounds.filter { !externalTypeParameters.contains(it.key) } + private val localTypeParameterBounds: Map + get() = allTypeParameterBounds.filterNot { it.key.isExternal } override val status = object : ConstraintSystemStatus { // for debug ConstraintsUtil.getDebugMessageForStatus might be used @@ -84,14 +81,14 @@ internal class ConstraintSystemImpl( } private fun getParameterToInferredValueMap( - typeParameterBounds: Map, + typeParameterBounds: Map, getDefaultType: (TypeParameterDescriptor) -> KotlinType, substituteOriginal: Boolean ): Map { val substitutionContext = HashMap() for ((variable, typeBounds) in typeParameterBounds) { val value = typeBounds.value - val typeParameter = if (substituteOriginal) variableToDescriptor[variable]!! else variable + val typeParameter = if (substituteOriginal) variableToDescriptor[variable]!! else variable.freshTypeParameter val type = if (value != null && !TypeUtils.containsSpecialType(value, DONT_CARE)) value else getDefaultType(typeParameter) @@ -112,16 +109,16 @@ internal class ConstraintSystemImpl( override val typeParameterDescriptors: Set get() = descriptorToVariable.keys - override val typeVariables: Set + override val typeVariables: Set get() = variableToDescriptor.keys - override fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeParameterDescriptor = + override fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable = descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor") - override fun variableToDescriptor(typeVariable: TypeParameterDescriptor): TypeParameterDescriptor = + override fun variableToDescriptor(typeVariable: TypeVariable): TypeParameterDescriptor = variableToDescriptor[typeVariable] ?: throw IllegalArgumentException("Unknown type variable: $typeVariable") - override fun getTypeBounds(typeVariable: TypeParameterDescriptor): TypeBoundsImpl { + override fun getTypeBounds(typeVariable: TypeVariable): TypeBoundsImpl { return allTypeParameterBounds[typeVariable] ?: throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $typeVariable") } @@ -170,7 +167,6 @@ internal class ConstraintSystemImpl( val (variable, bounds) = it variable to bounds.filterTo(arrayListOf()) { filterConstraintPosition(it.position )} }.toMap()) - result.externalTypeParameters.addAll(externalTypeParameters ) result.errors.addAll(errors.filter { filterConstraintPosition(it.constraintPosition) }) result.initialConstraints.addAll(initialConstraints.filter { filterConstraintPosition(it.position) }) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java index 50a31ca36ee..ae6b9a03617 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java @@ -30,8 +30,8 @@ import java.util.*; public class ConstraintsUtil { @Nullable - public static TypeParameterDescriptor getFirstConflictingVariable(@NotNull ConstraintSystem constraintSystem) { - for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) { + public static TypeVariable getFirstConflictingVariable(@NotNull ConstraintSystem constraintSystem) { + for (TypeVariable typeVariable : constraintSystem.getTypeVariables()) { TypeBounds constraints = constraintSystem.getTypeBounds(typeVariable); if (constraints.getValues().size() > 1) { return typeVariable; @@ -42,7 +42,7 @@ public class ConstraintsUtil { @NotNull public static Collection getSubstitutorsForConflictingParameters(@NotNull ConstraintSystem constraintSystem) { - TypeParameterDescriptor firstConflictingVariable = getFirstConflictingVariable(constraintSystem); + TypeVariable firstConflictingVariable = getFirstConflictingVariable(constraintSystem); if (firstConflictingVariable == null) return Collections.emptyList(); TypeParameterDescriptor firstConflictingParameter = constraintSystem.variableToDescriptor(firstConflictingVariable); @@ -55,7 +55,7 @@ public class ConstraintsUtil { substitutionContexts.add(context); } - for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) { + for (TypeVariable typeVariable : constraintSystem.getTypeVariables()) { if (typeVariable == firstConflictingVariable) continue; KotlinType safeType = getSafeValue(constraintSystem, typeVariable); @@ -72,7 +72,7 @@ public class ConstraintsUtil { } @NotNull - private static KotlinType getSafeValue(@NotNull ConstraintSystem constraintSystem, @NotNull TypeParameterDescriptor typeVariable) { + private static KotlinType getSafeValue(@NotNull ConstraintSystem constraintSystem, @NotNull TypeVariable typeVariable) { KotlinType type = constraintSystem.getTypeBounds(typeVariable).getValue(); if (type != null) { return type; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBounds.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBounds.kt index ffd214287fe..a6241eb0508 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBounds.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBounds.kt @@ -16,16 +16,13 @@ package org.jetbrains.kotlin.resolve.calls.inference -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind -import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.EXACT_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.TypeBounds.BoundKind.* import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition import org.jetbrains.kotlin.types.KotlinType public interface TypeBounds { - public val typeVariable: TypeParameterDescriptor + public val typeVariable: TypeVariable public val bounds: Collection @@ -41,13 +38,13 @@ public interface TypeBounds { } public class Bound( - public val typeVariable: TypeParameterDescriptor, + public val typeVariable: TypeVariable, public val constrainingType: KotlinType, public val kind: BoundKind, public val position: ConstraintPosition, public val isProper: Boolean, // to prevent infinite recursion in incorporation we store the variables that was substituted to derive this bound - public val derivedFrom: Set + public val derivedFrom: Set ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -65,7 +62,7 @@ public interface TypeBounds { } override fun hashCode(): Int { - var result = typeVariable.hashCode(); + var result = typeVariable.hashCode() result = 31 * result + constrainingType.hashCode() result = 31 * result + kind.hashCode() result = 31 * result + if (position.isStrong()) 1 else 0 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBoundsImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBoundsImpl.kt index 07608ef3a57..ca47e17e602 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBoundsImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeBoundsImpl.kt @@ -16,19 +16,17 @@ package org.jetbrains.kotlin.resolve.calls.inference -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.* import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor -import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* -public class TypeBoundsImpl(override val typeVariable: TypeParameterDescriptor) : TypeBounds { +public class TypeBoundsImpl(override val typeVariable: TypeVariable) : TypeBounds { override val bounds = ArrayList() private var resultValues: Collection? = null diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt new file mode 100644 index 00000000000..040595844c1 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.calls.inference + +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.KotlinTypeImpl + +class TypeVariable(val freshTypeParameter: TypeParameterDescriptor, val isExternal: Boolean) { + val name: Name get() = freshTypeParameter.name + + val type: KotlinType get() = freshTypeParameter.defaultType + + fun hasOnlyInputTypesAnnotation(): Boolean = + freshTypeParameter.hasOnlyInputTypesAnnotation() +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintIncorporation.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintIncorporation.kt index 33550ef7b76..21dd34f163d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintIncorporation.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintIncorporation.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.resolve.calls.inference -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.SUB_TYPE import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound @@ -35,7 +34,7 @@ import java.util.* data class ConstraintContext( val position: ConstraintPosition, // see TypeBounds.Bound.derivedFrom - val derivedFrom: Set? = null, + val derivedFrom: Set? = null, val initial: Boolean = false) fun ConstraintSystemBuilderImpl.incorporateBound(newBound: Bound) { @@ -54,7 +53,7 @@ fun ConstraintSystemBuilderImpl.incorporateBound(newBound: Bound) { val constrainingType = newBound.constrainingType if (isMyTypeVariable(constrainingType)) { val context = ConstraintContext(newBound.position, newBound.derivedFrom) - addBound(getMyTypeVariable(constrainingType)!!, typeVariable.correspondingType, newBound.kind.reverse(), context) + addBound(getMyTypeVariable(constrainingType)!!, typeVariable.type, newBound.kind.reverse(), context) return } @@ -92,7 +91,7 @@ private fun ConstraintSystemBuilderImpl.generateNewBound(bound: Bound, substitut } val newTypeProjection = TypeProjectionImpl(substitutedType) - val substitutor = TypeSubstitutor.create(mapOf(substitution.typeVariable.typeConstructor to newTypeProjection)) + val substitutor = TypeSubstitutor.create(mapOf(substitution.typeVariable.type.constructor to newTypeProjection)) val type = substitutor.substitute(bound.constrainingType, INVARIANT) ?: return val position = CompoundConstraintPosition(bound.position, substitution.position) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt index c7719591aa1..1fedecee99e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.types.TypeProjection import org.jetbrains.kotlin.types.TypeProjectionImpl import java.util.* -fun ConstraintSystem.getNestedTypeVariables(type: KotlinType): List = +fun ConstraintSystem.getNestedTypeVariables(type: KotlinType): List = type.getNestedTypeParameters().filter { it in typeParameterDescriptors }.map { descriptorToVariable(it) } fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {