diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs new file mode 100644 index 000000000..2f6d4706d --- /dev/null +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs @@ -0,0 +1,46 @@ +//! We setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself during the +//! initial `cargo check`. That way, we avoid checking the actual project, and +//! only build proc macros and build.rs. +//! +//! Code taken from IntelliJ :0) +//! https://github.com/intellij-rust/intellij-rust/blob/master/native-helper/src/main.rs +use std::{ + ffi::OsString, + io, + process::{Command, Stdio}, +}; + +/// ExitCode/ExitStatus are impossible to create :(. +pub(crate) struct ExitCode(pub(crate) Option<i32>); + +pub(crate) fn run_rustc_skipping_cargo_checking( + rustc_executable: OsString, + args: Vec<OsString>, +) -> io::Result<ExitCode> { + let is_cargo_check = args.iter().any(|arg| { + let arg = arg.to_string_lossy(); + // `cargo check` invokes `rustc` with `--emit=metadata` argument. + // + // https://doc.rust-lang.org/rustc/command-line-arguments.html#--emit-specifies-the-types-of-output-files-to-generate + // link — Generates the crates specified by --crate-type. The default + // output filenames depend on the crate type and platform. This + // is the default if --emit is not specified. + // metadata — Generates a file containing metadata about the crate. + // The default output filename is CRATE_NAME.rmeta. + arg.starts_with("--emit=") && arg.contains("metadata") && !arg.contains("link") + }); + if is_cargo_check { + return Ok(ExitCode(Some(0))); + } + run_rustc(rustc_executable, args) +} + +fn run_rustc(rustc_executable: OsString, args: Vec<OsString>) -> io::Result<ExitCode> { + let mut child = Command::new(rustc_executable) + .args(args) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()?; + Ok(ExitCode(child.wait()?.code())) +} |