Fix JetType.equals(): flexible types are not equal to non-flexible ones, when we store them in a HashSet

This commit is contained in:
Andrey Breslav
2014-10-07 14:05:55 +04:00
parent 5be4dda58b
commit e418a763db
12 changed files with 89 additions and 8 deletions
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.LazyType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.ArrayList;
@@ -397,9 +398,9 @@ public class DescriptorUtils {
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
return builtIns.isPrimitiveType(type) ||
builtIns.getStringType().equals(type) ||
builtIns.getNumber().getDefaultType().equals(type) ||
builtIns.getAnyType().equals(type);
JetTypeChecker.DEFAULT.equalTypes(builtIns.getStringType(), type) ||
JetTypeChecker.DEFAULT.equalTypes(builtIns.getNumber().getDefaultType(), type) ||
JetTypeChecker.DEFAULT.equalTypes(builtIns.getAnyType(), type);
}
public static boolean classCanHaveAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
import org.jetbrains.jet.lang.types.checker.TypingConstraints;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -388,7 +389,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
// can be equal for the recursive invocations:
// fun <T> foo(i: Int) : T { ... return foo(i); } => T <: T
if (subType.equals(superType)) return;
if (JetTypeChecker.DEFAULT.equalTypes(subType, superType)) return;
assert !isMyTypeVariable(subType) || !isMyTypeVariable(superType) :
"The constraint shouldn't contain different type variables on both sides: " + subType + " <: " + superType;
@@ -49,7 +49,7 @@ public abstract class AbstractJetType implements JetType {
JetType type = (JetType) obj;
return isNullable() == type.isNullable() && JetTypeChecker.DEFAULT.equalTypes(this, type);
return isNullable() == type.isNullable() && JetTypeChecker.FLEXIBLE_UNEQUAL_TO_INFLEXIBLE.equalTypes(this, type);
}
@Override
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import java.util.List;
@@ -77,7 +78,11 @@ public abstract class DelegatingType implements JetType {
@Override
public boolean equals(Object obj) {
return getDelegate().equals(obj);
if (this == obj) return true;
if (!(obj instanceof JetType)) return false;
JetType type = (JetType) obj;
return JetTypeChecker.FLEXIBLE_UNEQUAL_TO_INFLEXIBLE.equalTypes(this, type);
}
@Override
@@ -28,6 +28,13 @@ public class JetTypeChecker {
public static final JetTypeChecker DEFAULT = new JetTypeChecker(new TypeCheckingProcedure(new TypeCheckerTypingConstraints()));
public static final JetTypeChecker FLEXIBLE_UNEQUAL_TO_INFLEXIBLE = new JetTypeChecker(new TypeCheckingProcedure(new TypeCheckerTypingConstraints()) {
@Override
protected boolean heterogeneousEquivalence(JetType inflexibleType, JetType flexibleType) {
return false;
}
});
@NotNull
public static JetTypeChecker withAxioms(@NotNull final TypeConstructorEquality equalityAxioms) {
return new JetTypeChecker(new TypeCheckingProcedure(new TypeCheckerTypingConstraints() {
@@ -118,7 +118,7 @@ public class TypeCheckingProcedure {
return true;
}
private boolean heterogeneousEquivalence(JetType inflexibleType, JetType flexibleType) {
protected boolean heterogeneousEquivalence(JetType inflexibleType, JetType flexibleType) {
// This is to account for the case when we have Collection<X> vs (Mutable)Collection<X>! or K(java.util.Collection<? extends X>)
assert !TypesPackage.isFlexible(inflexibleType) : "Only inflexible types are allowed here: " + inflexibleType;
return isSubtypeOf(TypesPackage.flexibility(flexibleType).getLowerBound(), inflexibleType)