diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java index e9984635f3a..ed5e49d499c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java @@ -73,9 +73,11 @@ public class ConstraintSystemImpl implements ConstraintSystem { @Nullable public abstract KnownType getValue(); + + public abstract boolean equate(TypeValue other); } - private static class UnknownType extends TypeValue { + private class UnknownType extends TypeValue { private final TypeParameterDescriptor typeParameterDescriptor; private final Variance positionVariance; @@ -87,6 +89,24 @@ public class ConstraintSystemImpl implements ConstraintSystem { this.positionVariance = positionVariance; } + @Override + public void addUpperBound(@NotNull TypeValue bound) { + addBound(bound, getLowerBounds()); + super.addUpperBound(bound); + } + + @Override + public void addLowerBound(@NotNull TypeValue bound) { + addBound(bound, getUpperBounds()); + super.addLowerBound(bound); + } + + private void addBound(TypeValue bound, Set oppositeBounds) { + if (oppositeBounds.contains(bound)) { + this.equate(bound); + } + } + @NotNull public TypeParameterDescriptor getTypeParameterDescriptor() { return typeParameterDescriptor; @@ -139,6 +159,18 @@ public class ConstraintSystemImpl implements ConstraintSystem { return value; } + @Override + public boolean equate(TypeValue other) { + if (other instanceof KnownType) { + KnownType knownType = (KnownType) other; + return setValue(knownType); + } + + assert other instanceof UnknownType; + mergeUnknowns((UnknownType) other, this); + return true; + } + public boolean setValue(@NotNull KnownType value) { if (this.value != null) { // If we have already assigned a value to this unknown, @@ -186,6 +218,15 @@ public class ConstraintSystemImpl implements ConstraintSystem { public String toString() { return type.toString(); } + + @Override + public boolean equate(TypeValue other) { + if (other instanceof KnownType) { + KnownType knownType = (KnownType) other; + return TypeUtils.equalTypes(type, knownType.getType()); + } + return other.equate(this); + } } private final Map knownTypes = Maps.newHashMap(); @@ -233,25 +274,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { TypeValue aValue = getTypeValueFor(a); TypeValue bValue = getTypeValueFor(b); - if (aValue instanceof UnknownType) { - UnknownType aUnknown = (UnknownType) aValue; - if (bValue instanceof UnknownType) { - UnknownType bUnknown = (UnknownType) bValue; - mergeUnknowns(aUnknown, bUnknown); - } - else { - if (!aUnknown.setValue((KnownType) bValue)) return false; - } - } - else if (bValue instanceof UnknownType) { - UnknownType bUnknown = (UnknownType) bValue; - if (!bUnknown.setValue((KnownType) aValue)) return false; - } - else { - return TypeUtils.equalTypes(a, b); - } - - return true; + return aValue.equate(bValue); } @Override diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt688.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt688.jet new file mode 100644 index 00000000000..045dddc7d8f --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt688.jet @@ -0,0 +1,14 @@ +// KT-668 Failed to resolve generic parameter +open class A() +open class B() : A() { + fun b(): B = B() +} + + +class C() { + fun a(x: fun(T):T, y: T): T { + return x(x(y)) + } + + val x: B = a({it.b()}, B()) +} \ No newline at end of file