rust-lang / rustfmt

Format Rust code
https://rust-lang.github.io/rustfmt/
Apache License 2.0
6.05k stars 888 forks source link

RustFmt takes entire ram when formatting simple(broken) file #5752

Open qarmin opened 1 year ago

qarmin commented 1 year ago
rustfmt 1.5.2-nightly (a41fc00 2023-04-13)

File

cfg_if::cfg_if! {
    if #[cfg(any(
        all(target_arch = "wasm32", not(target_os = "wasi")),
        target_arch = "asmjs"
    ))] {
        #[cfg(all(feature = "stdweb", not(feature = "wasm-bindgen")))]
        extern crate stdweb;

        mod wasm;
        pub use wasm::Instant;
        pub use crate::wasm::now;
        pub use wasm::SystemTime;
    } else {
        mod native;
        pub use native::Instant;
    %=    pub use native::now;
    }
}

will take 20GB ram and upset my oom killer which will kill process

calebcartwright commented 1 year ago

Could you tell us a little more about the context in which you're seeing this? I'm unable to reproduce anything remotely resembling the behavior you're describing, so it would be helpful to know things like, how are you running rustfmt (e.g. via your editor or rustfmt file.rs), what platform/os are you on?, etc.

qarmin commented 1 year ago

Hmm...

For me simple rustfmt Broken/RUST_FILE_14086_06261.rs cause this problem without any special arguments

Zipped file - RUST_FILE_14086_06261.rs.zip

System:
  Host: rafal-H87M-D3H Kernel: 5.19.0-38-generic arch: x86_64 bits: 64
    compiler: N/A Desktop: GNOME v: 43.1 Distro: Ubuntu 22.10 (Kinetic Kudu)
Graphics:
  Device-1: AMD Ellesmere [Radeon RX 470/480/570/570X/580/580X/590]
    vendor: Sapphire driver: amdgpu v: kernel arch: GCN-4 bus-ID: 01:00.0
  Display: x11 server: X.Org v: 1.21.1.4 with: Xwayland v: 22.1.3 driver:
    X: loaded: amdgpu unloaded: fbdev,modesetting,radeon,vesa gpu: amdgpu
    resolution: 1: 1920x1080~60Hz 2: 1920x1080~60Hz
  OpenGL: renderer: AMD Radeon RX 570 Series (polaris10 LLVM 15.0.7 DRM
    3.47 5.19.0-38-generic) v: 4.6 Mesa 22.3.5 (git-78ef633056)
    direct render: Yes
calebcartwright commented 1 year ago

Able to reproduce with a more recently nightly (though not rustfmt from source) so it's possible something's changed upstream that happens to get triggered via the way rustfmt is utilizing some of the functions from rustc_parse

The triggering issue is the arbitrary %= you have on the last line in the else block, so removing that should allow you to get back to normal formatting behavior

whfuyn commented 1 year ago

I have run into a similar issue with rustfmt --check. It takes a huge amount of memory checking the format of a generated file. After some investigation, I was able to create a minimal reproducible example:

#[allow(
    clippy::too_many_arguments,
)]
pub mod module {
    #[rustfmt::skip]
    const __BYTECODE: &[u8] = &[
        0,
        1,
        2,
        ... // ~35k lines
    ];
    pub static CODE: _ = (
        __BYTECODE,
    );
}

There are about 35k lines in that byte code.

Only occurs in --check mode.

/home/runner/.cargo/bin/cargo fmt --all -- --check
memory allocation of 22871337920 bytes failed
$ rustfmt --version
rustfmt 1.5.2-stable (84c898d 2023-04-16)
Manishearth commented 1 year ago

Getting the same thing on GitHub Actions Windows CI builders (not OSX or Ubuntu), with this 5MB file that's basically a https://gist.github.com/Manishearth/ac352f577efd0357ad4187ddf787bf44 . I've included what it looks like when formatted too

Does not need --check mode.

The error is memory allocation of 9999999984 bytes failed. We're going to try and reduce the max_width and see what happens.