@Override
  public boolean reduce(InferenceSession session, List<? super ConstraintFormula> constraints) {
    if (session.isProperType(myT) && session.isProperType(myS)) {
      final boolean assignable = TypeConversionUtil.isAssignable(myT, myS);
      if (!assignable) {
        session.registerIncompatibleErrorMessage(
          JavaPsiBundle.message("error.incompatible.type.not.convertible", session.getPresentableText(myS), session.getPresentableText(myT)));
      }
      return assignable;
    }
    if (myS instanceof PsiPrimitiveType && !PsiTypes.voidType().equals(myS)) {
      final PsiClassType boxedType = ((PsiPrimitiveType)myS).getBoxedType(session.getManager(), session.getScope());
      if (boxedType != null) {
        constraints.add(new TypeCompatibilityConstraint(myT, boxedType));
        return true;
      }
    }
    if (myT instanceof PsiPrimitiveType && !PsiTypes.voidType().equals(myT)) {
      final PsiClassType boxedType = ((PsiPrimitiveType)myT).getBoxedType(session.getManager(), session.getScope());
      if (boxedType != null) {
        constraints.add(new TypeEqualityConstraint(boxedType, myS));
        return true;
      }
    }

    if (isUncheckedConversion(myT, myS, session)) {
      session.setErased();
      return true;
    }

    constraints.add(new StrictSubtypingConstraint(myT, myS));
    return true;
  }
@Override
  public boolean reduce(InferenceSession session, List<? super ConstraintFormula> constraints)