From 0394da053d129a2580aea3f888ece0094f3ecc57 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 10 Jul 2012 15:10:18 +0400 Subject: [PATCH] added assert for last type inference error type restructured 'isSuccessful' method of constraint system: !hasTypeConstructorMismatch && !hasUnknownParameters && !hasConflictingParameters to correspond with type inference errors --- .../jet/lang/resolve/calls/CallResolver.java | 11 ++-- .../calls/inference/ConstraintSystem.java | 25 +++++--- .../calls/inference/ConstraintSystemImpl.java | 58 +++++++++++++------ 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 46a1205e228..f272126933d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -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 void checkBounds(ResolvedCallImpl 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())); 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 20c87a79b5b..825f34d2155 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 @@ -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 getTypeBoundsMap(); - boolean isSuccessful(); boolean hasContradiction(); + boolean hasConflictingParameters(); + + boolean hasUnknownParameters(); + + boolean hasTypeConstructorMismatch(); + + TypeBounds getTypeBounds(TypeParameterDescriptor typeParameterDescriptor); + + Map getTypeBoundsMap(); + + @Nullable TypeParameterDescriptor getFirstConflictingParameter(); + @NotNull TypeSubstitutor getSubstitutor(); + @NotNull Collection getSubstitutors(); + @Nullable JetType getValue(TypeParameterDescriptor typeParameterDescriptor); - boolean hasError(); - - Queue getErrorConstraintPositions(); + @NotNull + Collection getErrorConstraintPositions(); boolean checkUpperBound(@NotNull TypeParameterDescriptor typeParameterDescriptor); } 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 79f70967ca7..66e9634f034 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 @@ -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 typeParameterBounds = Maps.newLinkedHashMap(); private final TypeSubstitutor typeSubstitutor; - private final Queue errorConstraintPositions; - private boolean error; + private final Collection errorConstraintPositions; + private boolean typeConstructorMismatch; public ConstraintSystemImpl() { - this(false, Lists.newLinkedList()); + this(false, Lists.newArrayList()); } - public ConstraintSystemImpl(boolean error, Queue errorConstraintPositions) { - this.error = error; + public ConstraintSystemImpl(boolean typeConstructorMismatch, Collection 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 getErrorConstraintPositions() { + public Collection 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 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;