summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
diff options
context:
space:
mode:
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.rs46
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()))
+}