boolean () { final Collection<InferenceVariable> inferenceVariables = mySession.getInferenceVariables(); for (InferenceVariable inferenceVariable : inferenceVariables) { if (inferenceVariable.getInstantiation() != PsiTypes.nullType()) continue; final Map<InferenceBound, Set<PsiType>> boundsMap = myCurrentBounds.get(inferenceVariable); if (boundsMap == null) continue; final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ); final List<PsiType> upperBounds = inferenceVariable.getBounds(InferenceBound.UPPER); final List<PsiType> lowerBounds = inferenceVariable.getBounds(InferenceBound.LOWER); final Collection<PsiType> changedEqBounds = boundsMap.get(InferenceBound.EQ); final Collection<PsiType> changedUpperBounds = boundsMap.get(InferenceBound.UPPER); final Collection<PsiType> changedLowerBounds = boundsMap.get(InferenceBound.LOWER); //no new eq constraints were added -> no new constraints could be inferred if (changedEqBounds != null) { eqEq(eqBounds, changedEqBounds); } upDown(lowerBounds, changedLowerBounds, upperBounds, changedUpperBounds); upDown(eqBounds, changedEqBounds, upperBounds, changedUpperBounds); upDown(lowerBounds, changedLowerBounds, eqBounds, changedEqBounds); if (changedUpperBounds != null) { upUp(upperBounds); } } for (Pair<InferenceVariable[], PsiClassType> capture : myCaptures) { final PsiClassType right = capture.second; final PsiClass gClass = right.resolve(); LOG.assertTrue(gClass != null); final InferenceVariable[] parameters = capture.first; PsiType[] typeArgs = right.getParameters(); PsiSubstitutor restSubst = PsiSubstitutor.EMPTY; if (Registry.is("javac.fresh.variables.for.captured.wildcards.only")) { List<PsiType> args = new ArrayList<>(); PsiTypeParameter[] typeParameters = gClass.getTypeParameters(); for (int i = 0; i < typeArgs.length; i++) { PsiType arg = typeArgs[i]; if (arg instanceof PsiWildcardType) { args.add(arg); } else { restSubst = restSubst.put(typeParameters[i], arg); } } typeArgs = args.toArray(PsiType.EMPTY_ARRAY); } if (parameters.length != typeArgs.length) continue; for (int i = 0; i < typeArgs.length; i++) { final PsiType aType = typeArgs[i]; final InferenceVariable inferenceVariable = parameters[i]; final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ); final List<PsiType> upperBounds = inferenceVariable.getBounds(InferenceBound.UPPER); final List<PsiType> lowerBounds = inferenceVariable.getBounds(InferenceBound.LOWER); if (aType instanceof PsiWildcardType) { for (PsiType eqBound : eqBounds) { if (!isInferenceVariableOrFreshTypeParameter(inferenceVariable, eqBound)) { return false; } } final PsiClassType[] paramBounds = inferenceVariable.getParameter().getExtendsListTypes(); PsiType glb = null; for (PsiClassType paramBound : paramBounds) { if (glb == null) { glb = paramBound; } else { glb = GenericsUtil.getGreatestLowerBound(glb, paramBound); } } glb = restSubst.substitute(glb); if (!((PsiWildcardType)aType).isBounded()) { for (PsiType upperBound : upperBounds) { if (glb != null && mySession.getInferenceVariable(upperBound) == null) { addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(glb))); } } for (PsiType lowerBound : lowerBounds) { if (isInferenceVariableOrFreshTypeParameter(inferenceVariable, lowerBound)) { return false; } } } else if (((PsiWildcardType)aType).isExtends()) { final PsiType extendsBound = ((PsiWildcardType)aType).getExtendsBound(); for (PsiType upperBound : upperBounds) { if (mySession.getInferenceVariable(upperBound) == null) { if (paramBounds.length == 1 && paramBounds[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || paramBounds.length == 0) { addConstraint(new StrictSubtypingConstraint(upperBound, extendsBound)); } else if (extendsBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) && glb != null) { addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(glb))); } } } for (PsiType lowerBound : lowerBounds) { if (isInferenceVariableOrFreshTypeParameter(inferenceVariable, lowerBound)) { return false; } } } else { LOG.assertTrue(((PsiWildcardType)aType).isSuper()); final PsiType superBound = ((PsiWildcardType)aType).getSuperBound(); for (PsiType upperBound : upperBounds) { if (glb != null && mySession.getInferenceVariable(upperBound) == null) { addConstraint(new StrictSubtypingConstraint(mySession.substituteWithInferenceVariables(glb), upperBound)); } } for (PsiType lowerBound : lowerBounds) { if (mySession.getInferenceVariable(lowerBound) == null) { addConstraint(new StrictSubtypingConstraint(superBound, lowerBound)); } } } } else { inferenceVariable.addBound(aType, InferenceBound.EQ, this); } } } return true; }