MethodCandidateInfo (@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor, boolean staticProblem, boolean accessible, boolean varargs) { PsiExpressionList argumentList = getArgumentList(); PsiType[] typeParameters = reference.getTypeParameters(); return new MethodCandidateInfo(method, substitutor, !accessible, staticProblem, argumentList, myCurrentFileContext, argumentList != null ? argumentList.getExpressionTypes() : null, method.hasTypeParameters() && typeParameters.length > 0 ? typeParameters : null, getLanguageLevel()) { @Override public boolean isVarargs() { return varargs; } @NotNull @Override public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) { if (includeReturnConstraint) { return inferTypeArguments(true); } PsiSubstitutor psiSubstitutor = MethodCandidateInfo.ourOverloadGuard .doPreventingRecursion(reference, false, () -> inferTypeArguments(false)); if (psiSubstitutor == null) { LOG.error("Recursive call for: " + ObjectUtils.notNull(LambdaUtil.treeWalkUp(reference), reference).getText()); return substitutor; } return psiSubstitutor; } @NotNull private PsiSubstitutor inferTypeArguments(boolean includeReturnConstraint) { if (interfaceMethod == null) return substitutor; InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, reference.getManager(), reference); session.initThrowsConstraints(method); PsiSubstitutor psiSubstitutor = session.collectApplicabilityConstraints(reference, this, functionalInterfaceType); if (psiSubstitutor != null) { return psiSubstitutor; } if (!session.repeatInferencePhases()) { List<String> errorMessages = session.getIncompatibleErrorMessages(); if (errorMessages != null) { setApplicabilityError(StringUtil.join(errorMessages, "\n")); } return substitutor; } if (includeReturnConstraint && !PsiTypes.voidType().equals(interfaceMethodReturnType) && interfaceMethodReturnType != null) { PsiType returnType = method.isConstructor() ? composeReturnType(containingClass, substitutor) : PsiMethodReferenceCompatibilityConstraint .getSubstitutor(signature, qualifierResolveResult, method, containingClass, reference) .substitute(method.getReturnType()); if (returnType != null) { session.registerReturnTypeConstraints(returnType, interfaceMethodReturnType, reference); } } return session.infer(method.getParameterList().getParameters(), null, null, null); } @Override public boolean isApplicable() { if (signature == null) return false; if (getInferenceErrorMessageAssumeAlreadyComputed() != null) return false; PsiType[] argTypes = signature.getParameterTypes(); boolean hasReceiver = PsiMethodReferenceUtil.isSecondSearchPossible(argTypes, qualifierResolveResult, reference); return MethodReferenceConflictResolver.isApplicableByFirstSearch(this, argTypes, hasReceiver, reference, interfaceMethod.isVarArgs(), interfaceMethod) != null; } }; }