boolean (PsiTypeCastExpression cast) { PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(cast.getType()); if (psiClass == null) return false; Set<PsiTypeParameter> parameters = Set.of(psiClass.getTypeParameters()); if (parameters.isEmpty()) return false; PsiElement parent = PsiUtil.skipParenthesizedExprUp(cast.getParent()); if (parent instanceof PsiReferenceExpression ref) { PsiElement target = ref.resolve(); if (!(target instanceof PsiMember)) return false; PsiClass containingClass = ((PsiMember)target).getContainingClass(); if (containingClass == null) return false; PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, psiClass, PsiSubstitutor.EMPTY); if (target instanceof PsiField) { PsiType type = substitutor.substitute(((PsiField)target).getType()); PsiClass varType = PsiUtil.resolveClassInClassTypeOnly(type); return (varType instanceof PsiTypeParameter && parameters.contains(varType) && !PsiUtil.isAccessedForWriting(ref)) || !PsiTypesUtil.mentionsTypeParameters(type, parameters); } if (target instanceof PsiMethod) { PsiMethodCallExpression call = ObjectUtils.tryCast(ref.getParent(), PsiMethodCallExpression.class); if (call == null) return false; if (!ExpressionUtils.isVoidContext(call)) { PsiType type = substitutor.substitute(((PsiMethod)target).getReturnType()); PsiClass varType = PsiUtil.resolveClassInClassTypeOnly(type); if (!(varType instanceof PsiTypeParameter && parameters.contains(varType)) && PsiTypesUtil.mentionsTypeParameters(type, parameters)) { return false; } } PsiParameterList parameterList = ((PsiMethod)target).getParameterList(); for (PsiParameter parameter : parameterList.getParameters()) { if (parameter.isVarArgs() && call.getArgumentList().getExpressionCount() == parameterList.getParametersCount() - 1) { // No vararg parameters specified continue; } PsiType parameterType = parameter.getType(); if (PsiTypesUtil.mentionsTypeParameters(parameterType, Predicates.alwaysTrue())) return false; } return true; } } return false; }