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.ResolvedCallImpl.MAP_TO_CANDIDATE;
|
||||
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.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
|
||||
@@ -465,7 +468,7 @@ public class CallResolver {
|
||||
ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, traceForUnknown);
|
||||
JetType type = temporaryServices.getType(scope, expression, substituteDontCare.substitute(valueParameterDescriptor.getOutType(), Variance.INVARIANT));
|
||||
if (type != null) {
|
||||
constraintSystem.addSubtypingConstraint(type, effectiveExpectedType);
|
||||
constraintSystem.addSubtypingConstraint(VALUE_ARGUMENT.assertSubtyping(type, effectiveExpectedType));
|
||||
}
|
||||
else {
|
||||
candidateCall.argumentHasNoType();
|
||||
@@ -478,12 +481,12 @@ public class CallResolver {
|
||||
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
|
||||
ReceiverDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter();
|
||||
if (receiverArgument.exists() && receiverParameter.exists()) {
|
||||
constraintSystem.addSubtypingConstraint(receiverArgument.getType(), receiverParameter.getType());
|
||||
constraintSystem.addSubtypingConstraint(RECEIVER.assertSubtyping(receiverArgument.getType(), receiverParameter.getType()));
|
||||
}
|
||||
|
||||
// Return type
|
||||
if (expectedType != NO_EXPECTED_TYPE) {
|
||||
constraintSystem.addSubtypingConstraint(candidateWithFreshVariables.getReturnType(), expectedType);
|
||||
constraintSystem.addSubtypingConstraint(EXPECTED_TYPE.assertSubtyping(candidateWithFreshVariables.getReturnType(), expectedType));
|
||||
}
|
||||
|
||||
// Solution
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.resolve.calls.inference;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
|
||||
/**
|
||||
@@ -11,7 +10,7 @@ import org.jetbrains.jet.lang.types.Variance;
|
||||
public interface ConstraintSystem {
|
||||
void registerTypeVariable(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull Variance positionVariance);
|
||||
|
||||
void addSubtypingConstraint(@NotNull JetType lower, @NotNull JetType upper);
|
||||
void addSubtypingConstraint(@NotNull SubtypingConstraint constraint);
|
||||
|
||||
@NotNull
|
||||
ConstraintSystemSolution solve();
|
||||
|
||||
+13
-5
@@ -382,9 +382,9 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSubtypingConstraint(@NotNull JetType lower, @NotNull JetType upper) {
|
||||
TypeValue typeValueForLower = getTypeValueFor(lower);
|
||||
TypeValue typeValueForUpper = getTypeValueFor(upper);
|
||||
public void addSubtypingConstraint(@NotNull SubtypingConstraint constraint) {
|
||||
TypeValue typeValueForLower = getTypeValueFor(constraint.getSubtype());
|
||||
TypeValue typeValueForUpper = getTypeValueFor(constraint.getSupertype());
|
||||
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
|
||||
|
||||
+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