Constraint priorities introduced. Not used for the time being
This commit is contained in:
@@ -29,6 +29,9 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
|||||||
import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.*;
|
import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_CANDIDATE;
|
import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_CANDIDATE;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_RESULT;
|
import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_RESULT;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.EXPECTED_TYPE;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.VALUE_ARGUMENT;
|
||||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
@@ -465,7 +468,7 @@ public class CallResolver {
|
|||||||
ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, traceForUnknown);
|
ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, traceForUnknown);
|
||||||
JetType type = temporaryServices.getType(scope, expression, substituteDontCare.substitute(valueParameterDescriptor.getOutType(), Variance.INVARIANT));
|
JetType type = temporaryServices.getType(scope, expression, substituteDontCare.substitute(valueParameterDescriptor.getOutType(), Variance.INVARIANT));
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
constraintSystem.addSubtypingConstraint(type, effectiveExpectedType);
|
constraintSystem.addSubtypingConstraint(VALUE_ARGUMENT.assertSubtyping(type, effectiveExpectedType));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
candidateCall.argumentHasNoType();
|
candidateCall.argumentHasNoType();
|
||||||
@@ -478,12 +481,12 @@ public class CallResolver {
|
|||||||
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
|
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
|
||||||
ReceiverDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter();
|
ReceiverDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter();
|
||||||
if (receiverArgument.exists() && receiverParameter.exists()) {
|
if (receiverArgument.exists() && receiverParameter.exists()) {
|
||||||
constraintSystem.addSubtypingConstraint(receiverArgument.getType(), receiverParameter.getType());
|
constraintSystem.addSubtypingConstraint(RECEIVER.assertSubtyping(receiverArgument.getType(), receiverParameter.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return type
|
// Return type
|
||||||
if (expectedType != NO_EXPECTED_TYPE) {
|
if (expectedType != NO_EXPECTED_TYPE) {
|
||||||
constraintSystem.addSubtypingConstraint(candidateWithFreshVariables.getReturnType(), expectedType);
|
constraintSystem.addSubtypingConstraint(EXPECTED_TYPE.assertSubtyping(candidateWithFreshVariables.getReturnType(), expectedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solution
|
// Solution
|
||||||
|
|||||||
+1
-2
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.resolve.calls.inference;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.jetbrains.jet.lang.types.Variance;
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,7 +10,7 @@ import org.jetbrains.jet.lang.types.Variance;
|
|||||||
public interface ConstraintSystem {
|
public interface ConstraintSystem {
|
||||||
void registerTypeVariable(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull Variance positionVariance);
|
void registerTypeVariable(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull Variance positionVariance);
|
||||||
|
|
||||||
void addSubtypingConstraint(@NotNull JetType lower, @NotNull JetType upper);
|
void addSubtypingConstraint(@NotNull SubtypingConstraint constraint);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
ConstraintSystemSolution solve();
|
ConstraintSystemSolution solve();
|
||||||
|
|||||||
+13
-5
@@ -382,9 +382,9 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addSubtypingConstraint(@NotNull JetType lower, @NotNull JetType upper) {
|
public void addSubtypingConstraint(@NotNull SubtypingConstraint constraint) {
|
||||||
TypeValue typeValueForLower = getTypeValueFor(lower);
|
TypeValue typeValueForLower = getTypeValueFor(constraint.getSubtype());
|
||||||
TypeValue typeValueForUpper = getTypeValueFor(upper);
|
TypeValue typeValueForUpper = getTypeValueFor(constraint.getSupertype());
|
||||||
addSubtypingConstraintOnTypeValues(typeValueForLower, typeValueForUpper);
|
addSubtypingConstraintOnTypeValues(typeValueForLower, typeValueForUpper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,8 +415,16 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower bounds?
|
for (TypeValue lowerBound : typeValue.getLowerBounds()) {
|
||||||
|
if (lowerBound instanceof KnownType) {
|
||||||
|
KnownType knownBoundType = (KnownType) lowerBound;
|
||||||
|
boolean ok = constraintExpander.isSubtypeOf(knownBoundType.getType(), jetType);
|
||||||
|
if (!ok) {
|
||||||
|
listener.error("Error while expanding '" + knownBoundType.getType() + " :< " + jetType + "'");
|
||||||
|
return new Solution().registerError("Mismatch while expanding constraints");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in upper bounds from type parameter bounds
|
// Fill in upper bounds from type parameter bounds
|
||||||
|
|||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.calls.inference;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public enum ConstraintType implements Comparable<ConstraintType> {
|
||||||
|
// The order of these constants DOES matter
|
||||||
|
// they are compared according to ordinal() values
|
||||||
|
// First element has the highest priority
|
||||||
|
RECEIVER("{0} is not a subtype of the expected receiver type {1}"),
|
||||||
|
VALUE_ARGUMENT("Type mismatch: argument type is {0}, but {1} was expected"),
|
||||||
|
EXPECTED_TYPE("Resulting type is {0} but {1} was expected"),
|
||||||
|
PARAMETER_BOUND("Type parameter bound is not satisfied: {0} is not a subtype of {1}");
|
||||||
|
|
||||||
|
private final String errorMessageTemplate; // {0} is subtype, {1} is supertye
|
||||||
|
|
||||||
|
private ConstraintType(@NotNull String errorMessageTemplate) {
|
||||||
|
this.errorMessageTemplate = errorMessageTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public SubtypingConstraint assertSubtyping(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||||
|
return new SubtypingConstraint(this, subtype, supertype);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String makeErrorMessage(@NotNull SubtypingConstraint constraint) {
|
||||||
|
return MessageFormat.format(errorMessageTemplate, constraint.getSubtype(), constraint.getSupertype());
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.calls.inference;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class SubtypingConstraint {
|
||||||
|
private final ConstraintType type;
|
||||||
|
private final JetType subtype;
|
||||||
|
private final JetType supertype;
|
||||||
|
|
||||||
|
public SubtypingConstraint(@NotNull ConstraintType type, @NotNull JetType subtype, @NotNull JetType supertype) {
|
||||||
|
this.type = type;
|
||||||
|
this.subtype = subtype;
|
||||||
|
this.supertype = supertype;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetType getSubtype() {
|
||||||
|
return subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JetType getSupertype() {
|
||||||
|
return supertype;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public ConstraintType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return type.makeErrorMessage(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user