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 c452a12ec8b..87f500890b1 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 @@ -338,7 +338,8 @@ public class CallResolver { ConstraintsSystem constraintsSystem = resolvedCall.getConstraintsSystem(); assert constraintsSystem != null; - constraintsSystem.addSupertypeConstraint(context.expectedType, descriptor.getReturnType(), ConstraintPosition.EXPECTED_TYPE_POSITION); + constraintsSystem.addSubtypingConstraint(descriptor.getReturnType(), context.expectedType, + ConstraintPosition.EXPECTED_TYPE_POSITION); // constraints for function literals // Value parameters @@ -744,7 +745,8 @@ public class CallResolver { ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument(); ReceiverDescriptor receiverParameter = candidateWithFreshVariables.getReceiverParameter(); if (receiverArgument.exists() && receiverParameter.exists()) { - constraintsSystem.addSubtypingConstraint(receiverArgument.getType(), receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION); + constraintsSystem.addSupertypeConstraint(receiverParameter.getType(), receiverArgument.getType(), + ConstraintPosition.RECEIVER_POSITION); } ConstraintsSystemImpl constraintsBuilderWithRightTypeParameters = new ConstraintsSystemImpl(constraintsSystem.hasTypeConstructorMismatch(), constraintsSystem @@ -785,7 +787,7 @@ public class CallResolver { context.scope, argumentExpression, substitutor.substitute(valueParameterDescriptor.getType(), Variance.INVARIANT), context.dataFlowInfo, traceForUnknown) : null; if (type == null || ErrorUtils.isErrorType(type)) return false; - constraintsSystem.addSubtypingConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( + constraintsSystem.addSupertypeConstraint(effectiveExpectedType, type, ConstraintPosition.getValueParameterPosition( valueParameterDescriptor.getIndex())); return true; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java index c9c63bf020e..4eec087690c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java @@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure; import java.util.*; @@ -46,9 +45,9 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { return ConstraintKind.EQUAL; } if (variance == Variance.OUT_VARIANCE) { - return ConstraintKind.SUB_TYPE; + return ConstraintKind.SUPER_TYPE; } - return ConstraintKind.SUPER_TYPE; + return ConstraintKind.SUB_TYPE; } private final Map typeParameterConstraints = Maps.newLinkedHashMap(); @@ -123,63 +122,66 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { addConstraint(ConstraintKind.SUPER_TYPE, subjectType, constrainingType, constraintPosition); } - private void addConstraint(@NotNull ConstraintKind constraintKind, @NotNull JetType subjectType, @NotNull JetType constrainingType, + private void addConstraint(@NotNull ConstraintKind constraintKind, + @NotNull JetType subjectType, + @NotNull JetType constrainingType, @NotNull ConstraintPosition constraintPosition) { - if (subjectType == DONT_CARE || constrainingType == DONT_CARE || subjectType == TypeUtils.NO_EXPECTED_TYPE - || constrainingType == TypeUtils.NO_EXPECTED_TYPE) { + + if (constrainingType == DONT_CARE || subjectType == DONT_CARE || constrainingType == TypeUtils.NO_EXPECTED_TYPE + || subjectType == TypeUtils.NO_EXPECTED_TYPE) { return; } DeclarationDescriptor constrainingTypeDescriptor = constrainingType.getConstructor().getDeclarationDescriptor(); DeclarationDescriptor subjectTypeDescriptor = subjectType.getConstructor().getDeclarationDescriptor(); - if (constrainingTypeDescriptor instanceof TypeParameterDescriptor) { - if (TypeUtils.dependsOnTypeParameterConstructors(subjectType, Collections.singleton(DONT_CARE.getConstructor()))) return; - if (constrainingType.isNullable()) { - subjectType = TypeUtils.makeNotNullable(subjectType); + if (subjectTypeDescriptor instanceof TypeParameterDescriptor) { + if (TypeUtils.dependsOnTypeParameterConstructors(constrainingType, Collections.singleton(DONT_CARE.getConstructor()))) return; + if (subjectType.isNullable()) { + constrainingType = TypeUtils.makeNotNullable(constrainingType); } - TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) constrainingTypeDescriptor; - if (constraintKind == ConstraintKind.SUB_TYPE) { - typeParameterConstraints.get(typeParameter).addLowerBound(subjectType); + TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) subjectTypeDescriptor; + if (constraintKind == ConstraintKind.SUPER_TYPE) { + typeParameterConstraints.get(typeParameter).addLowerBound(constrainingType); } - else if (constraintKind == ConstraintKind.SUPER_TYPE) { - typeParameterConstraints.get(typeParameter).addUpperBound(subjectType); + else if (constraintKind == ConstraintKind.SUB_TYPE) { + typeParameterConstraints.get(typeParameter).addUpperBound(constrainingType); } else { - typeParameterConstraints.get(typeParameter).addExactBound(subjectType); + typeParameterConstraints.get(typeParameter).addExactBound(constrainingType); } return; } - if (subjectTypeDescriptor instanceof ClassDescriptor && constrainingTypeDescriptor instanceof ClassDescriptor) { - if (constraintKind != ConstraintKind.SUPER_TYPE) { - JetType correspondingSupertype = TypeCheckingProcedure.findCorrespondingSupertype(subjectType, constrainingType); - if (correspondingSupertype != null) { - subjectType = correspondingSupertype; - } - } - else { + if (constrainingTypeDescriptor instanceof ClassDescriptor && subjectTypeDescriptor instanceof ClassDescriptor) { + if (constraintKind != ConstraintKind.SUB_TYPE) { JetType correspondingSupertype = TypeCheckingProcedure.findCorrespondingSupertype(constrainingType, subjectType); if (correspondingSupertype != null) { constrainingType = correspondingSupertype; } } + else { + JetType correspondingSupertype = TypeCheckingProcedure.findCorrespondingSupertype(subjectType, constrainingType); + if (correspondingSupertype != null) { + subjectType = correspondingSupertype; + } + } - if (subjectType.getConstructor().getParameters().size() != constrainingType.getConstructor().getParameters().size()) { + if (constrainingType.getConstructor().getParameters().size() != subjectType.getConstructor().getParameters().size()) { errorConstraintPositions.add(constraintPosition); typeConstructorMismatch = true; return; } - ClassDescriptor subClass = (ClassDescriptor) subjectType.getConstructor().getDeclarationDescriptor(); - ClassDescriptor superClass = (ClassDescriptor) constrainingType.getConstructor().getDeclarationDescriptor(); + ClassDescriptor subClass = (ClassDescriptor) constrainingType.getConstructor().getDeclarationDescriptor(); + ClassDescriptor superClass = (ClassDescriptor) subjectType.getConstructor().getDeclarationDescriptor(); if (DescriptorUtils.isSubclass(subClass, superClass)) { - List subArguments = subjectType.getArguments(); - List superArguments = constrainingType.getArguments(); - List superParameters = constrainingType.getConstructor().getParameters(); + List subArguments = constrainingType.getArguments(); + List superArguments = subjectType.getArguments(); + List superParameters = subjectType.getConstructor().getParameters(); for (int i = 0; i < superArguments.size(); i++) { - addConstraint(varianceToConstraintKind(superParameters.get(i).getVariance()), subArguments.get(i).getType(), superArguments.get(i).getType(), - constraintPosition); + addConstraint(varianceToConstraintKind(superParameters.get(i).getVariance()), superArguments.get(i).getType(), + subArguments.get(i).getType(), constraintPosition); } return; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index 3c269ea52ab..41e811aaa5a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -239,7 +239,7 @@ public class ExpressionTypingUtils { ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter(); if (expectedReceiver.exists() && receiverParameter.exists()) { - constraintsSystem.addSubtypingConstraint(receiverType, receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION); + constraintsSystem.addSupertypeConstraint(receiverParameter.getType(), receiverType, ConstraintPosition.RECEIVER_POSITION); } else if (expectedReceiver.exists() || receiverParameter.exists()) { // Only one of receivers exist