code: public static Optional<SoyType> computeLowestCommonTypeArithmetic(SoyType t0, SoyType t1) {
      // If either of the types is an error type, return the error type
      if (t0.getKind() == Kind.ERROR || t1.getKind() == Kind.ERROR) {
        return Optional.of(ErrorType.getInstance());
      }
      // If either of the types isn't numeric or unknown, then this isn't valid for an arithmetic
      // operation.
      if (!isNumericOrUnknown(t0) || !isNumericOrUnknown(t1)) {
        return Optional.absent();
      }
  
      // Note: everything is assignable to unknown and itself.  So the first two conditions take care
      // of all cases but a mix of float and int.
      if (t0.isAssignableFrom(t1)) {
        return Optional.of(t0);
      } else if (t1.isAssignableFrom(t0)) {
        return Optional.of(t1);
      } else {
        // If we get here then we know that we have a mix of float and int.  In this case arithmetic
        // ops always 'upgrade' to float.  So just return that.
        return Optional.of(FloatType.getInstance());
      }
    }
docs: Compute the most specific type that is assignable from both t0 and t1, taking into account
  arithmetic promotions - that is, converting int to float if needed.
  
  @param t0 A type.
  @param t1 Another type.
  @return A type that is assignable from both t0 and t1 or absent if the types are not arithmetic
  meaning a subtype of 'number' or unknown.