KT-668 Failed to resolve generic parameter
Same lower and upper bounds cause an equality constraint to be created
This commit is contained in:
+43
-20
@@ -73,9 +73,11 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public abstract KnownType getValue();
|
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 TypeParameterDescriptor typeParameterDescriptor;
|
||||||
private final Variance positionVariance;
|
private final Variance positionVariance;
|
||||||
@@ -87,6 +89,24 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
this.positionVariance = positionVariance;
|
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<TypeValue> oppositeBounds) {
|
||||||
|
if (oppositeBounds.contains(bound)) {
|
||||||
|
this.equate(bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TypeParameterDescriptor getTypeParameterDescriptor() {
|
public TypeParameterDescriptor getTypeParameterDescriptor() {
|
||||||
return typeParameterDescriptor;
|
return typeParameterDescriptor;
|
||||||
@@ -139,6 +159,18 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
return value;
|
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) {
|
public boolean setValue(@NotNull KnownType value) {
|
||||||
if (this.value != null) {
|
if (this.value != null) {
|
||||||
// If we have already assigned a value to this unknown,
|
// If we have already assigned a value to this unknown,
|
||||||
@@ -186,6 +218,15 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return type.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<JetType, KnownType> knownTypes = Maps.newHashMap();
|
private final Map<JetType, KnownType> knownTypes = Maps.newHashMap();
|
||||||
@@ -233,25 +274,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
TypeValue aValue = getTypeValueFor(a);
|
TypeValue aValue = getTypeValueFor(a);
|
||||||
TypeValue bValue = getTypeValueFor(b);
|
TypeValue bValue = getTypeValueFor(b);
|
||||||
|
|
||||||
if (aValue instanceof UnknownType) {
|
return aValue.equate(bValue);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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<T>(x: fun(T):T, y: T): T {
|
||||||
|
return x(x(y))
|
||||||
|
}
|
||||||
|
|
||||||
|
val x: B = a({it.b()}, B())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user