Pre-RFC: Change abs() to return unsigned integers

A small analysis of the usage of abs in the Rust source code:

There are a total of 196 uses of abs. Only 11 are not called on float types. These 11 usages are displayed below.

Doc examples:

//! impl PartialEq for FuzzyNum {
//!     // Our custom eq allows numbers which are near each other to be equal! :D
//!     fn eq(&self, other: &FuzzyNum) -> bool {
//!         (self.num - other.num).abs() < 5
//!     }
//! }
/// let a = [-3, 0, 1, 5, -10];
/// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
/// let a = [-3, 0, 1, 5, -10];
/// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);

In unit tests:

struct SketchyNum {
    num : int
}
impl PartialEq for SketchyNum {
    // Our custom eq allows numbers which are near each other to be equal! :D
    fn eq(&self, other: &SketchyNum) -> bool {
        (self.num - other.num).abs() < 5
    }
}
let xs: &[int] = &[-3, 0, 1, 5, -10];
assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
let xs: &[int] = &[-3, 0, 1, 5, -10];
assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);

In the “literal out of range” lint it is already expected to end up as an u64, which means this as u64 would simply be a widening cast

if (negative && v > (min.abs() as u64)) ||
   (!negative && v > (max.abs() as u64)) {
    cx.span_lint(OVERFLOWING_LITERALS,
                 e.span,
                 &*format!("literal out of range for {:?}", t));
    return;
}

Unit tests for abs would be somewhat more complicated as they currently expect the result to be of the same type.

assert!((1 as $T).abs() == 1 as $T);
assert!((0 as $T).abs() == 0 as $T);
assert!((-1 as $T).abs() == 1 as $T);
2 Likes