public static TabledDescriptorRenderer renderUpperBoundViolatedInferenceError( InferenceErrorData inferenceErrorData, TabledDescriptorRenderer result) { TypeParameterDescriptor typeParameterDescriptor = null; for (TypeParameterDescriptor typeParameter : inferenceErrorData.descriptor.getTypeParameters()) { if (!ConstraintsUtil.checkUpperBoundIsSatisfied( inferenceErrorData.constraintSystem, typeParameter, true)) { typeParameterDescriptor = typeParameter; break; } } assert typeParameterDescriptor != null; result .text( newText() .normal("Type parameter bound for ") .strong(typeParameterDescriptor.getName()) .normal(" in ")) .table(newTable().descriptor(inferenceErrorData.descriptor)); JetType inferredValueForTypeParameter = ConstraintsUtil.getValue( inferenceErrorData.constraintSystem.getTypeConstraints(typeParameterDescriptor)); assert inferredValueForTypeParameter != null; JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType(); JetType upperBoundWithSubstitutedInferredTypes = inferenceErrorData .constraintSystem .getResultingSubstitutor() .substitute(upperBound, Variance.INVARIANT); assert upperBoundWithSubstitutedInferredTypes != null; Renderer<JetType> typeRenderer = result.getTypeRenderer(); result.text( newText() .normal(" is not satisfied: inferred type ") .error(typeRenderer.render(inferredValueForTypeParameter)) .normal(" is not a subtype of ") .strong(typeRenderer.render(upperBoundWithSubstitutedInferredTypes))); return result; }
public static TabledDescriptorRenderer renderConflictingSubstitutionsInferenceError( ExtendedInferenceErrorData inferenceErrorData, TabledDescriptorRenderer result) { assert inferenceErrorData.constraintSystem.hasConflictingConstraints(); Collection<CallableDescriptor> substitutedDescriptors = Lists.newArrayList(); Collection<TypeSubstitutor> substitutors = ConstraintsUtil.getSubstitutorsForConflictingParameters( inferenceErrorData.constraintSystem); for (TypeSubstitutor substitutor : substitutors) { CallableDescriptor substitutedDescriptor = inferenceErrorData.descriptor.substitute(substitutor); substitutedDescriptors.add(substitutedDescriptor); } TypeParameterDescriptor firstConflictingParameter = ConstraintsUtil.getFirstConflictingParameter(inferenceErrorData.constraintSystem); assert firstConflictingParameter != null; result.text( newText() .normal("Cannot infer type parameter ") .strong(firstConflictingParameter.getName()) .normal(" in")); // String type = strong(firstConflictingParameter.getName()); TableRenderer table = newTable(); result.table(table); table.descriptor(inferenceErrorData.descriptor).text("None of the following substitutions"); for (CallableDescriptor substitutedDescriptor : substitutedDescriptors) { JetType receiverType = DescriptorUtils.getReceiverParameterType(substitutedDescriptor.getReceiverParameter()); final Collection<ConstraintPosition> errorPositions = Sets.newHashSet(); List<JetType> parameterTypes = Lists.newArrayList(); for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) { parameterTypes.add(valueParameterDescriptor.getType()); if (valueParameterDescriptor.getIndex() >= inferenceErrorData.valueArgumentsTypes.size()) continue; JetType actualType = inferenceErrorData.valueArgumentsTypes.get(valueParameterDescriptor.getIndex()); if (!JetTypeChecker.INSTANCE.isSubtypeOf(actualType, valueParameterDescriptor.getType())) { errorPositions.add( ConstraintPosition.getValueParameterPosition(valueParameterDescriptor.getIndex())); } } if (receiverType != null && inferenceErrorData.receiverArgumentType != null && !JetTypeChecker.INSTANCE.isSubtypeOf( inferenceErrorData.receiverArgumentType, receiverType)) { errorPositions.add(ConstraintPosition.RECEIVER_POSITION); } Predicate<ConstraintPosition> isErrorPosition = new Predicate<ConstraintPosition>() { @Override public boolean apply(@Nullable ConstraintPosition constraintPosition) { return errorPositions.contains(constraintPosition); } }; table.functionArgumentTypeList(receiverType, parameterTypes, isErrorPosition); } table .text("can be applied to") .functionArgumentTypeList( inferenceErrorData.receiverArgumentType, inferenceErrorData.valueArgumentsTypes); return result; }