boolean (InferenceSession session, List<? super ConstraintFormula> constraints) { if (myT instanceof PsiWildcardType && myS instanceof PsiWildcardType) { final PsiType tBound = ((PsiWildcardType)myT).getBound(); final PsiType sBound = ((PsiWildcardType)myS).getBound(); if (tBound == null && sBound == null) return true; if (sBound == null && ((PsiWildcardType)myT).isExtends()) { //extends bound of "?" (Object) constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myS).getExtendsBound(), tBound)); return true; } if (tBound == null && ((PsiWildcardType)myS).isExtends()) { //extends bound of "?" (Object) constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myT).getExtendsBound(), sBound)); return true; } if (((PsiWildcardType)myT).isExtends() && ((PsiWildcardType)myS).isExtends() || ((PsiWildcardType)myT).isSuper() && ((PsiWildcardType)myS).isSuper()) { LOG.assertTrue(tBound != null); LOG.assertTrue(sBound != null); constraints.add(new TypeEqualityConstraint(tBound, sBound)); return true; } } if (myT instanceof PsiWildcardType || myS instanceof PsiWildcardType) { session.registerIncompatibleErrorMessage( JavaPsiBundle.message("error.incompatible.type.incompatible.equality.constraint", session.getPresentableText(myT), session.getPresentableText(myS))); return false; } if (session.isProperType(myT) && session.isProperType(myS)) { final boolean equal = Comparing.equal(myT, myS); if (!equal) { session.registerIncompatibleErrorMessage( JavaPsiBundle.message("error.incompatible.type.incompatible.equality.constraint", session.getPresentableText(myT), session.getPresentableText(myS))); } return equal; } if (myT == null || myT == PsiTypes.nullType()) return false; if (myS == null || myS == PsiTypes.nullType()) return false; InferenceVariable inferenceVariable = session.getInferenceVariable(myS); if (inferenceVariable != null && !(myT instanceof PsiPrimitiveType)) { InferenceVariable.addBound(myS, myT, InferenceBound.EQ, session); return true; } inferenceVariable = session.getInferenceVariable(myT); if (inferenceVariable != null && !(myS instanceof PsiPrimitiveType)) { InferenceVariable.addBound(myT, myS, InferenceBound.EQ, session); return true; } if (myT instanceof PsiClassType && myS instanceof PsiClassType) { final PsiClassType.ClassResolveResult tResult = ((PsiClassType)myT).resolveGenerics(); final PsiClassType.ClassResolveResult sResult = ((PsiClassType)myS).resolveGenerics(); final PsiClass tClass = tResult.getElement(); //equal erasure if (tClass != null && tClass.getManager().areElementsEquivalent(tClass, sResult.getElement())) { final PsiSubstitutor tSubstitutor = tResult.getSubstitutor(); final PsiSubstitutor sSubstitutor = sResult.getSubstitutor(); for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(tClass)) { final PsiType tSubstituted = tSubstitutor.substitute(typeParameter); final PsiType sSubstituted = sSubstitutor.substitute(typeParameter); if (tSubstituted != null && sSubstituted != null) { constraints.add(new TypeEqualityConstraint(tSubstituted, sSubstituted)); } if (tSubstituted == null ^ sSubstituted == null) { session.registerIncompatibleErrorMessage( JavaPsiBundle.message("error.incompatible.type.incompatible.equality.constraint", session.getPresentableText(myT), session.getPresentableText(myS))); return false; } } return true; } } if (myT instanceof PsiArrayType && myS instanceof PsiArrayType) { constraints.add(new TypeEqualityConstraint(((PsiArrayType)myT).getComponentType(), ((PsiArrayType)myS).getComponentType())); return true; } session.registerIncompatibleErrorMessage(session.getInferenceVariables(), JavaPsiBundle.message("type.conforms.to.constraint", session.getPresentableText(myS), session.getPresentableText(myT))); return false; }