diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java index c3aeda4ea26..6806097fdd9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java @@ -16,16 +16,13 @@ package org.jetbrains.jet.lang.resolve.calls.inference; -import com.google.common.base.Predicate; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; -import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.Variance; -import java.util.Collection; import java.util.Set; /** @@ -33,43 +30,94 @@ import java.util.Set; */ public interface ConstraintsSystem { - void registerTypeVariable(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull Variance positionVariance); + /** + * Registers a variable in a constraint system. + */ + void registerTypeVariable(@NotNull TypeParameterDescriptor typeVariable, @NotNull Variance positionVariance); + /** + * Returns a set of all registered type variables. + */ @NotNull Set getTypeVariables(); - //todo - /** only subject type might contain type variables + /** + * Adds a constraint that the subject type is a supertype of the constraining type.

+ * Asserts that only subject type may contain registered type variables.

* - * @param subjectType - * @param constrainingType - * @param constraintPosition + * For example, for {@code "fun id(t: T) {}"} to infer T in invocation "id(1)" + * should be generated a constraint "T is a supertype of Int" where T is a subject type, and Int is a constraining type. + */ + void addSupertypeConstraint(@NotNull JetType subjectType, @Nullable JetType constrainingType, @NotNull ConstraintPosition constraintPosition); + + /** + * Adds a constraint that subject type is a subtype of constraining type.

+ * Asserts that only subject type may contain registered type variables.

+ * + * For example, for {@code "fun create() : T"} to infer T in invocation "val i: Int = create()" + * should be generated a constraint "T is a subtype of Int" where T is a subject type, and Int is a constraining type. */ void addSubtypingConstraint(@NotNull JetType subjectType, @Nullable JetType constrainingType, @NotNull ConstraintPosition constraintPosition); - // only subject type might contain type variables - void addSupertypeConstraint(@NotNull JetType subjectType, @Nullable JetType constrainingType, @NotNull ConstraintPosition constraintPosition); - + /** + * Returns true if constraint system has a solution (has no contradiction and has enough information to infer each registered type variable). + */ boolean isSuccessful(); - boolean hasContradiction(); - - boolean hasConflictingParameters(); - - boolean hasUnknownParameters(); - - boolean hasTypeConstructorMismatch(); - - boolean hasTypeConstructorMismatchAt(@NotNull ConstraintPosition constraintPosition); - - boolean hasErrorInConstrainingTypes(); - - @Nullable - TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeParameterDescriptor); + /** + * Returns true if type constraints for some type variable are contradicting.

+ * + * For example, for

fun <R> foo(r: R, t: java.util.List<R>) {}
in invocation foo(1, arrayList("s")) + * type variable R has two conflicting constraints:

+ * - "R is a supertype of Int"

+ * - "List<R> is a supertype of List<String>" which leads to "R is equal to String" + */ + boolean hasConflictingConstraints(); /** + * Returns true if there is no information for some registered type variable. * - * @return + * For example, for

fun <E> newList()
in invocation "val nl = newList()" + * there is no information to infer type variable E. + */ + boolean hasUnknownParameters(); + + /** + * Returns true if some constraint cannot be processed because of type constructor mismatch. + * + * For example, for
fun <R> foo(t: List<R>) {}
in invocation foo(hashSet("s")) + * there is type constructor mismatch: "HashSet<String> cannot be a subtype of List<R>". + */ + boolean hasTypeConstructorMismatch(); + + /** + * Returns true if there is type constructor mismatch error at a specific {@code constraintPosition}. + * + * For example, for
fun <R> foo(t: List<R>) {}
in invocation foo(hashSet("s")) + * there is type constructor mismatch: "HashSet<String> cannot be a subtype of List<R>" + * at a constraint position {@code ConstraintPosition.getValueParameterPosition(0)}. + */ + boolean hasTypeConstructorMismatchAt(@NotNull ConstraintPosition constraintPosition); + + /** + * Returns true if there is an error in constraining types.

+ * Is used not to generate type inference error if there was one in argument types. + */ + boolean hasErrorInConstrainingTypes(); + + /** + * Returns the resulting type constraints of solving the constraint system for specific type variable.

+ * Returns null if the type variable was not registered. + */ + @Nullable + TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeVariable); + + /** + * Returns a result of solving the constraint system (mapping from the type variable to the resulting type projection).

+ * In the resulting substitution should be concerned:

+ * - type constraints

+ * - variance of the type variable // not implemented yet

+ * - type parameter bounds (that can bind type variables with each other). // not implemented yet */ @NotNull TypeSubstitutor getResultingSubstitutor();