0

What I do: I try change .collect::<Vec<(i32, i32)>>(); to .collect::<Vec<(usize, usize)>>();

    let result = (0..4)
        .flat_map(|x| {
            (0..=x - 1).map(move |y| {
                println!("{:?},{:?}", y, x);
                (y, x)
            })
        })
        .collect::<Vec<(usize, usize)>>();
    assert_eq!(usize::BITS, 64);

Expected: The program should print this output

0,1
0,2
1,2
0,3
1,3
2,3

Reality: Causing this error

thread 'main' panicked at 'attempt to subtract with overflow', sandbox.rs:4:18
stack backtrace:
   0:        0x104e5b714 - std::backtrace_rs::backtrace::libunwind::trace::h3cae2b905fd8ac13
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:        0x104e5b714 - std::backtrace_rs::backtrace::trace_unsynchronized::he35fb4c47e25f88c
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x104e5b714 - std::sys_common::backtrace::_print_fmt::hdb42afc2298dc41a
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:66:5
   3:        0x104e5b714 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hc80096156cd24709
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:45:22
   4:        0x104e6f36b - core::fmt::write::hb6b947db0e571766
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/fmt/mod.rs:1194:17
   5:        0x104e59998 - std::io::Write::write_fmt::h59c4febf5f8fcb1e
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/io/mod.rs:1655:15
   6:        0x104e5ceed - std::sys_common::backtrace::_print::h72a3180302df7468
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:48:5
   7:        0x104e5ceed - std::sys_common::backtrace::print::ha0747cec3f48ad89
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:35:9
   8:        0x104e5ceed - std::panicking::default_hook::{{closure}}::h0e76f92bbb367061
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:295:22
   9:        0x104e5cbd1 - std::panicking::default_hook::hbbbb8c05ad6cce9a
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:314:9
  10:        0x104e5d46e - std::panicking::rust_panic_with_hook::ha581a2c99399f83b
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:698:17
  11:        0x104e5d32a - std::panicking::begin_panic_handler::{{closure}}::h97df6e4273b6a879
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:586:13
  12:        0x104e5bb97 - std::sys_common::backtrace::__rust_end_short_backtrace::ha4a3b48ae6bfb343
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/sys_common/backtrace.rs:138:18
  13:        0x104e5d03a - rust_begin_unwind
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:584:5
  14:        0x104e75ad3 - core::panicking::panic_fmt::h4a5343602e6cbb54
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/panicking.rs:143:14
  15:        0x104e759b7 - core::panicking::panic::h6b179fc6a750c6a7
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/panicking.rs:48:5
  16:        0x104e3b9be - sandbox::main::{{closure}}::hf08783165a52a79c
  17:        0x104e3b80c - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once::hf882f89c41f0bc1a
  18:        0x104e3db0a - core::option::Option<T>::map::h8da6a8ee39a64700
  19:        0x104e3b76d - <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::next::hff3dfbd45c29371a
  20:        0x104e3bead - <core::iter::adapters::fuse::Fuse<I> as core::iter::adapters::fuse::FuseImpl<I>>::next::hc0f3bee62dae5fb7
  21:        0x104e3bdf4 - <core::iter::adapters::fuse::Fuse<I> as core::iter::traits::iterator::Iterator>::next::h5e78846a93a83854
  22:        0x104e3a9b1 - <core::iter::adapters::flatten::FlattenCompat<I,U> as core::iter::traits::iterator::Iterator>::next::h4e729994babe33d0
  23:        0x104e3a914 - <core::iter::adapters::flatten::FlatMap<I,U,F> as core::iter::traits::iterator::Iterator>::next::hc25c9d268b91673b
  24:        0x104e3cff8 - <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::hc317abd23254384d
  25:        0x104e3d5bb - <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter::h83bc07655110a239
  26:        0x104e3d54a - <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter::h97531d9802a79ec6
  27:        0x104e3b24b - core::iter::traits::iterator::Iterator::collect::h7d66f1c588b4ccd5
  28:        0x104e3b93c - sandbox::main::h665c6f01c25b7779
  29:        0x104e3b5ca - core::ops::function::FnOnce::call_once::h66b82387820b635c
  30:        0x104e3b39d - std::sys_common::backtrace::__rust_begin_short_backtrace::h69deb9d52437a77b
  31:        0x104e3e1d0 - std::rt::lang_start::{{closure}}::h7e1e8999ed160d7b
  32:        0x104e568ba - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h45b43bdd91db95dd
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/core/src/ops/function.rs:259:13
  33:        0x104e568ba - std::panicking::try::do_call::h249f439f16aa313c
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:492:40
  34:        0x104e568ba - std::panicking::try::ha8537a1873fa2ff9
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:456:19
  35:        0x104e568ba - std::panic::catch_unwind::hffa61ccaeb4f89c5
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panic.rs:137:14
  36:        0x104e568ba - std::rt::lang_start_internal::{{closure}}::h32bbf4c39987b002
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/rt.rs:128:48
  37:        0x104e568ba - std::panicking::try::do_call::h558936e01b59417c
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:492:40
  38:        0x104e568ba - std::panicking::try::h12a630e8ced1b46a
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panicking.rs:456:19
  39:        0x104e568ba - std::panic::catch_unwind::h539ca15d1ec773ea
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/panic.rs:137:14
  40:        0x104e568ba - std::rt::lang_start_internal::hdb19fe6764e59ca8
                               at /rustc/fe5b13d681f25ee6474be29d748c65adcd91f69e/library/std/src/rt.rs:128:20
  41:        0x104e3e1b2 - std::rt::lang_start::h779bf72e0eff05a1
  42:        0x104e3bab6 - _main

My environment Darwin xxx.local 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:22 PDT 2022; root:xnu-8020.121.3~4/RELEASE_X86_64 x86_64

Question: usize in my machine is 64 so I expect changing from i32 to usize should be valid

  1. Is this an issue with overflow or the error are just generic?
  2. If the issue is not related to overflow then why I can't use usize

Context: The reason I use .collect::<Vec<(usize, usize)>>(); is because this error in another code here https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=be45ed1d9d5cd836a37040da20243b26

Code: snippet code that causes the error https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6929e4620c980749397de4c1b5f03a03

Similar issue: There seems to be a similar error on StackOverflow here thread 'main' panicked at 'attempt to subtract with overflow' Thread 'main' panicked at 'attempt to multiply with overflow' Panicked at 'attempt to subtract with overflow' when cycling backwards though a list https://discord.com/channels/442252698964721669/448238009733742612/975126106090921994 But all of them are arithmetic operations related which I don't think is the case with my code.

Kyrielight
  • 119
  • 5
  • I like your post but this is a very simple misunderstanding. If `x` is a `usize` (since it is being collected as such) and your iterations start with 0, then trying to do `x - 1` will overflow. – kmdreko Jun 11 '22 at 18:00
  • The actual misunderstanding here I think is that `a..b` includes `a` but does **not** include `b`. To include `b`, you would have to write `a..=b`. – Finomnis Jun 11 '22 at 18:07

1 Answers1

4

The minimum value of usize is 0 and you're computing 0 - 1 in the first iteration in the expression (0..=x - 1) which causes an underflow.

You probably want to use (0..x) which creates a range upto x - 1 but does not cause an underflow if x == 0 (it simply creates an empty range):

let result = (0..4)
    .flat_map(|x| {
        (0..x).map(move |y| {
            println!("{:?},{:?}", y, x);
            (y, x)
        })
    })
    .collect::<Vec<(usize, usize)>>();

Playground

Dogbert
  • 212,659
  • 41
  • 396
  • 397