What trait can be used for scalar casts?

162 Views Asked by At

What trait can I restrict T to to allow this to compile?

fn one<T>() -> T {
    1.0 as _
}

fn main() {
    println!("{}", one::<i8>());
}

As-is, it gives this error:

rustc 1.14.0 (e8a012324 2016-12-16)
error: non-scalar cast: `f64` as `T`
 --> <anon>:2:5
  |
2 |     1.0 as _
  |     ^^^^^^^^

A good solution would be a trait that restricts T to primitive numeric types (i8, f64, etc.). I found std::num::Primitive but it's experimental apparently and the nightly compiler couldn't find it anyway.

2

There are 2 best solutions below

0
On

There is a crate called num that provides some traits like the one you mention. You can find the documentation here. In your particular case, it seems that you should be able to use the One trait. This trait is, however, very limited because it only provides one function:

pub trait One: Mul<Self, Output=Self> {
    fn one() -> Self;
}

Depending on what you are trying to do, you are probably better off using the Num trait, which is a subtrait of Zero<Output=Self> + One<Output=Self> + Add<Self> + Sub<Self, Output=Self> + Mul<Self> + Div<Self, Output=Self> + Rem<Self, Output=Self> + PartialEq<Self>.

Both traits are implemented for the primitive numerical types (usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64). Note, however, that they are also implemented for some types that are defined in the library (BigInt, BigUint, Ratio, Complex).

1
On

Answering the question you asked:

What trait can be used for scalar casts?

None. Traits only define methods and associated types. Scalar casts are built into the language and are not open for extension.

aochagavia has answered "how do I solve this problem".