]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / rust-analyzer / src / bin / rustc_wrapper.rs
CommitLineData
064997fb
FG
1//! We setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself during the
2//! initial `cargo check`. That way, we avoid checking the actual project, and
3//! only build proc macros and build.rs.
4//!
5//! Code taken from IntelliJ :0)
6//! https://github.com/intellij-rust/intellij-rust/blob/master/native-helper/src/main.rs
7use std::{
8 ffi::OsString,
9 io,
10 process::{Command, Stdio},
11};
12
13/// ExitCode/ExitStatus are impossible to create :(.
14pub(crate) struct ExitCode(pub(crate) Option<i32>);
15
16pub(crate) fn run_rustc_skipping_cargo_checking(
17 rustc_executable: OsString,
18 args: Vec<OsString>,
19) -> io::Result<ExitCode> {
f2b60f7d
FG
20 // `CARGO_CFG_TARGET_ARCH` is only set by cargo when executing build scripts
21 // We don't want to exit out checks unconditionally with success if a build
22 // script tries to invoke checks themselves
23 // See https://github.com/rust-lang/rust-analyzer/issues/12973 for context
24 let not_invoked_by_build_script = std::env::var_os("CARGO_CFG_TARGET_ARCH").is_none();
064997fb
FG
25 let is_cargo_check = args.iter().any(|arg| {
26 let arg = arg.to_string_lossy();
27 // `cargo check` invokes `rustc` with `--emit=metadata` argument.
28 //
29 // https://doc.rust-lang.org/rustc/command-line-arguments.html#--emit-specifies-the-types-of-output-files-to-generate
30 // link — Generates the crates specified by --crate-type. The default
31 // output filenames depend on the crate type and platform. This
32 // is the default if --emit is not specified.
33 // metadata — Generates a file containing metadata about the crate.
34 // The default output filename is CRATE_NAME.rmeta.
35 arg.starts_with("--emit=") && arg.contains("metadata") && !arg.contains("link")
36 });
f2b60f7d 37 if not_invoked_by_build_script && is_cargo_check {
064997fb
FG
38 return Ok(ExitCode(Some(0)));
39 }
40 run_rustc(rustc_executable, args)
41}
42
43fn run_rustc(rustc_executable: OsString, args: Vec<OsString>) -> io::Result<ExitCode> {
44 let mut child = Command::new(rustc_executable)
45 .args(args)
46 .stdin(Stdio::inherit())
47 .stdout(Stdio::inherit())
48 .stderr(Stdio::inherit())
49 .spawn()?;
50 Ok(ExitCode(child.wait()?.code()))
51}