How to declare the item is i128 but not i32

Hi, I try the below example from std lib for into_iterator. I get the following error. How and where do I need to declare the item here is i128 but not i32

#![allow(unused)]
fn main() {
fn collect_as_strings<T>(collection: T) -> Vec<String>
where
    T: IntoIterator,
    T::Item: std::fmt::Debug,
{
    collection
        .into_iter()
        .map(|item| format!("{item:?}"))
        .collect()
}

dbg!(collect_as_strings([12345434553435533553345,12345434553435533553345]));

}

Errors:

 Compiling playground v0.0.1 (/playground)
error: literal out of range for `i32`
  --> src/main.rs:14:26
   |
14 | dbg!(collect_as_strings([12345434553435533553345,12345434553435533553345]));
   |                          ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: the literal `12345434553435533553345` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
   = help: consider using the type `i128` instead
   = note: `#[deny(overflowing_literals)]` on by default

error: literal out of range for `i32`
  --> src/main.rs:14:50
   |
14 | dbg!(collect_as_strings([12345434553435533553345,12345434553435533553345]));
   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: the literal `12345434553435533553345` does not fit into the type `i32` whose range is `-2147483648..=2147483647`
   = help: consider using the type `i128` instead

error: could not compile `playground` due to 2 previous errors

Proceed the integer literal with the type you wish it to be if the default or inferred type is wrong:

let x = 2135u128; // default is i32.

Similarly for floats:

let z = 3.5f32; // default is f64.
1 Like

You can put a suffix on the literal like 123i128 or 123_456_i128, or you can add the explicit type on the function call with "turbo-fish", collect_as_strings::<i128>(...).

1 Like

It's the other way -- the float default is f64.

1 Like

Oh whoops, fixed :sweat_smile:

Ahh thank you, Assuming rust infers the type automatically but it looks like rust wants them to be explicitly declared for this case.

Well the type is indeed inferred automatically, it just happens to be that an integer overflow isn't enough to push the compiler to choose a different integer type.

1 Like

It does, when there's an information to infer from. Integer value isn't treated as such information, since it would be too easy to end up with unexpected breakage otherwise.

3 Likes

An integer literal could be any of the primitive types. How would you expect the compiler to guess which one you meant? There's no information about that in the code.

Can do the same way as C: if it doesn't fit into i32 then it's long.

This is often source of bugs and rarely a good idea thus I think I like Rust's approach better.

Just specify the size explicitly when it's needed.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.