From 5cea8a37b75d84bbc95cb66487cc768181d440d5 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 17 Feb 2020 23:33:48 +0200 Subject: [PATCH] Install rust-src when it is not found --- crates/ra_project_model/src/sysroot.rs | 39 ++++++++++++++++++++------ docs/user/readme.adoc | 4 ++- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index 7b9cc899c07..28756c7ca2b 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs @@ -47,16 +47,19 @@ pub fn crates<'a>(&'a self) -> impl Iterator + ExactSizeIte } 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 diff --git a/docs/user/readme.adoc b/docs/user/readme.adoc index 57a8cbe312d..cb171defda2 100644 --- a/docs/user/readme.adoc +++ b/docs/user/readme.adoc @@ -20,7 +20,9 @@ In theory, one should be able to just install the server binary and have it auto We are not there yet, so some editor specific setup is required. Additionally, rust-analyzer needs sources of the standard library. -This commands adds them: +When fails to locate them, rust-analyzer attempts to install them automatically. + +To add the sources manually, run the following command: ```bash $ rustup component add rust-src