/** * Given a partial solution to our type argument inference, replace any uses of type parameters * that have been solved with their arguments. * * <p>That is: Let S be a partial solution to our inference (i.e. we have inferred type arguments * for some types) Let S be a map {@code (T0 -> A0, T1 -> A1, ..., TN -> AN)} where Ti is a type * parameter and Ai is its solved argument. For all uses of Ti in this constraint, replace them * with Ai. * * <p>For the mapping {@code (T0 -> A0)}, the following constraint: {@code ArrayList<T0> << * List<T1>} * * <p>Becomes: {@code ArrayList<A0> << List<T1>} * * <p>A constraint: {@code T0 << T1} * * <p>Becomes: {@code A0 << T1} * * @param substitutions a mapping of target type parameter to the type argument to * @return a new constraint that contains no use of the keys in substitutions */ public AFConstraint substitute(final Map<TypeVariable, AnnotatedTypeMirror> substitutions) { final AnnotatedTypeMirror newArgument = TypeArgInferenceUtil.substitute(substitutions, argument); final AnnotatedTypeMirror newFormalParameter = TypeArgInferenceUtil.substitute(substitutions, formalParameter); return construct(newArgument, newFormalParameter); }