Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for whether index is out of bound during compilation failed unexpectedly #124889

Open
htw-yay opened this issue May 8, 2024 · 3 comments
Open
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug. L-unconditional_panic Lint: unconditional_panic S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@htw-yay
Copy link

htw-yay commented May 8, 2024

I tried these two codes:

#[derive(Debug)]
struct Arr<T, const N: usize>([T; N]);

impl<T: Default + Copy, const N: usize> Arr<T, N> {
    fn from_slice(slice: &[T]) -> Option<Self> {
        if slice.len() == N {
            let mut arr = Self([T::default(); N]);
            arr.0.copy_from_slice(&slice);
            Some(arr)
        } else {
            None
        }
    }
}

fn main() {
    let slice: &[u8] = b"Hello, world";
    let arr = Arr::<u8, 12>::from_slice(slice).unwrap();
    println!("{:?}", arr.0[20]);
// let inner = arr.0;
// println!("{:?}", inner[20]);
}
...
// println!("{:?}", arr.0[20]);
    let inner = arr.0;
    println!("{:?}", inner[20]);
...

I expected to see this happen:
When running cargo build,
"index out of bounds: the length is 12 but the index is 20" should be indicated for both codes

Instead, this happened:
Only Code 2 had it

Meta

rustc --version --verbose:

rustc 1.78.0 (9b00956e5 2024-04-29)
binary: rustc
commit-hash: 9b00956e56009bab2aa15d7bff10916599e3d6d6
commit-date: 2024-04-29
host: x86_64-pc-windows-msvc
release: 1.78.0
LLVM version: 18.1.2
rustc 1.79.0-beta.3 (f5d04caa7 2024-05-03)
binary: rustc
commit-hash: f5d04caa74a1dfa5ffc4082c2c8f621f25336bbc
commit-date: 2024-05-03
host: x86_64-pc-windows-msvc
release: 1.79.0-beta.3
LLVM version: 18.1.4
rustc 1.80.0-nightly (faefc618c 2024-05-07)
binary: rustc
commit-hash: faefc618cf48bd794cbc808448df1bf3f59f36af
commit-date: 2024-05-07
host: x86_64-pc-windows-msvc
release: 1.80.0-nightly
LLVM version: 18.1.4
Backtrace

Building:

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
error: this operation will panic at runtime
  --> t1\src\main.rs:22:22
   |
22 |     println!("{:?}", inner[20])
   |                      ^^^^^^^^^ index out of bounds: the length is 12 but the index is 20
   |
   = note: `#[deny(unconditional_panic)]` on by default

error: could not compile `t1` (bin "t1") due to 1 previous error

Running(Code 1):

