From 4a6e602c9419cc5ed464343b2373c7fe86fb89d6 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 11 Feb 2021 17:34:56 +0100 Subject: Allow automatically detect the rustc-src directory (fixes #3517). If the configured rustcSource is set to "discover", try to automatically detect a source from the sysroot rustc directory. --- crates/project_model/src/sysroot.rs | 40 +++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'crates/project_model/src/sysroot.rs') diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs index ff44dae4a..3b0ff506d 100644 --- a/crates/project_model/src/sysroot.rs +++ b/crates/project_model/src/sysroot.rs @@ -51,11 +51,18 @@ impl Sysroot { pub fn discover(cargo_toml: &AbsPath) -> Result { log::debug!("Discovering sysroot for {}", cargo_toml.display()); let current_dir = cargo_toml.parent().unwrap(); - let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?; + let sysroot_dir = discover_sysroot_dir(current_dir)?; + let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, current_dir)?; let res = Sysroot::load(&sysroot_src_dir)?; Ok(res) } + pub fn discover_rustc(cargo_toml: &AbsPath) -> Option { + log::debug!("Discovering rustc source for {}", cargo_toml.display()); + let current_dir = cargo_toml.parent().unwrap(); + discover_sysroot_dir(current_dir).ok().and_then(|sysroot_dir| get_rustc_src(&sysroot_dir)) + } + pub fn load(sysroot_src_dir: &AbsPath) -> Result { let mut sysroot = Sysroot { crates: Arena::default() }; @@ -110,7 +117,18 @@ impl Sysroot { } } -fn discover_sysroot_src_dir(current_dir: &AbsPath) -> Result { +fn discover_sysroot_dir(current_dir: &AbsPath) -> Result { + let mut rustc = Command::new(toolchain::rustc()); + rustc.current_dir(current_dir).args(&["--print", "sysroot"]); + log::debug!("Discovering sysroot by {:?}", rustc); + let stdout = utf8_stdout(rustc)?; + Ok(AbsPathBuf::assert(PathBuf::from(stdout))) +} + +fn discover_sysroot_src_dir( + sysroot_path: &AbsPathBuf, + current_dir: &AbsPath, +) -> Result { if let Ok(path) = env::var("RUST_SRC_PATH") { let path = AbsPathBuf::try_from(path.as_str()) .map_err(|path| format_err!("RUST_SRC_PATH must be absolute: {}", path.display()))?; @@ -122,14 +140,6 @@ fn discover_sysroot_src_dir(current_dir: &AbsPath) -> Result { log::debug!("RUST_SRC_PATH is set, but is invalid (no core: {:?}), ignoring", core); } - let sysroot_path = { - let mut rustc = Command::new(toolchain::rustc()); - rustc.current_dir(current_dir).args(&["--print", "sysroot"]); - log::debug!("Discovering sysroot by {:?}", rustc); - let stdout = utf8_stdout(rustc)?; - AbsPathBuf::assert(PathBuf::from(stdout)) - }; - get_rust_src(&sysroot_path) .or_else(|| { let mut rustup = Command::new(toolchain::rustup()); @@ -149,6 +159,16 @@ try installing the Rust source the same way you installed rustc", }) } +fn get_rustc_src(sysroot_path: &AbsPath) -> Option { + let rustc_src = sysroot_path.join("lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml"); + log::debug!("Checking for rustc source code: {}", rustc_src.display()); + if rustc_src.exists() { + Some(rustc_src) + } else { + None + } +} + fn get_rust_src(sysroot_path: &AbsPath) -> Option { // Try the new path first since the old one still exists. let rust_src = sysroot_path.join("lib/rustlib/src/rust"); -- cgit v1.2.3