]>
Commit | Line | Data |
---|---|---|
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 | |
7 | use std::{ | |
8 | ffi::OsString, | |
9 | io, | |
10 | process::{Command, Stdio}, | |
11 | }; | |
12 | ||
13 | /// ExitCode/ExitStatus are impossible to create :(. | |
14 | pub(crate) struct ExitCode(pub(crate) Option<i32>); | |
15 | ||
16 | pub(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 | ||
43 | fn 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 | } |