rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
99.1k stars 12.79k forks source link

Rust compiler hangs when pretty-printing MIR for a constant #132122

Open celinval opened 1 month ago

celinval commented 1 month ago

I tried this code:

// compiler-flags: --emit mir
fn main() {
    let _dummy = [(); usize::MAX];
}

I expected to see this happen: Compilation should succeed and generate a MIR file

Instead, this happened: Compiler hangs

Meta

rustc --version --verbose:

rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: x86_64-unknown-linux-gnu
release: 1.82.0
LLVM version: 19.1.1
I tried the same example in the playground, and it reported that the program was killed.

``` Compiling playground v0.0.1 (/playground) error: could not compile `playground` (bin "playground") Caused by: process didn't exit successfully: `/playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name playground --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --emit mir=compilation --check-cfg 'cfg(docsrs)' --check-cfg 'cfg(feature, values())' -C metadata=78b40b1b4b7fab71 -C extra-filename=-78b40b1b4b7fab71 --out-dir /playground/target/debug/deps -L dependency=/playground/target/debug/deps -L native=/playground/target/debug/build/libsqlite3-sys-6cf5b51c5e7b32e1/out -L native=/playground/target/debug/build/ring-5cfcc6da0313868c/out -L native=/playground/.cargo/registry/src/index.crates.io-6f17d22bba15001f/windows_x86_64_msvc-0.52.6/lib` (signal: 9, SIGKILL: kill) ```

FYI, the same issue happens in StableMIR pretty print. I believe the compiler is hanging inside rustc_middle::mir::pretty::pretty_print_const_value.

celinval commented 1 month ago

This seems to be related to using usize::MAX inside the array. I did debug this a bit further, and the problem is that the pretty print expands the content of the array. In this case, it is trying to generate 2^64 x ().

lolbinarycat commented 1 month ago

In what practical scenario would this be useful?

I suppose it could elipsize the constant, but that would probably be a nuisance in other non-extreme scenarios.

celinval commented 1 month ago

I could see buffer initialization blowing up the generated MIR, but I agree that usize::MAX is not a very practical example. I bumped into this issue while looking at how size_of_val_raw can overflow using safe Rust.