Keats/validator

bug: the literal (...) does not fit into the type `i32`

Opened this issue · 3 comments

I just commited to finally migrating away from v0.16 and deal with all the errors.
I was able to fix most of them (so far) but now found another bug.

I want to validate an input for an Option<i64> with min and max, and get the error, that the max it out of bounds for an i32, even though the variable is an i64.

A stripped down version of my struct:

#[derive(Debug, Serialize, Deserialize, Validate)]
pub struct MyRequest {
    #[validate(range(min = 1672527600, max = 4070905200))]
    pub value: Option<i64>,
}

The compiler yells at me that 4070905200 is out of range for an i32, but there is no i32:

   |
30 |     #[validate(range(min = 1672527600, max = 4070905200))]
   |                                              ^^^^^^^^^^
   |
   = note: the literal `4070905200` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
   = help: consider using the type `u32` instead
   = note: `#[deny(overflowing_literals)]` on by default

So the error happens when we are generating the code for error insertion. It sees:

                err.add_param(::std::borrow::Cow::from("min"), &1672527600);
                err.add_param(::std::borrow::Cow::from("max"), &4070905200);

and somehow Rust thinks they are i32?!

Yes it seems like that. As soon as I removed the max there, the compiler was happy.

Looks like it's defaulting to i32 after not being able to infer a type for T: Serialize. The easiest fix is to use the i64 suffix:

#[derive(Debug, Serialize, Deserialize, Validate)]
pub struct MyRequest {
    #[validate(range(min = 1672527600i64, max = 4070905200i64))]
    pub value: Option<i64>,
}

I don't think there's a way to correctly handle i64 and f64 at the same time without providing the type explicitly.