thread 'main' panicked at t1\src\main.rs:19:22:
index out of bounds: the len is 12 but the index is 20
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\panicking.rs:645
   1: core::panicking::panic_fmt
             at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\core\src\panicking.rs:72
   2: core::panicking::panic_bounds_check
             at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\core\src\panicking.rs:209
   3: t1::main
             at .\t1\src\main.rs:19
   4: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6\library\core\src\ops\function.rs:250
   5: core::hint::black_box
             at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6\library\core\src\hint.rs:337
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\t1.exe` (exit code: 101)
thread 'main' panicked at t1\src\main.rs:19:22:
index out of bounds: the len is 12 but the index is 20
stack backtrace:
   0:     0x7ff650fa73fa - std::backtrace_rs::backtrace::dbghelp64::trace
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:99
   1:     0x7ff650fa73fa - std::backtrace_rs::backtrace::trace_unsynchronized
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
   2:     0x7ff650fa73fa - std::sys_common::backtrace::_print_fmt
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\sys_common\backtrace.rs:68
   3:     0x7ff650fa73fa - std::sys_common::backtrace::_print::impl$0::fmt
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\sys_common\backtrace.rs:44
   4:     0x7ff650fb519b - core::fmt::rt::Argument::fmt
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\core\src\fmt\rt.rs:142
   5:     0x7ff650fb519b - core::fmt::write
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\core\src\fmt\mod.rs:1153
   6:     0x7ff650fa5791 - std::io::Write::write_fmt<std::sys::pal::windows::stdio::Stderr>
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\io\mod.rs:1843
   7:     0x7ff650fa71e6 - std::sys_common::backtrace::print
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\sys_common\backtrace.rs:34
   8:     0x7ff650fa8ccf - std::panicking::default_hook::closure$1
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\panicking.rs:272
   9:     0x7ff650fa8967 - std::panicking::default_hook
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\panicking.rs:292
  10:     0x7ff650fa920d - std::panicking::rust_panic_with_hook
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\panicking.rs:779
  11:     0x7ff650fa90c9 - std::panicking::begin_panic_handler::closure$0
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\panicking.rs:657
  12:     0x7ff650fa7a89 - std::sys_common::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::closure_env$0,never$>
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\sys_common\backtrace.rs:171
  13:     0x7ff650fa8d86 - std::panicking::begin_panic_handler
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\panicking.rs:645
  14:     0x7ff650fba387 - core::panicking::panic_fmt
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\core\src\panicking.rs:72
  15:     0x7ff650fba534 - core::panicking::panic_bounds_check
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\core\src\panicking.rs:209
  16:     0x7ff650fa1768 - t1::main
                               at C:\Users\htwyay\Documents\LearnRust\t1\src\main.rs:19
  17:     0x7ff650fa11cb - core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6\library\core\src\ops\function.rs:250
  18:     0x7ff650fa113e - core::hint::black_box
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6\library\core\src\hint.rs:337
  19:     0x7ff650fa113e - std::sys_common::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<> >
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6\library\std\src\sys_common\backtrace.rs:155
  20:     0x7ff650fa1061 - std::rt::lang_start::closure$0<tuple$<> >
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6\library\std\src\rt.rs:166
  21:     0x7ff650fa3672 - std::rt::lang_start_internal
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library\std\src\rt.rs:148
  22:     0x7ff650fa103a - std::rt::lang_start<tuple$<> >
                               at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6\library\std\src\rt.rs:165
  23:     0x7ff650fa1789 - main
  24:     0x7ff650fb8950 - invoke_main
                               at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
  25:     0x7ff650fb8950 - __scrt_common_main_seh
                               at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
  26:     0x7ff95a3e1fd7 - BaseThreadInitThunk
  27:     0x7ff95c49d7d0 - RtlUserThreadStart
error: process didn't exit successfully: `target\debug\t1.exe` (exit code: 101)

@htw-yay htw-yay added the C-bug Category: This is a bug. label May 8, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 8, 2024
@mkehrt
Copy link

mkehrt commented May 10, 2024

This repros without the copying method.

This panics at runtime:

#[derive(Debug)]
struct Arr<T, const N: usize>([T; N]);

fn main() {
    let arr = Arr(*b"Hello, world");
    println!("{:?}", arr.0[20]);
    // let inner = arr.0;
    // println!("{:?}", inner[20]);
}

While this gives a compiler error:

#[derive(Debug)]
struct Arr<T, const N: usize>([T; N]);

fn main() {
    let arr = Arr(*b"Hello, world");
    // println!("{:?}", arr.0[20]);
    let inner = arr.0;
    println!("{:?}", inner[20]);
}

@mkehrt
Copy link

mkehrt commented May 12, 2024

Interestingly this panics:

struct Arr([u8; 12]);

fn main() {
    let arr = Arr(*b"Hello, world");
    
    // Panics
    println!("{:?}", arr.0[20]);

But this (without the println) is a compiler error:

struct Arr([u8; 12]);

fn main() {
    let arr = Arr(*b"Hello, world");
    
    // Compiler errror
    arr.0[20];
}

Expanding the macros for the former println call (into HIR) gives:

 ::std::io::_print(format_arguments::new_v1(&["", "\n"],
                        &[format_argument::new_debug(&arr.0[20])]));
            };

I guessed that the reference before arr.0[20] was the issue. And, in fact, this panics:

struct Arr([u8; 12]);

fn main() {
    let arr = Arr(*b"Hello, world");
    
    // Panics
    (&arr.0)[20];
}

In fact, this happens even if you remove the enclosing struct:

fn main() {
    let arr: [u8; 12] = *b"Hello, world";

    // Panic
    (&arr)[20];
fn main() {
    let arr: [u8; 12] = *b"Hello, world";

    // Compile error
    arr[20];
}

So it appears that the issue is that the lint to check whether a constant index into a constant array or slice will be out of bounds occurs with arrays but not with slices. I don't know if this is a bug or not.

@mkehrt
Copy link

mkehrt commented May 12, 2024

@rustbot label +A-lint

@rustbot rustbot added the A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. label May 12, 2024
@jieyouxu jieyouxu added S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue L-unconditional_panic Lint: unconditional_panic T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug. L-unconditional_panic Lint: unconditional_panic S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants