This commit is contained in:
Svetlana Isakova
2012-07-19 15:38:37 +04:00
parent b161b6bfbf
commit d2c65b8529
9 changed files with 76 additions and 77 deletions
@@ -170,17 +170,17 @@ public class Renderers {
public static TabledDescriptorRenderer renderConflictingSubstitutionsInferenceError(InferenceErrorData inferenceErrorData, public static TabledDescriptorRenderer renderConflictingSubstitutionsInferenceError(InferenceErrorData inferenceErrorData,
TabledDescriptorRenderer result) { TabledDescriptorRenderer result) {
assert inferenceErrorData.constraintsSystem.hasConflictingConstraints(); assert inferenceErrorData.constraintSystem.hasConflictingConstraints();
Collection<CallableDescriptor> substitutedDescriptors = Lists.newArrayList(); Collection<CallableDescriptor> substitutedDescriptors = Lists.newArrayList();
Collection<TypeSubstitutor> substitutors = ConstraintsUtil.getSubstitutorsForConflictingParameters( Collection<TypeSubstitutor> substitutors = ConstraintsUtil.getSubstitutorsForConflictingParameters(
inferenceErrorData.constraintsSystem); inferenceErrorData.constraintSystem);
for (TypeSubstitutor substitutor : substitutors) { for (TypeSubstitutor substitutor : substitutors) {
CallableDescriptor substitutedDescriptor = inferenceErrorData.descriptor.substitute(substitutor); CallableDescriptor substitutedDescriptor = inferenceErrorData.descriptor.substitute(substitutor);
substitutedDescriptors.add(substitutedDescriptor); substitutedDescriptors.add(substitutedDescriptor);
} }
TypeParameterDescriptor firstConflictingParameter = ConstraintsUtil.getFirstConflictingParameter(inferenceErrorData.constraintsSystem); TypeParameterDescriptor firstConflictingParameter = ConstraintsUtil.getFirstConflictingParameter(inferenceErrorData.constraintSystem);
assert firstConflictingParameter != null; assert firstConflictingParameter != null;
result.text(newText() result.text(newText()
@@ -232,7 +232,7 @@ public class Renderers {
@Override @Override
public boolean apply(@Nullable ConstraintPosition constraintPosition) { public boolean apply(@Nullable ConstraintPosition constraintPosition) {
assert constraintPosition != null; assert constraintPosition != null;
return inferenceErrorData.constraintsSystem.hasTypeConstructorMismatchAt(constraintPosition); return inferenceErrorData.constraintSystem.hasTypeConstructorMismatchAt(constraintPosition);
} }
}; };
return renderer.table(TabledDescriptorRenderer.newTable() return renderer.table(TabledDescriptorRenderer.newTable()
@@ -247,8 +247,8 @@ public class Renderers {
public static TabledDescriptorRenderer renderNoInformationForParameterError(InferenceErrorData inferenceErrorData, public static TabledDescriptorRenderer renderNoInformationForParameterError(InferenceErrorData inferenceErrorData,
TabledDescriptorRenderer renderer) { TabledDescriptorRenderer renderer) {
TypeParameterDescriptor firstUnknownParameter = null; TypeParameterDescriptor firstUnknownParameter = null;
for (TypeParameterDescriptor typeParameter : inferenceErrorData.constraintsSystem.getTypeVariables()) { for (TypeParameterDescriptor typeParameter : inferenceErrorData.constraintSystem.getTypeVariables()) {
if (inferenceErrorData.constraintsSystem.getTypeConstraints(typeParameter).isEmpty()) { if (inferenceErrorData.constraintSystem.getTypeConstraints(typeParameter).isEmpty()) {
firstUnknownParameter = typeParameter; firstUnknownParameter = typeParameter;
break; break;
} }
@@ -267,7 +267,7 @@ public class Renderers {
public static TabledDescriptorRenderer renderUpperBoundViolatedInferenceError(InferenceErrorData inferenceErrorData, TabledDescriptorRenderer result) { public static TabledDescriptorRenderer renderUpperBoundViolatedInferenceError(InferenceErrorData inferenceErrorData, TabledDescriptorRenderer result) {
TypeParameterDescriptor typeParameterDescriptor = null; TypeParameterDescriptor typeParameterDescriptor = null;
for (TypeParameterDescriptor typeParameter : inferenceErrorData.descriptor.getTypeParameters()) { for (TypeParameterDescriptor typeParameter : inferenceErrorData.descriptor.getTypeParameters()) {
if (!ConstraintsUtil.checkUpperBoundIsSatisfied(inferenceErrorData.constraintsSystem, typeParameter)) { if (!ConstraintsUtil.checkUpperBoundIsSatisfied(inferenceErrorData.constraintSystem, typeParameter)) {
typeParameterDescriptor = typeParameter; typeParameterDescriptor = typeParameter;
break; break;
} }
@@ -278,9 +278,9 @@ public class Renderers {
.table(newTable(). .table(newTable().
descriptor(inferenceErrorData.descriptor)); descriptor(inferenceErrorData.descriptor));
JetType type = ConstraintsUtil.getValue(inferenceErrorData.constraintsSystem.getTypeConstraints(typeParameterDescriptor)); JetType type = ConstraintsUtil.getValue(inferenceErrorData.constraintSystem.getTypeConstraints(typeParameterDescriptor));
JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType(); JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType();
JetType substitute = inferenceErrorData.constraintsSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT); JetType substitute = inferenceErrorData.constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
result.text(newText() result.text(newText()
.normal(" is not satisfied: inferred type ") .normal(" is not satisfied: inferred type ")
@@ -340,10 +340,10 @@ public class CallResolver {
) { ) {
assert resolvedCall.hasUnknownTypeParameters(); assert resolvedCall.hasUnknownTypeParameters();
D descriptor = resolvedCall.getCandidateDescriptor(); D descriptor = resolvedCall.getCandidateDescriptor();
ConstraintsSystem constraintsSystem = resolvedCall.getConstraintsSystem(); ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
assert constraintsSystem != null; assert constraintSystem != null;
constraintsSystem.addSubtypingConstraint(descriptor.getReturnType(), context.expectedType, constraintSystem.addSubtypingConstraint(descriptor.getReturnType(), context.expectedType,
ConstraintPosition.EXPECTED_TYPE_POSITION); ConstraintPosition.EXPECTED_TYPE_POSITION);
// constraints for function literals // constraints for function literals
@@ -355,23 +355,23 @@ public class CallResolver {
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) { for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue; if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintsSystem.getCurrentSubstitutor(), addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintSystem.getCurrentSubstitutor(),
constraintsSystem, context); constraintSystem, context);
} }
} }
if (!constraintsSystem.isSuccessful()) { if (!constraintSystem.isSuccessful()) {
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, context.trace).argumentTypes; List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, context.trace).argumentTypes;
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null; JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
tracing.typeInferenceFailed(context.trace, tracing.typeInferenceFailed(context.trace,
InferenceErrorData.create(descriptor, constraintsSystem, argumentTypes, receiverType, context.expectedType)); InferenceErrorData.create(descriptor, constraintSystem, argumentTypes, receiverType, context.expectedType));
resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR); resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR);
failed.add(resolvedCall); failed.add(resolvedCall);
return; return;
} }
D substitute = (D) descriptor.substitute(constraintsSystem.getResultingSubstitutor()); D substitute = (D) descriptor.substitute(constraintSystem.getResultingSubstitutor());
assert substitute != null; assert substitute != null;
replaceValueParametersWithSubstitutedOnes(resolvedCall, substitute); replaceValueParametersWithSubstitutedOnes(resolvedCall, substitute);
resolvedCall.setResultingDescriptor(substitute); //replacement resolvedCall.setResultingDescriptor(substitute); //replacement
@@ -379,7 +379,7 @@ public class CallResolver {
// Here we type check the arguments with inferred types expected // Here we type check the arguments with inferred types expected
checkValueArgumentTypes(context, resolvedCall, context.trace); checkValueArgumentTypes(context, resolvedCall, context.trace);
checkBounds(resolvedCall, constraintsSystem, context.trace, tracing); checkBounds(resolvedCall, constraintSystem, context.trace, tracing);
resolvedCall.setHasUnknownTypeParameters(false); resolvedCall.setHasUnknownTypeParameters(false);
if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) { if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) {
resolvedCall.addStatus(ResolutionStatus.SUCCESS); resolvedCall.addStatus(ResolutionStatus.SUCCESS);
@@ -392,13 +392,13 @@ public class CallResolver {
private <D extends CallableDescriptor> void checkBounds( private <D extends CallableDescriptor> void checkBounds(
@NotNull ResolvedCallImpl<D> call, @NotNull ResolvedCallImpl<D> call,
@NotNull ConstraintsSystem constraintsSystem, @NotNull ConstraintSystem constraintSystem,
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) { for (TypeParameterDescriptor typeParameter : call.getCandidateDescriptor().getTypeParameters()) {
if (!ConstraintsUtil.checkUpperBoundIsSatisfied(constraintsSystem, typeParameter)) { if (!ConstraintsUtil.checkUpperBoundIsSatisfied(constraintSystem, typeParameter)) {
tracing.upperBoundViolated(trace, InferenceErrorData.create(call.getCandidateDescriptor(), constraintsSystem)); tracing.upperBoundViolated(trace, InferenceErrorData.create(call.getCandidateDescriptor(), constraintSystem));
} }
} }
} }
@@ -693,7 +693,7 @@ public class CallResolver {
ResolutionDebugInfo.Data debugInfo = context.trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement()); ResolutionDebugInfo.Data debugInfo = context.trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement());
ConstraintsSystemImpl constraintsSystem = new ConstraintsSystemImpl(); ConstraintSystemImpl constraintsSystem = new ConstraintSystemImpl();
// If the call is recursive, e.g. // If the call is recursive, e.g.
// fun foo<T>(t : T) : T = foo(t) // fun foo<T>(t : T) : T = foo(t)
@@ -709,7 +709,7 @@ public class CallResolver {
} }
TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities
.makeConstantSubstitutor(candidateWithFreshVariables.getTypeParameters(), ConstraintsSystemImpl.DONT_CARE); .makeConstantSubstitutor(candidateWithFreshVariables.getTypeParameters(), ConstraintSystemImpl.DONT_CARE);
// Value parameters // Value parameters
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) { for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
@@ -746,8 +746,8 @@ public class CallResolver {
typeVariablesMap.put(candidateWithFreshVariables.getTypeParameters().get(typeParameterDescriptor.getIndex()), typeVariablesMap.put(candidateWithFreshVariables.getTypeParameters().get(typeParameterDescriptor.getIndex()),
typeParameterDescriptor); typeParameterDescriptor);
} }
ConstraintsSystem constraintsBuilderWithRightTypeParameters = constraintsSystem.replaceTypeVariables(typeVariablesMap); ConstraintSystem constraintBuilderWithRightTypeParameters = constraintsSystem.replaceTypeVariables(typeVariablesMap);
candidateCall.setConstraintsSystem(constraintsBuilderWithRightTypeParameters); candidateCall.setConstraintSystem(constraintBuilderWithRightTypeParameters);
// Solution // Solution
@@ -761,7 +761,7 @@ public class CallResolver {
List<JetType> argumentTypes = checkingResult.argumentTypes; List<JetType> argumentTypes = checkingResult.argumentTypes;
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null; JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
context.tracing.typeInferenceFailed(context.trace, context.tracing.typeInferenceFailed(context.trace,
InferenceErrorData.create(candidate, constraintsBuilderWithRightTypeParameters, argumentTypes, receiverType, context.expectedType)); InferenceErrorData.create(candidate, constraintBuilderWithRightTypeParameters, argumentTypes, receiverType, context.expectedType));
return TYPE_INFERENCE_ERROR.combine(argumentsStatus); return TYPE_INFERENCE_ERROR.combine(argumentsStatus);
} }
} }
@@ -769,7 +769,7 @@ public class CallResolver {
private boolean addConstraintForValueArgument(ValueArgument valueArgument, private boolean addConstraintForValueArgument(ValueArgument valueArgument,
@NotNull ValueParameterDescriptor valueParameterDescriptor, @NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull TypeSubstitutor substitutor, @NotNull TypeSubstitutor substitutor,
@NotNull ConstraintsSystem constraintsSystem, @NotNull ConstraintSystem constraintSystem,
@NotNull ResolutionContext context) { @NotNull ResolutionContext context) {
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
@@ -778,7 +778,7 @@ public class CallResolver {
JetType type = argumentExpression != null ? expressionTypingServices.getType( JetType type = argumentExpression != null ? expressionTypingServices.getType(
context.scope, argumentExpression, substitutor.substitute(valueParameterDescriptor.getType(), Variance.INVARIANT), context.scope, argumentExpression, substitutor.substitute(valueParameterDescriptor.getType(), Variance.INVARIANT),
context.dataFlowInfo, traceForUnknown) : null; context.dataFlowInfo, traceForUnknown) : null;
constraintsSystem.addSupertypeConstraint(effectiveExpectedType, type, ConstraintPosition.getValueParameterPosition( constraintSystem.addSupertypeConstraint(effectiveExpectedType, type, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex())); valueParameterDescriptor.getIndex()));
//todo no return //todo no return
if (type == null || ErrorUtils.isErrorType(type)) return false; if (type == null || ErrorUtils.isErrorType(type)) return false;
@@ -977,7 +977,7 @@ public class CallResolver {
if (argument.getSpreadElement() != null) { if (argument.getSpreadElement() != null) {
if (parameterDescriptor.getVarargElementType() == null) { if (parameterDescriptor.getVarargElementType() == null) {
// Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper // Spread argument passed to a non-vararg parameter, an error is already reported by ValueArgumentsToParametersMapper
return ConstraintsSystemImpl.DONT_CARE; return ConstraintSystemImpl.DONT_CARE;
} }
else { else {
return parameterDescriptor.getType(); return parameterDescriptor.getType();
@@ -27,8 +27,7 @@ import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData; import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -236,24 +235,24 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends R
@Override @Override
public void typeInferenceFailed(@NotNull BindingTrace trace, @NotNull InferenceErrorData data) { public void typeInferenceFailed(@NotNull BindingTrace trace, @NotNull InferenceErrorData data) {
ConstraintsSystem constraintsSystem = data.constraintsSystem; ConstraintSystem constraintSystem = data.constraintSystem;
assert !constraintsSystem.isSuccessful(); assert !constraintSystem.isSuccessful();
if (constraintsSystem.hasErrorInConstrainingTypes()) { if (constraintSystem.hasErrorInConstrainingTypes()) {
return; return;
} }
if (constraintsSystem.hasExpectedTypeMismatch()) { if (constraintSystem.hasExpectedTypeMismatch()) {
JetType returnType = data.descriptor.getReturnType(); JetType returnType = data.descriptor.getReturnType();
assert returnType != null; assert returnType != null;
trace.report(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH.on(reference, returnType, data.expectedType)); trace.report(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH.on(reference, returnType, data.expectedType));
} }
else if (constraintsSystem.hasTypeConstructorMismatch()) { else if (constraintSystem.hasTypeConstructorMismatch()) {
trace.report(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH.on(reference, data)); trace.report(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH.on(reference, data));
} }
else if (constraintsSystem.hasConflictingConstraints()) { else if (constraintSystem.hasConflictingConstraints()) {
trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(reference, data)); trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(reference, data));
} }
else { else {
assert constraintsSystem.hasUnknownParameters(); assert constraintSystem.hasUnknownParameters();
trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(reference, data)); trace.report(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(reference, data));
} }
} }
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsSystem; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -72,7 +72,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
private TemporaryBindingTrace trace; private TemporaryBindingTrace trace;
private ResolutionStatus status = UNKNOWN_STATUS; private ResolutionStatus status = UNKNOWN_STATUS;
private boolean hasUnknownTypeParameters = false; private boolean hasUnknownTypeParameters = false;
private ConstraintsSystem constraintsSystem = null; private ConstraintSystem constraintSystem = null;
private ResolvedCallImpl(@NotNull ResolutionCandidate<D> candidate, @NotNull TemporaryBindingTrace trace) { private ResolvedCallImpl(@NotNull ResolutionCandidate<D> candidate, @NotNull TemporaryBindingTrace trace) {
this.candidateDescriptor = candidate.getDescriptor(); this.candidateDescriptor = candidate.getDescriptor();
@@ -130,13 +130,13 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
typeArguments.put(typeParameter, typeArgument); typeArguments.put(typeParameter, typeArgument);
} }
public void setConstraintsSystem(@NotNull ConstraintsSystem constraintsSystem) { public void setConstraintSystem(@NotNull ConstraintSystem constraintSystem) {
this.constraintsSystem = constraintsSystem; this.constraintSystem = constraintSystem;
} }
@Nullable @Nullable
public ConstraintsSystem getConstraintsSystem() { public ConstraintSystem getConstraintSystem() {
return constraintsSystem; return constraintSystem;
} }
public void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument) { public void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument) {
@@ -28,7 +28,7 @@ import java.util.Set;
/** /**
* @author svtk * @author svtk
*/ */
public interface ConstraintsSystem { public interface ConstraintSystem {
/** /**
* Registers a variable in a constraint system. * Registers a variable in a constraint system.
@@ -32,7 +32,7 @@ import java.util.*;
/** /**
* @author svtk * @author svtk
*/ */
public class ConstraintsSystemImpl implements ConstraintsSystem { public class ConstraintSystemImpl implements ConstraintSystem {
public static final JetType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE"); public static final JetType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE");
@@ -42,7 +42,7 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
private final TypeSubstitutor currentSubstitutor; private final TypeSubstitutor currentSubstitutor;
private boolean hasErrorInConstrainingTypes; private boolean hasErrorInConstrainingTypes;
public ConstraintsSystemImpl() { public ConstraintSystemImpl() {
this.resultingSubstitutor = createTypeSubstitutorWithDefaultForUnknownTypeParameter(null); this.resultingSubstitutor = createTypeSubstitutorWithDefaultForUnknownTypeParameter(null);
this.currentSubstitutor = createTypeSubstitutorWithDefaultForUnknownTypeParameter(new TypeProjection(DONT_CARE)); this.currentSubstitutor = createTypeSubstitutorWithDefaultForUnknownTypeParameter(new TypeProjection(DONT_CARE));
} }
@@ -105,8 +105,8 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
} }
@NotNull @NotNull
public ConstraintsSystemImpl replaceTypeVariables(@NotNull Map<TypeParameterDescriptor, TypeParameterDescriptor> typeVariablesMap) { public ConstraintSystemImpl replaceTypeVariables(@NotNull Map<TypeParameterDescriptor, TypeParameterDescriptor> typeVariablesMap) {
ConstraintsSystemImpl newConstraintSystem = new ConstraintsSystemImpl(); ConstraintSystemImpl newConstraintSystem = new ConstraintSystemImpl();
for (Map.Entry<TypeParameterDescriptor, TypeConstraintsImpl> entry : typeParameterConstraints.entrySet()) { for (Map.Entry<TypeParameterDescriptor, TypeConstraintsImpl> entry : typeParameterConstraints.entrySet()) {
TypeParameterDescriptor typeParameter = entry.getKey(); TypeParameterDescriptor typeParameter = entry.getKey();
TypeConstraintsImpl typeConstraints = entry.getValue(); TypeConstraintsImpl typeConstraints = entry.getValue();
@@ -84,9 +84,9 @@ public class ConstraintsUtil {
@Nullable @Nullable
public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintsSystem constraintsSystem) { public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintSystem constraintSystem) {
for (TypeParameterDescriptor typeParameter : constraintsSystem.getTypeVariables()) { for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeVariables()) {
TypeConstraints constraints = constraintsSystem.getTypeConstraints(typeParameter); TypeConstraints constraints = constraintSystem.getTypeConstraints(typeParameter);
if (getValues(constraints).size() > 1) { if (getValues(constraints).size() > 1) {
return typeParameter; return typeParameter;
} }
@@ -95,11 +95,11 @@ public class ConstraintsUtil {
} }
@NotNull @NotNull
public static Collection<TypeSubstitutor> getSubstitutorsForConflictingParameters(@NotNull ConstraintsSystem constraintsSystem) { public static Collection<TypeSubstitutor> getSubstitutorsForConflictingParameters(@NotNull ConstraintSystem constraintSystem) {
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter(constraintsSystem); TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter(constraintSystem);
if (firstConflictingParameter == null) return Collections.emptyList(); if (firstConflictingParameter == null) return Collections.emptyList();
Collection<JetType> conflictingTypes = getValues(constraintsSystem.getTypeConstraints(firstConflictingParameter)); Collection<JetType> conflictingTypes = getValues(constraintSystem.getTypeConstraints(firstConflictingParameter));
ArrayList<Map<TypeConstructor, TypeProjection>> substitutionContexts = Lists.newArrayList(); ArrayList<Map<TypeConstructor, TypeProjection>> substitutionContexts = Lists.newArrayList();
for (JetType type : conflictingTypes) { for (JetType type : conflictingTypes) {
@@ -108,10 +108,10 @@ public class ConstraintsUtil {
substitutionContexts.add(context); substitutionContexts.add(context);
} }
for (TypeParameterDescriptor typeParameter : constraintsSystem.getTypeVariables()) { for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeVariables()) {
if (typeParameter == firstConflictingParameter) continue; if (typeParameter == firstConflictingParameter) continue;
JetType safeType = getSafeValue(constraintsSystem, typeParameter); JetType safeType = getSafeValue(constraintSystem, typeParameter);
for (Map<TypeConstructor, TypeProjection> context : substitutionContexts) { for (Map<TypeConstructor, TypeProjection> context : substitutionContexts) {
TypeProjection typeProjection = new TypeProjection(safeType); TypeProjection typeProjection = new TypeProjection(safeType);
context.put(typeParameter.getTypeConstructor(), typeProjection); context.put(typeParameter.getTypeConstructor(), typeProjection);
@@ -125,8 +125,8 @@ public class ConstraintsUtil {
} }
@NotNull @NotNull
public static JetType getSafeValue(@NotNull ConstraintsSystem constraintsSystem, @NotNull TypeParameterDescriptor typeParameter) { public static JetType getSafeValue(@NotNull ConstraintSystem constraintSystem, @NotNull TypeParameterDescriptor typeParameter) {
TypeConstraints constraints = constraintsSystem.getTypeConstraints(typeParameter); TypeConstraints constraints = constraintSystem.getTypeConstraints(typeParameter);
JetType type = getValue(constraints); JetType type = getValue(constraints);
if (type != null) { if (type != null) {
return type; return type;
@@ -135,13 +135,13 @@ public class ConstraintsUtil {
return typeParameter.getUpperBoundsAsType(); return typeParameter.getUpperBoundsAsType();
} }
public static boolean checkUpperBoundIsSatisfied(@NotNull ConstraintsSystem constraintsSystem, public static boolean checkUpperBoundIsSatisfied(@NotNull ConstraintSystem constraintSystem,
@NotNull TypeParameterDescriptor typeParameter) { @NotNull TypeParameterDescriptor typeParameter) {
TypeConstraints typeConstraints = constraintsSystem.getTypeConstraints(typeParameter); TypeConstraints typeConstraints = constraintSystem.getTypeConstraints(typeParameter);
assert typeConstraints != null; assert typeConstraints != null;
JetType type = getValue(typeConstraints); JetType type = getValue(typeConstraints);
JetType upperBound = typeParameter.getUpperBoundsAsType(); JetType upperBound = typeParameter.getUpperBoundsAsType();
JetType substitute = constraintsSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT); JetType substitute = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
if (type != null) { if (type != null) {
if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) { if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) {
@@ -151,11 +151,11 @@ public class ConstraintsUtil {
return true; return true;
} }
public static boolean checkBoundsAreSatisfied(ConstraintsSystem constraintsSystem) { public static boolean checkBoundsAreSatisfied(ConstraintSystem constraintSystem) {
for (TypeParameterDescriptor typeVariable : constraintsSystem.getTypeVariables()) { for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) {
JetType type = getValue(constraintsSystem.getTypeConstraints(typeVariable)); JetType type = getValue(constraintSystem.getTypeConstraints(typeVariable));
JetType upperBound = typeVariable.getUpperBoundsAsType(); JetType upperBound = typeVariable.getUpperBoundsAsType();
JetType substitutedType = constraintsSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT); JetType substitutedType = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
if (type != null) { if (type != null) {
if (substitutedType == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitutedType)) { if (substitutedType == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitutedType)) {
@@ -29,27 +29,27 @@ import java.util.List;
*/ */
public class InferenceErrorData { public class InferenceErrorData {
public final CallableDescriptor descriptor; public final CallableDescriptor descriptor;
public final ConstraintsSystem constraintsSystem; public final ConstraintSystem constraintSystem;
public final JetType receiverArgumentType; public final JetType receiverArgumentType;
public final JetType expectedType; public final JetType expectedType;
public final List<JetType> valueArgumentsTypes; public final List<JetType> valueArgumentsTypes;
private InferenceErrorData(@NotNull CallableDescriptor descriptor, @NotNull ConstraintsSystem constraintsSystem, private InferenceErrorData(@NotNull CallableDescriptor descriptor, @NotNull ConstraintSystem constraintSystem,
@Nullable List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType, @Nullable JetType expectedType) { @Nullable List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType, @Nullable JetType expectedType) {
this.descriptor = descriptor; this.descriptor = descriptor;
this.constraintsSystem = constraintsSystem; this.constraintSystem = constraintSystem;
this.receiverArgumentType = receiverArgumentType; this.receiverArgumentType = receiverArgumentType;
this.valueArgumentsTypes = valueArgumentsTypes; this.valueArgumentsTypes = valueArgumentsTypes;
this.expectedType = expectedType; this.expectedType = expectedType;
} }
public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintsSystem constraintsSystem, public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintSystem constraintSystem,
@NotNull List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType, @Nullable JetType expectedType) { @NotNull List<JetType> valueArgumentsTypes, @Nullable JetType receiverArgumentType, @Nullable JetType expectedType) {
return new InferenceErrorData(descriptor, constraintsSystem, valueArgumentsTypes, receiverArgumentType, return new InferenceErrorData(descriptor, constraintSystem, valueArgumentsTypes, receiverArgumentType,
expectedType != TypeUtils.NO_EXPECTED_TYPE ? expectedType : null); expectedType != TypeUtils.NO_EXPECTED_TYPE ? expectedType : null);
} }
public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintsSystem constraintsSystem) { public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintSystem constraintSystem) {
return new InferenceErrorData(descriptor, constraintsSystem, null, null, null); return new InferenceErrorData(descriptor, constraintSystem, null, null, null);
} }
} }
@@ -232,20 +232,20 @@ public class ExpressionTypingUtils {
@NotNull JetType receiverType, @NotNull JetType receiverType,
@NotNull CallableDescriptor receiverArgument @NotNull CallableDescriptor receiverArgument
) { ) {
ConstraintsSystem constraintsSystem = new ConstraintsSystemImpl(); ConstraintSystem constraintSystem = new ConstraintSystemImpl();
for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) { for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
constraintsSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
} }
ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter(); ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
if (expectedReceiver.exists() && receiverParameter.exists()) { if (expectedReceiver.exists() && receiverParameter.exists()) {
constraintsSystem.addSupertypeConstraint(receiverParameter.getType(), receiverType, ConstraintPosition.RECEIVER_POSITION); constraintSystem.addSupertypeConstraint(receiverParameter.getType(), receiverType, ConstraintPosition.RECEIVER_POSITION);
} }
else if (expectedReceiver.exists() || receiverParameter.exists()) { else if (expectedReceiver.exists() || receiverParameter.exists()) {
// Only one of receivers exist // Only one of receivers exist
return false; return false;
} }
return constraintsSystem.isSuccessful() && ConstraintsUtil.checkBoundsAreSatisfied(constraintsSystem); return constraintSystem.isSuccessful() && ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem);
} }
} }