From 5cea8a37b75d84bbc95cb66487cc768181d440d5 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 17 Feb 2020 23:33:48 +0200 Subject: Install rust-src when it is not found --- crates/ra_project_model/src/sysroot.rs | 39 +++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'crates/ra_project_model/src/sysroot.rs') diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index 7b9cc899c..28756c7ca 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs @@ -47,16 +47,19 @@ impl Sysroot { } pub fn discover(cargo_toml: &Path) -> Result { - let src = try_find_src_path(cargo_toml)?; + let mut src = try_find_src_path(cargo_toml)?; if !src.exists() { - Err(anyhow!( - "can't load standard library from sysroot\n\ - {}\n\ - (discovered via `rustc --print sysroot`)\n\ - try running `rustup component add rust-src` or set `RUST_SRC_PATH`", - src.display(), - ))?; + src = try_install_rust_src(cargo_toml)?; + if !src.exists() { + Err(anyhow!( + "can't load standard library from sysroot\n\ + {}\n\ + (discovered via `rustc --print sysroot`)\n\ + try running `rustup component add rust-src` or set `RUST_SRC_PATH`", + src.display(), + ))?; + } } let mut sysroot = Sysroot { crates: Arena::default() }; @@ -113,6 +116,26 @@ fn try_find_src_path(cargo_toml: &Path) -> Result { Ok(sysroot_path.join("lib/rustlib/src/rust/src")) } +fn try_install_rust_src(cargo_toml: &Path) -> Result { + let rustup_output = Command::new("rustup") + .current_dir(cargo_toml.parent().unwrap()) + .args(&["component", "add", "rust-src"]) + .output() + .context("rustup component add rust-src failed")?; + if !rustup_output.status.success() { + match rustup_output.status.code() { + Some(code) => bail!( + "failed to install rust-src: rustup component add rust-src exited with code {}", + code + ), + None => bail!( + "failed to install rust-src: rustup component add rust-src terminated by signal" + ), + }; + } + try_find_src_path(cargo_toml) +} + impl SysrootCrate { pub fn name(self, sysroot: &Sysroot) -> &str { &sysroot.crates[self].name -- cgit v1.2.3