int (Supplier<? extends PsiSubstitutor> substitutorSupplier) { if (myArgumentList == null || !myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { return getApplicabilityLevel(); } final PsiMethod method = getElement(); if (isToInferApplicability()) { //ensure applicability check is performed substitutorSupplier.get(); //already performed checks, so if inference failed, error message should be saved if (myApplicabilityError || isPotentiallyCompatible() != ThreeState.YES) { return ApplicabilityLevel.NOT_APPLICABLE; } return isVarargs() ? ApplicabilityLevel.VARARGS : ApplicabilityLevel.FIXED_ARITY; } final PsiSubstitutor substitutor = substitutorSupplier.get(); final Computable<Integer> computable = () -> computeWithKnownTargetType(() -> { //arg types are calculated here without additional constraints: //non-pertinent to applicability arguments of arguments would be skipped //known target types are cached so poly method calls are able to retrieve that target type when type inference is done //see InferenceSession#getTargetTypeFromParent PsiType[] argumentTypes = getArgumentTypes(); if (argumentTypes == null) { return ApplicabilityLevel.NOT_APPLICABLE; } int level1 = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel, true, true, (left, right, allowUncheckedConversion, argId) -> checkFunctionalInterfaceAcceptance(method, left, right, allowUncheckedConversion)); if (!isVarargs() && level1 < ApplicabilityLevel.FIXED_ARITY) { return ApplicabilityLevel.NOT_APPLICABLE; } return level1; }, substitutor); Integer applicabilityLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, computable); if (applicabilityLevel == null) { return ApplicabilityLevel.NOT_APPLICABLE; } @ApplicabilityLevelConstant int level = applicabilityLevel; if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(() -> substitutor)) { level = ApplicabilityLevel.NOT_APPLICABLE; } return level; }