Safer casting with a little macro


#1

In the past months I’ve had some bugs in my Rust code caused by usage of hard casts. Now I have started to use this simple to!() macro that should avoid similar troubles, it acts like regular integral operations, becoming a fast “as” cast in debug builds:

#![cfg_attr(debug_assertions, feature(try_from))]

#[allow(unused_imports)] use std::convert::TryFrom;

#[cfg(not(debug_assertions))]
macro_rules! to { ($e:expr, $t:ident) => (($e) as $t)  }

#[cfg(debug_assertions)]
macro_rules! to { ($e:expr, $t:ident) => ($t::try_from($e).unwrap())  }

fn main() { // Example usage:
    let x: u32 = 1000;
    let y = to!(x, u8);
    println!("{}", y);
}

(The name “to!” comes from a different but related template from the D standard library).

I think to!() should go in the Rust std lib, and Clippy should warn when you don’t use it (Clippy should also warn when you use an “as” where an T::from() suffices).

An unsolved problem: I think I can’t use it in a const contex:

const N: u32 = 10;
let arr = [0u32; to!(N, usize)];

But I guess eventually Rust will be able to run try_from() at compile-time?

(By the way, my Rust code still has hundreds of “as usize” to acces arrays, vectors and slices, sooner or later this problem will need to be solved. In the last few months I haven’t seen much progress toward solving this problem).