added assert for last type inference error type

restructured 'isSuccessful' method of constraint system:
!hasTypeConstructorMismatch && !hasUnknownParameters && !hasConflictingParameters
to correspond with type inference errors
This commit is contained in:
Svetlana Isakova
2012-07-10 15:10:18 +04:00
parent 33c25ea01f
commit 0394da053d
3 changed files with 64 additions and 30 deletions
@@ -399,15 +399,17 @@ public class CallResolver {
}
private void reportTypeInferenceFailed(@NotNull BindingTrace trace, @NotNull Call call, @NotNull InferenceErrorData inferenceErrorData) {
assert !inferenceErrorData.constraintSystem.isSuccessful();
JetExpression calleeExpression = call.getCalleeExpression();
PsiElement element = calleeExpression != null ? calleeExpression : call.getCallElement();
if (inferenceErrorData.constraintSystem.hasError()) {
if (inferenceErrorData.constraintSystem.hasTypeConstructorMismatch()) {
trace.report(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH.on(element, inferenceErrorData));
}
else if (inferenceErrorData.constraintSystem.hasContradiction()) {
else if (inferenceErrorData.constraintSystem.hasConflictingParameters()) {
trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(element, inferenceErrorData));
}
else {
assert inferenceErrorData.constraintSystem.hasUnknownParameters();
trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(element, inferenceErrorData));
}
}
@@ -415,7 +417,8 @@ public class CallResolver {
private <D extends CallableDescriptor> void checkBounds(ResolvedCallImpl<D> call, ConstraintSystem constraintSystem, BasicResolutionContext context) {
for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) {
if (!constraintSystem.checkUpperBound(typeParameter)) {
context.trace.report(Errors.TYPE_INFERENCE_UPPER_BOUND_VIOLATED.on(context.call.getCallElement(), InferenceErrorData.create(call.getCandidateDescriptor(), constraintSystem)));
context.trace.report(Errors.TYPE_INFERENCE_UPPER_BOUND_VIOLATED.on(context.call.getCallElement(), InferenceErrorData
.create(call.getCandidateDescriptor(), constraintSystem)));
}
}
}
@@ -765,7 +768,7 @@ public class CallResolver {
constraintSystem.addSubtypingConstraint(receiverArgument.getType(), receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION);
}
ConstraintSystemImpl constraintSystemWithRightTypeParameters = new ConstraintSystemImpl(constraintSystem.hasError(), constraintSystem.getErrorConstraintPositions());
ConstraintSystemImpl constraintSystemWithRightTypeParameters = new ConstraintSystemImpl(constraintSystem.hasTypeConstructorMismatch(), constraintSystem.getErrorConstraintPositions());
for (TypeParameterDescriptor typeParameterDescriptor : candidate.getTypeParameters()) {
TypeBounds typeBounds = constraintSystem.getTypeBounds(
candidateWithFreshVariables.getTypeParameters().get(typeParameterDescriptor.getIndex()));
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve.calls.inference;
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;
@@ -25,7 +26,6 @@ import org.jetbrains.jet.lang.types.Variance;
import java.util.Collection;
import java.util.Map;
import java.util.Queue;
/**
* @author svtk
@@ -46,25 +46,34 @@ public interface ConstraintSystem {
void addConstraint(@NotNull ConstraintType constraintType, @NotNull JetType exactType, @NotNull JetType expectedType, @NotNull ConstraintPosition constraintPosition);
TypeBounds getTypeBounds(TypeParameterDescriptor typeParameterDescriptor);
Map<TypeParameterDescriptor, TypeBounds> getTypeBoundsMap();
boolean isSuccessful();
boolean hasContradiction();
boolean hasConflictingParameters();
boolean hasUnknownParameters();
boolean hasTypeConstructorMismatch();
TypeBounds getTypeBounds(TypeParameterDescriptor typeParameterDescriptor);
Map<TypeParameterDescriptor, TypeBounds> getTypeBoundsMap();
@Nullable
TypeParameterDescriptor getFirstConflictingParameter();
@NotNull
TypeSubstitutor getSubstitutor();
@NotNull
Collection<TypeSubstitutor> getSubstitutors();
@Nullable
JetType getValue(TypeParameterDescriptor typeParameterDescriptor);
boolean hasError();
Queue<ConstraintPosition> getErrorConstraintPositions();
@NotNull
Collection<ConstraintPosition> getErrorConstraintPositions();
boolean checkUpperBound(@NotNull TypeParameterDescriptor typeParameterDescriptor);
}
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -49,15 +48,15 @@ public class ConstraintSystemImpl implements ConstraintSystem {
private final Map<TypeParameterDescriptor, TypeBounds> typeParameterBounds = Maps.newLinkedHashMap();
private final TypeSubstitutor typeSubstitutor;
private final Queue<ConstraintPosition> errorConstraintPositions;
private boolean error;
private final Collection<ConstraintPosition> errorConstraintPositions;
private boolean typeConstructorMismatch;
public ConstraintSystemImpl() {
this(false, Lists.<ConstraintPosition>newLinkedList());
this(false, Lists.<ConstraintPosition>newArrayList());
}
public ConstraintSystemImpl(boolean error, Queue<ConstraintPosition> errorConstraintPositions) {
this.error = error;
public ConstraintSystemImpl(boolean typeConstructorMismatch, Collection<ConstraintPosition> errorConstraintPositions) {
this.typeConstructorMismatch = typeConstructorMismatch;
this.errorConstraintPositions = errorConstraintPositions;
this.typeSubstitutor = TypeSubstitutor.create(new TypeSubstitution() {
@Override
@@ -88,12 +87,13 @@ public class ConstraintSystemImpl implements ConstraintSystem {
}
@Override
public boolean hasError() {
return error;
public boolean hasTypeConstructorMismatch() {
return typeConstructorMismatch;
}
@NotNull
@Override
public Queue<ConstraintPosition> getErrorConstraintPositions() {
public Collection<ConstraintPosition> getErrorConstraintPositions() {
return errorConstraintPositions;
}
@@ -164,7 +164,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
if (exactType.getConstructor().getParameters().size() != expectedType.getConstructor().getParameters().size()) {
errorConstraintPositions.add(constraintPosition);
error = true;
typeConstructorMismatch = true;
return;
}
@@ -181,15 +181,12 @@ public class ConstraintSystemImpl implements ConstraintSystem {
return;
}
}
error = true;
typeConstructorMismatch = true;
errorConstraintPositions.add(constraintPosition);
}
private boolean checkConstraints(TypeParameterDescriptor typeParameterDescriptor) {
//todo refactor
if (error) {
return false;
}
TypeBounds typeBounds = typeParameterBounds.get(typeParameterDescriptor);
if (typeBounds == null || typeBounds.isEmpty()) return true;
JetType exactType = null;
@@ -268,14 +265,30 @@ public class ConstraintSystemImpl implements ConstraintSystem {
values.addAll(typeBounds.getExactValues());
if (!typeBounds.getLowerBounds().isEmpty()) {
JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertype(typeBounds.getLowerBounds());
if (values.isEmpty()) {
values.add(superTypeOfLowerBounds);
}
for (JetType value : values) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(superTypeOfLowerBounds, value)) {
values.add(superTypeOfLowerBounds);
break;
}
}
}
if (!typeBounds.getUpperBounds().isEmpty()) {
//todo subTypeOfUpperBounds
JetType subTypeOfUpperBounds = typeBounds.getUpperBounds().iterator().next(); //todo
if (values.isEmpty()) {
values.add(subTypeOfUpperBounds);
}
for (JetType value : values) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(value, subTypeOfUpperBounds)) {
values.add(subTypeOfUpperBounds);
break;
}
}
}
}
//todo subTypeOfLowerBounds
return values;
}
@@ -291,6 +304,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
return null;
}
@NotNull
@Override
public Collection<TypeSubstitutor> getSubstitutors() {
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter();
@@ -334,18 +348,25 @@ public class ConstraintSystemImpl implements ConstraintSystem {
@Override
public boolean isSuccessful() {
return !error && !hasUnknownParameters() && !hasContradiction();
return !hasTypeConstructorMismatch() && !hasUnknownParameters() && !hasConflictingParameters();
}
@Override
public boolean hasContradiction() {
return hasTypeConstructorMismatch() || hasConflictingParameters();
}
@Override
public boolean hasConflictingParameters() {
for (TypeParameterDescriptor typeParameter : typeParameterBounds.keySet()) {
if (!checkConstraints(typeParameter)) return true;
if (getValues(typeParameter).size() > 1) return true;
//if (!checkConstraints(typeParameter)) return true;
}
return false;
}
private boolean hasUnknownParameters() {
@Override
public boolean hasUnknownParameters() {
for (TypeBounds bounds : typeParameterBounds.values()) {
if (bounds.isEmpty()) {
return true;
@@ -354,6 +375,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
return false;
}
@NotNull
@Override
public TypeSubstitutor getSubstitutor() {
return typeSubstitutor;