boolean (@NotNull PsiClassType.ClassResolveResult leftResult, @NotNull PsiClassType.ClassResolveResult rightResult, boolean allowUncheckedConversion, PsiSubstitutor superSubstitutor, boolean capture) { PsiSubstitutor rightSubstitutor = rightResult.getSubstitutor(); PsiClass leftClass = leftResult.getElement(); PsiClass rightClass = rightResult.getElement(); Iterator<PsiTypeParameter> li = PsiUtil.typeParametersIterator(leftClass); if (!li.hasNext()) return true; PsiSubstitutor leftSubstitutor = leftResult.getSubstitutor(); if (!leftClass.getManager().areElementsEquivalent(leftClass, rightClass)) { rightSubstitutor = superSubstitutor; rightClass = leftClass; } else if (!PsiUtil.typeParametersIterator(rightClass).hasNext()) return true; Iterator<PsiTypeParameter> ri = PsiUtil.typeParametersIterator(rightClass); while (li.hasNext()) { if (!ri.hasNext()) return false; PsiTypeParameter lp = li.next(); PsiTypeParameter rp = ri.next(); final PsiType typeLeft = leftSubstitutor.substitute(lp); if (typeLeft == null) continue; final PsiType typeRight = PsiCapturedWildcardType.isCapture() && capture ? rightSubstitutor.substituteWithBoundsPromotion(rp) : rightSubstitutor.substitute(rp); if (typeRight == null) { // compatibility feature: allow to assign raw types to generic ones return allowUncheckedConversion; } if (!typesAgree(typeLeft, typeRight, allowUncheckedConversion)) { return false; } } return true; }