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:
@@ -399,15 +399,17 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void reportTypeInferenceFailed(@NotNull BindingTrace trace, @NotNull Call call, @NotNull InferenceErrorData inferenceErrorData) {
|
private void reportTypeInferenceFailed(@NotNull BindingTrace trace, @NotNull Call call, @NotNull InferenceErrorData inferenceErrorData) {
|
||||||
|
assert !inferenceErrorData.constraintSystem.isSuccessful();
|
||||||
JetExpression calleeExpression = call.getCalleeExpression();
|
JetExpression calleeExpression = call.getCalleeExpression();
|
||||||
PsiElement element = calleeExpression != null ? calleeExpression : call.getCallElement();
|
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));
|
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));
|
trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(element, inferenceErrorData));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert inferenceErrorData.constraintSystem.hasUnknownParameters();
|
||||||
trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(element, inferenceErrorData));
|
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) {
|
private <D extends CallableDescriptor> void checkBounds(ResolvedCallImpl<D> call, ConstraintSystem constraintSystem, BasicResolutionContext context) {
|
||||||
for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) {
|
for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) {
|
||||||
if (!constraintSystem.checkUpperBound(typeParameter)) {
|
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);
|
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()) {
|
for (TypeParameterDescriptor typeParameterDescriptor : candidate.getTypeParameters()) {
|
||||||
TypeBounds typeBounds = constraintSystem.getTypeBounds(
|
TypeBounds typeBounds = constraintSystem.getTypeBounds(
|
||||||
candidateWithFreshVariables.getTypeParameters().get(typeParameterDescriptor.getIndex()));
|
candidateWithFreshVariables.getTypeParameters().get(typeParameterDescriptor.getIndex()));
|
||||||
|
|||||||
+17
-8
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.calls.inference;
|
package org.jetbrains.jet.lang.resolve.calls.inference;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
@@ -46,25 +46,34 @@ public interface ConstraintSystem {
|
|||||||
|
|
||||||
void addConstraint(@NotNull ConstraintType constraintType, @NotNull JetType exactType, @NotNull JetType expectedType, @NotNull ConstraintPosition constraintPosition);
|
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 isSuccessful();
|
||||||
|
|
||||||
boolean hasContradiction();
|
boolean hasContradiction();
|
||||||
|
|
||||||
|
boolean hasConflictingParameters();
|
||||||
|
|
||||||
|
boolean hasUnknownParameters();
|
||||||
|
|
||||||
|
boolean hasTypeConstructorMismatch();
|
||||||
|
|
||||||
|
TypeBounds getTypeBounds(TypeParameterDescriptor typeParameterDescriptor);
|
||||||
|
|
||||||
|
Map<TypeParameterDescriptor, TypeBounds> getTypeBoundsMap();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
TypeParameterDescriptor getFirstConflictingParameter();
|
TypeParameterDescriptor getFirstConflictingParameter();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
TypeSubstitutor getSubstitutor();
|
TypeSubstitutor getSubstitutor();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
Collection<TypeSubstitutor> getSubstitutors();
|
Collection<TypeSubstitutor> getSubstitutors();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
JetType getValue(TypeParameterDescriptor typeParameterDescriptor);
|
JetType getValue(TypeParameterDescriptor typeParameterDescriptor);
|
||||||
|
|
||||||
boolean hasError();
|
@NotNull
|
||||||
|
Collection<ConstraintPosition> getErrorConstraintPositions();
|
||||||
Queue<ConstraintPosition> getErrorConstraintPositions();
|
|
||||||
|
|
||||||
boolean checkUpperBound(@NotNull TypeParameterDescriptor typeParameterDescriptor);
|
boolean checkUpperBound(@NotNull TypeParameterDescriptor typeParameterDescriptor);
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-18
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
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.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
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 Map<TypeParameterDescriptor, TypeBounds> typeParameterBounds = Maps.newLinkedHashMap();
|
||||||
private final TypeSubstitutor typeSubstitutor;
|
private final TypeSubstitutor typeSubstitutor;
|
||||||
private final Queue<ConstraintPosition> errorConstraintPositions;
|
private final Collection<ConstraintPosition> errorConstraintPositions;
|
||||||
private boolean error;
|
private boolean typeConstructorMismatch;
|
||||||
|
|
||||||
public ConstraintSystemImpl() {
|
public ConstraintSystemImpl() {
|
||||||
this(false, Lists.<ConstraintPosition>newLinkedList());
|
this(false, Lists.<ConstraintPosition>newArrayList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstraintSystemImpl(boolean error, Queue<ConstraintPosition> errorConstraintPositions) {
|
public ConstraintSystemImpl(boolean typeConstructorMismatch, Collection<ConstraintPosition> errorConstraintPositions) {
|
||||||
this.error = error;
|
this.typeConstructorMismatch = typeConstructorMismatch;
|
||||||
this.errorConstraintPositions = errorConstraintPositions;
|
this.errorConstraintPositions = errorConstraintPositions;
|
||||||
this.typeSubstitutor = TypeSubstitutor.create(new TypeSubstitution() {
|
this.typeSubstitutor = TypeSubstitutor.create(new TypeSubstitution() {
|
||||||
@Override
|
@Override
|
||||||
@@ -88,12 +87,13 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasError() {
|
public boolean hasTypeConstructorMismatch() {
|
||||||
return error;
|
return typeConstructorMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Queue<ConstraintPosition> getErrorConstraintPositions() {
|
public Collection<ConstraintPosition> getErrorConstraintPositions() {
|
||||||
return errorConstraintPositions;
|
return errorConstraintPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
|
|
||||||
if (exactType.getConstructor().getParameters().size() != expectedType.getConstructor().getParameters().size()) {
|
if (exactType.getConstructor().getParameters().size() != expectedType.getConstructor().getParameters().size()) {
|
||||||
errorConstraintPositions.add(constraintPosition);
|
errorConstraintPositions.add(constraintPosition);
|
||||||
error = true;
|
typeConstructorMismatch = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,15 +181,12 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
error = true;
|
typeConstructorMismatch = true;
|
||||||
errorConstraintPositions.add(constraintPosition);
|
errorConstraintPositions.add(constraintPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkConstraints(TypeParameterDescriptor typeParameterDescriptor) {
|
private boolean checkConstraints(TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
//todo refactor
|
//todo refactor
|
||||||
if (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TypeBounds typeBounds = typeParameterBounds.get(typeParameterDescriptor);
|
TypeBounds typeBounds = typeParameterBounds.get(typeParameterDescriptor);
|
||||||
if (typeBounds == null || typeBounds.isEmpty()) return true;
|
if (typeBounds == null || typeBounds.isEmpty()) return true;
|
||||||
JetType exactType = null;
|
JetType exactType = null;
|
||||||
@@ -268,14 +265,30 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
values.addAll(typeBounds.getExactValues());
|
values.addAll(typeBounds.getExactValues());
|
||||||
if (!typeBounds.getLowerBounds().isEmpty()) {
|
if (!typeBounds.getLowerBounds().isEmpty()) {
|
||||||
JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertype(typeBounds.getLowerBounds());
|
JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertype(typeBounds.getLowerBounds());
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
values.add(superTypeOfLowerBounds);
|
||||||
|
}
|
||||||
for (JetType value : values) {
|
for (JetType value : values) {
|
||||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(superTypeOfLowerBounds, value)) {
|
if (!JetTypeChecker.INSTANCE.isSubtypeOf(superTypeOfLowerBounds, value)) {
|
||||||
values.add(superTypeOfLowerBounds);
|
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;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +304,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<TypeSubstitutor> getSubstitutors() {
|
public Collection<TypeSubstitutor> getSubstitutors() {
|
||||||
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter();
|
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter();
|
||||||
@@ -334,18 +348,25 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSuccessful() {
|
public boolean isSuccessful() {
|
||||||
return !error && !hasUnknownParameters() && !hasContradiction();
|
return !hasTypeConstructorMismatch() && !hasUnknownParameters() && !hasConflictingParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasContradiction() {
|
public boolean hasContradiction() {
|
||||||
|
return hasTypeConstructorMismatch() || hasConflictingParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasConflictingParameters() {
|
||||||
for (TypeParameterDescriptor typeParameter : typeParameterBounds.keySet()) {
|
for (TypeParameterDescriptor typeParameter : typeParameterBounds.keySet()) {
|
||||||
if (!checkConstraints(typeParameter)) return true;
|
if (getValues(typeParameter).size() > 1) return true;
|
||||||
|
//if (!checkConstraints(typeParameter)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasUnknownParameters() {
|
@Override
|
||||||
|
public boolean hasUnknownParameters() {
|
||||||
for (TypeBounds bounds : typeParameterBounds.values()) {
|
for (TypeBounds bounds : typeParameterBounds.values()) {
|
||||||
if (bounds.isEmpty()) {
|
if (bounds.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
@@ -354,6 +375,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public TypeSubstitutor getSubstitutor() {
|
public TypeSubstitutor getSubstitutor() {
|
||||||
return typeSubstitutor;
|
return typeSubstitutor;
|
||||||
|
|||||||
Reference in New Issue
Block a user