diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java
index b78fa46334d..85d04cee461 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil;
import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData;
+import org.jetbrains.jet.lang.resolve.calls.inference.TypeConstraints;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
@@ -277,7 +278,7 @@ public class Renderers {
.table(newTable().
descriptor(inferenceErrorData.descriptor));
- JetType inferredValueForTypeParameter = ConstraintsUtil.getValue(inferenceErrorData.constraintSystem.getTypeConstraints(typeParameterDescriptor));
+ JetType inferredValueForTypeParameter = inferenceErrorData.constraintSystem.getTypeConstraints(typeParameterDescriptor).getValue();
assert inferredValueForTypeParameter != null;
JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType();
JetType upperBoundWithSubstitutedInferredTypes = inferenceErrorData.constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java
index 4667445bc59..bf429775a96 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.context.CallResolutionContext;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil;
+import org.jetbrains.jet.lang.resolve.calls.inference.TypeConstraints;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
@@ -115,7 +116,7 @@ public class CallResolverUtil {
if (returnType == null) return false;
for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) {
- JetType inferredValueForTypeVariable = ConstraintsUtil.getValue(constraintSystem.getTypeConstraints(typeVariable));
+ JetType inferredValueForTypeVariable = constraintSystem.getTypeConstraints(typeVariable).getValue();
if (inferredValueForTypeVariable == null) {
if (TypeUtils.dependsOnTypeParameters(returnType, Collections.singleton(typeVariable))) {
return true;
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java
index f9637517a43..0244a0ea5ff 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystem.java
@@ -64,7 +64,7 @@ public interface ConstraintSystem {
* Returns the resulting type constraints of solving the constraint system for specific type variable.
* Returns null if the type variable was not registered.
*/
- @Nullable
+ @NotNull
TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeVariable);
/**
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java
index db547b436a3..1a10a87a46d 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java
@@ -72,7 +72,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
public boolean hasConflictingConstraints() {
for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) {
TypeConstraints typeConstraints = getTypeConstraints(typeParameter);
- if (typeConstraints != null && ConstraintsUtil.getValues(typeConstraints).size() > 1) return true;
+ if (typeConstraints.getValues().size() > 1) return true;
}
return false;
}
@@ -133,11 +133,11 @@ public class ConstraintSystemImpl implements ConstraintSystem {
if (declarationDescriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
- JetType value = ConstraintsUtil.getValue(getTypeConstraints(descriptor));
- if (value != null && !TypeUtils.equalsOrContainsAsArgument(value, DONT_CARE)) {
- return new TypeProjection(value);
- }
if (typeParameterConstraints.containsKey(descriptor)) {
+ JetType value = getTypeConstraints(descriptor).getValue();
+ if (value != null && !TypeUtils.equalsOrContainsAsArgument(value, DONT_CARE)) {
+ return new TypeProjection(value);
+ }
return defaultTypeProjection;
}
}
@@ -363,9 +363,11 @@ public class ConstraintSystemImpl implements ConstraintSystem {
}
@Override
- @Nullable
+ @NotNull
public TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeVariable) {
- return typeParameterConstraints.get(typeVariable);
+ TypeConstraintsImpl typeConstraints = typeParameterConstraints.get(typeVariable);
+ assert typeConstraints != null : "TypeParameterDescriptor is not a type variable for constraint system: " + typeVariable;
+ return typeConstraints;
}
@Nullable
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java
index 3c715347b4f..88cb8a09fb6 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java
@@ -19,8 +19,6 @@ package org.jetbrains.jet.lang.resolve.calls.inference;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-import com.intellij.openapi.util.Pair;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
@@ -30,147 +28,11 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import java.util.*;
public class ConstraintsUtil {
-
- @NotNull
- public static Set getValues(@Nullable TypeConstraints typeConstraints) {
- Set values = Sets.newLinkedHashSet();
- if (typeConstraints == null || typeConstraints.isEmpty()) {
- return values;
- }
- TypeConstraints typeConstraintsWithoutErrorTypes = filterNotContainingErrorType(typeConstraints, values);
- Collection exactBounds = typeConstraintsWithoutErrorTypes.getExactBounds();
- if (exactBounds.size() == 1) {
- JetType exactBound = exactBounds.iterator().next();
- if (trySuggestion(exactBound, typeConstraints)) {
- return Collections.singleton(exactBound);
- }
- }
- values.addAll(exactBounds);
-
- Pair, Collection> pair =
- TypeUtils.filterNumberTypes(typeConstraintsWithoutErrorTypes.getLowerBounds());
- Collection generalLowerBounds = pair.getFirst();
- Collection numberLowerBounds = pair.getSecond();
-
- JetType superTypeOfLowerBounds = commonSupertype(generalLowerBounds);
- if (trySuggestion(superTypeOfLowerBounds, typeConstraints)) {
- return Collections.singleton(superTypeOfLowerBounds);
- }
- ContainerUtil.addIfNotNull(superTypeOfLowerBounds, values);
-
- Collection upperBounds = typeConstraintsWithoutErrorTypes.getUpperBounds();
- for (JetType upperBound : upperBounds) {
- if (trySuggestion(upperBound, typeConstraints)) {
- return Collections.singleton(upperBound);
- }
- }
- //todo
- //fun foo(t: T, consumer: Consumer): T
- //foo(1, c: Consumer) - infer Int, not Any here
-
- values.addAll(typeConstraintsWithoutErrorTypes.getUpperBounds());
-
- JetType superTypeOfNumberLowerBounds = commonSupertypeForNumberTypes(numberLowerBounds);
- if (trySuggestion(superTypeOfNumberLowerBounds, typeConstraints)) {
- return Collections.singleton(superTypeOfNumberLowerBounds);
- }
- ContainerUtil.addIfNotNull(superTypeOfNumberLowerBounds, values);
-
- if (superTypeOfLowerBounds != null && superTypeOfNumberLowerBounds != null) {
- JetType superTypeOfAllLowerBounds = commonSupertype(Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
- if (trySuggestion(superTypeOfAllLowerBounds, typeConstraints)) {
- return Collections.singleton(superTypeOfAllLowerBounds);
- }
- }
- return values;
- }
-
- @Nullable
- private static JetType commonSupertype(@NotNull Collection lowerBounds) {
- if (lowerBounds.isEmpty()) return null;
- if (lowerBounds.size() == 1) {
- JetType type = lowerBounds.iterator().next();
- if (type.getConstructor() instanceof IntersectionTypeConstructor) {
- return commonSupertype(type.getConstructor().getSupertypes());
- }
- }
- return CommonSupertypes.commonSupertype(lowerBounds);
- }
-
- @Nullable
- private static JetType commonSupertypeForNumberTypes(@NotNull Collection numberLowerBounds) {
- if (numberLowerBounds.isEmpty()) return null;
- return TypeUtils.commonSupertypeForNumberTypes(numberLowerBounds);
- }
-
- private static boolean trySuggestion(
- @Nullable JetType suggestion,
- @NotNull TypeConstraints typeConstraints
- ) {
- if (suggestion == null) return false;
- if (!suggestion.getConstructor().isDenotable()) return false;
- if (typeConstraints.getExactBounds().size() > 1) return false;
-
- for (JetType exactBound : typeConstraints.getExactBounds()) {
- if (!JetTypeChecker.INSTANCE.equalTypes(exactBound, suggestion)) {
- return false;
- }
- }
- for (JetType lowerBound : typeConstraints.getLowerBounds()) {
- if (!JetTypeChecker.INSTANCE.isSubtypeOf(lowerBound, suggestion)) {
- return false;
- }
- }
- for (JetType upperBound : typeConstraints.getUpperBounds()) {
- if (!JetTypeChecker.INSTANCE.isSubtypeOf(suggestion, upperBound)) {
- return false;
- }
- }
- return true;
- }
-
- @NotNull
- private static TypeConstraints filterNotContainingErrorType(
- @NotNull TypeConstraints typeConstraints,
- @NotNull Collection values
- ) {
- TypeConstraintsImpl typeConstraintsWithoutErrorType = new TypeConstraintsImpl(typeConstraints.getVarianceOfPosition());
- Collection> allBounds = ((TypeConstraintsImpl) typeConstraints).getAllBounds();
- for (Pair pair : allBounds) {
- TypeConstraintsImpl.BoundKind boundKind = pair.getFirst();
- JetType type = pair.getSecond();
- if (ErrorUtils.containsErrorType(type)) {
- values.add(type);
- }
- else if (type != null) {
- typeConstraintsWithoutErrorType.addBound(boundKind, type);
- }
- }
- return typeConstraintsWithoutErrorType;
- }
-
- @Nullable
- public static JetType getValue(@Nullable TypeConstraints typeConstraints) {
- //todo all checks
- //todo variance dependance
- if (typeConstraints == null) {
- //todo assert typeConstraints != null;
- return null;
- }
- Set values = getValues(typeConstraints);
- if (values.size() == 1) {
- return values.iterator().next();
- }
- return null;
- }
-
-
-
@Nullable
public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintSystem constraintSystem) {
for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeVariables()) {
TypeConstraints constraints = constraintSystem.getTypeConstraints(typeParameter);
- if (getValues(constraints).size() > 1) {
+ if (constraints.getValues().size() > 1) {
return typeParameter;
}
}
@@ -182,7 +44,7 @@ public class ConstraintsUtil {
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter(constraintSystem);
if (firstConflictingParameter == null) return Collections.emptyList();
- Collection conflictingTypes = getValues(constraintSystem.getTypeConstraints(firstConflictingParameter));
+ Collection conflictingTypes = constraintSystem.getTypeConstraints(firstConflictingParameter).getValues();
ArrayList