Repository: rust
Issue: Space for large, constant arrays is allocated on the stack
Labels: A-lints,T-compiler,C-bug,C-optimization

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

When a large, constant array like
```rust
const ARRAY: [u32; LARGE_CONSTANT] = [ /* ... */ ];
```
is accessed directly (rather than through a reference) in a function like this
```rust
pub fn get(idx: usize) -> u32 {
    match idx {
        0..=8455 => ARRAY[idx],
        8550..=8645 => ARRAY[idx - 94],
        8740..=8835 => ARRAY[idx - 188],
        8930..=13127 => ARRAY[idx - 282],
        13206..=13299 => ARRAY[idx - 360],
        13396..=13489 => ARRAY[idx - 456],
        13586..=13679 => ARRAY[idx - 552],
        13966..=14059 => ARRAY[idx - 838],
        _ => 0,
    }
}
```
rustc appears to be allocating enough space to hold the whole array on the stack for each reference. With a large enough array times number of uses, this can cause the stack probe to fail. (I didn't check if the whole array is actually materialized on the stack each time or if only space for it is allocated.)

I expected rustc to not allocate space for the constant array and instead access it directly from the read-only memory segment of the executable.

Instead, when I run the code, I get
```
    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running target/debug/deps/array_bug-d57a78204f1529fa

running 1 test

thread 'test::test' has overflowed its stack
fatal runtime error: stack overflow
error: test failed, to rerun pass '--lib'

Caused by:
  process didn't exit successfully: `/Users/steve/programming/array-bug/target/debug/deps/array_bug-d57a78204f1529fa` (signal: 6, SIGABRT: process abort signal)
```

Disassembling the binary is sufficient to see the issue.
```
array_bug-d57a78204f1529fa`array_bug::get::h8e3dc22d47c73cc1:
    0x1000014f0 <+0>:    pushq  %rbp
    0x1000014f1 <+1>:    movq   %rsp, %rbp
    0x1000014f4 <+4>:    movl   $0x2f9cd0, %eax           ; imm = 0x2F9CD0
    0x1000014f9 <+9>:    callq  0x10007fd40               ; __rust_probestack
    0x1000014fe <+14>:   subq   %rax, %rsp
```

As you can see, this function is trying to allocate 3120336 bytes on the stack.

A complete example from which the above output was derived is available [here](https://github.com/stevecheckoway/array-bug). The numbers in the array are meaningless. They came from `/dev/urandom`. The numbers in the match are likewise immaterial.

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.49.0 (e1884a8e3 2020-12-29)
binary: rustc
commit-hash: e1884a8e3c3e813aada8254edfa120e85bf5ffca
commit-date: 2020-12-29
host: x86_64-apple-darwin
release: 1.49.0
```

The same occurs with nightly.
```
cargo 1.50.0-nightly (75d5d8cff 2020-12-22)
release: 1.50.0
commit-hash: 75d5d8cffe3464631f82dcd3c470b78dc1dda8bb
commit-date: 2020-12-22
```

<!--
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in your
environment. E.g. `RUST_BACKTRACE=1 cargo build`.
-->

`RUST_BACKTRACE=1` does not work; however, here's a backtrace from `rust-lldb`.

<details><summary>Backtrace</summary>
<p>

```
* thread #2, name = 'test::test', stop reason = EXC_BAD_ACCESS (code=2, address=0x7000053986d8)
  * frame #0: 0x000000010007fd57 array_bug-d57a78204f1529fa`__rust_probestack + 23
    frame #1: 0x00000001000014fe array_bug-d57a78204f1529fa`array_bug::get::h8e3dc22d47c73cc1(idx=4294972670) at lib.rs:1
    frame #2: 0x00000001000032d2 array_bug-d57a78204f1529fa`array_bug::test::test::hc711f7a43c02bc30 at lib.rs:52:17
    frame #3: 0x0000000100004111 array_bug-d57a78204f1529fa`array_bug::test::test::_$u7b$$u7b$closure$u7d$$u7d$::had6d89fadeb77842((null)=0x0000700005598730) at lib.rs:51:5
    frame #4: 0x00000001000039f1 array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once::hc97ff02d53ad383b((null)=closure-0 @ 0x0000700005598730, (null)=<unavailable>) at function.rs:227:5
    frame #5: 0x000000010002c12a array_bug-d57a78204f1529fa`test::__rust_begin_short_backtrace::h1d6019f47cc55f08 [inlined] core::ops::function::FnOnce::call_once::h23ab09971f90347f at function.rs:227:5 [opt]
    frame #6: 0x000000010002c128 array_bug-d57a78204f1529fa`test::__rust_begin_short_backtrace::h1d6019f47cc55f08 at lib.rs:517 [opt]
    frame #7: 0x000000010002a8c7 array_bug-d57a78204f1529fa`test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h3defa140cc3517df [inlined] _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h12a9510fad786d50 at boxed.rs:1307:9 [opt]
    frame #8: 0x000000010002a8c0 array_bug-d57a78204f1529fa`test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h3defa140cc3517df [inlined] _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::ha48b56b04ad25da0 at panic.rs:322 [opt]
    frame #9: 0x000000010002a8c0 array_bug-d57a78204f1529fa`test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h3defa140cc3517df [inlined] std::panicking::try::do_call::h4e253e91d72f4add at panicking.rs:381 [opt]
    frame #10: 0x000000010002a8c0 array_bug-d57a78204f1529fa`test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h3defa140cc3517df [inlined] std::panicking::try::h04beadc619e361ca at panicking.rs:345 [opt]
    frame #11: 0x000000010002a8c0 array_bug-d57a78204f1529fa`test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h3defa140cc3517df [inlined] std::panic::catch_unwind::hf3a82a81dfae044e at panic.rs:396 [opt]
    frame #12: 0x000000010002a8c0 array_bug-d57a78204f1529fa`test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h3defa140cc3517df [inlined] test::run_test_in_process::he5ca912ca9f4425d at lib.rs:544 [opt]
    frame #13: 0x000000010002a8a7 array_bug-d57a78204f1529fa`test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h3defa140cc3517df at lib.rs:450 [opt]
    frame #14: 0x0000000100004e4b array_bug-d57a78204f1529fa`std::sys_common::backtrace::__rust_begin_short_backtrace::h11e8de6518e23f3b at backtrace.rs:125:18 [opt]
    frame #15: 0x000000010000a021 array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h9c2b7019f7d7dd03 [inlined] std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::hcfceb62bb517582f at mod.rs:474:17 [opt]
    frame #16: 0x0000000100009ffd array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h9c2b7019f7d7dd03 [inlined] _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h56a2e20a57edcf31 at panic.rs:322 [opt]
    frame #17: 0x0000000100009ffd array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h9c2b7019f7d7dd03 [inlined] std::panicking::try::do_call::ha4b354535e898800 at panicking.rs:381 [opt]
    frame #18: 0x0000000100009ffd array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h9c2b7019f7d7dd03 [inlined] std::panicking::try::hccd11140096bd12b at panicking.rs:345 [opt]
    frame #19: 0x0000000100009ffd array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h9c2b7019f7d7dd03 [inlined] std::panic::catch_unwind::hf486f916485b6696 at panic.rs:396 [opt]
    frame #20: 0x0000000100009ffd array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h9c2b7019f7d7dd03 [inlined] std::thread::Builder::spawn_unchecked::_$u7b$$u7b$closure$u7d$$u7d$::hdb2f765d4cf1e663 at mod.rs:473 [opt]
    frame #21: 0x0000000100009f4d array_bug-d57a78204f1529fa`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h9c2b7019f7d7dd03 at function.rs:227 [opt]
    frame #22: 0x00000001000635ad array_bug-d57a78204f1529fa`std::sys::unix::thread::Thread::new::thread_start::hedb7cc0d930a8f40 [inlined] _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::h22f4d58d7c8a821c at boxed.rs:1307:9 [opt]
    frame #23: 0x00000001000635a7 array_bug-d57a78204f1529fa`std::sys::unix::thread::Thread::new::thread_start::hedb7cc0d930a8f40 [inlined] _$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$::call_once::haa812e1889643845 at boxed.rs:1307 [opt]
    frame #24: 0x000000010006359e array_bug-d57a78204f1529fa`std::sys::unix::thread::Thread::new::thread_start::hedb7cc0d930a8f40 at thread.rs:71 [opt]
    frame #25: 0x00007fff5ddb32eb libsystem_pthread.dylib`_pthread_body + 126
    frame #26: 0x00007fff5ddb6249 libsystem_pthread.dylib`_pthread_start + 66
    frame #27: 0x00007fff5ddb240d libsystem_pthread.dylib`thread_start + 13
```
</p>
</details>