aboutsummaryrefslogtreecommitdiff
path: root/crates/project_model/src/sysroot.rs
diff options
context:
space:
mode:
authorBenjamin Bouvier <[email protected]>2021-02-11 16:34:56 +0000
committerBenjamin Bouvier <[email protected]>2021-02-13 17:20:46 +0000
commit4a6e602c9419cc5ed464343b2373c7fe86fb89d6 (patch)
treeed4148a4ccb0a7e81cb897f611e66e40bf492488 /crates/project_model/src/sysroot.rs
parent2967e783ac53e89f06a8f8bd1afc12433311fded (diff)
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.
Diffstat (limited to 'crates/project_model/src/sysroot.rs')
-rw-r--r--crates/project_model/src/sysroot.rs40
1 files changed, 30 insertions, 10 deletions
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 {
51 pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> { 51 pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
52 log::debug!("Discovering sysroot for {}", cargo_toml.display()); 52 log::debug!("Discovering sysroot for {}", cargo_toml.display());
53 let current_dir = cargo_toml.parent().unwrap(); 53 let current_dir = cargo_toml.parent().unwrap();
54 let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?; 54 let sysroot_dir = discover_sysroot_dir(current_dir)?;
55 let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, current_dir)?;
55 let res = Sysroot::load(&sysroot_src_dir)?; 56 let res = Sysroot::load(&sysroot_src_dir)?;
56 Ok(res) 57 Ok(res)
57 } 58 }
58 59
60 pub fn discover_rustc(cargo_toml: &AbsPath) -> Option<AbsPathBuf> {
61 log::debug!("Discovering rustc source for {}", cargo_toml.display());
62 let current_dir = cargo_toml.parent().unwrap();
63 discover_sysroot_dir(current_dir).ok().and_then(|sysroot_dir| get_rustc_src(&sysroot_dir))
64 }
65
59 pub fn load(sysroot_src_dir: &AbsPath) -> Result<Sysroot> { 66 pub fn load(sysroot_src_dir: &AbsPath) -> Result<Sysroot> {
60 let mut sysroot = Sysroot { crates: Arena::default() }; 67 let mut sysroot = Sysroot { crates: Arena::default() };
61 68
@@ -110,7 +117,18 @@ impl Sysroot {
110 } 117 }
111} 118}
112 119
113fn discover_sysroot_src_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> { 120fn discover_sysroot_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> {
121 let mut rustc = Command::new(toolchain::rustc());
122 rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
123 log::debug!("Discovering sysroot by {:?}", rustc);
124 let stdout = utf8_stdout(rustc)?;
125 Ok(AbsPathBuf::assert(PathBuf::from(stdout)))
126}
127
128fn discover_sysroot_src_dir(
129 sysroot_path: &AbsPathBuf,
130 current_dir: &AbsPath,
131) -> Result<AbsPathBuf> {
114 if let Ok(path) = env::var("RUST_SRC_PATH") { 132 if let Ok(path) = env::var("RUST_SRC_PATH") {
115 let path = AbsPathBuf::try_from(path.as_str()) 133 let path = AbsPathBuf::try_from(path.as_str())
116 .map_err(|path| format_err!("RUST_SRC_PATH must be absolute: {}", path.display()))?; 134 .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<AbsPathBuf> {
122 log::debug!("RUST_SRC_PATH is set, but is invalid (no core: {:?}), ignoring", core); 140 log::debug!("RUST_SRC_PATH is set, but is invalid (no core: {:?}), ignoring", core);
123 } 141 }
124 142
125 let sysroot_path = {
126 let mut rustc = Command::new(toolchain::rustc());
127 rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
128 log::debug!("Discovering sysroot by {:?}", rustc);
129 let stdout = utf8_stdout(rustc)?;
130 AbsPathBuf::assert(PathBuf::from(stdout))
131 };
132
133 get_rust_src(&sysroot_path) 143 get_rust_src(&sysroot_path)
134 .or_else(|| { 144 .or_else(|| {
135 let mut rustup = Command::new(toolchain::rustup()); 145 let mut rustup = Command::new(toolchain::rustup());
@@ -149,6 +159,16 @@ try installing the Rust source the same way you installed rustc",
149 }) 159 })
150} 160}
151 161
162fn get_rustc_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
163 let rustc_src = sysroot_path.join("lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml");
164 log::debug!("Checking for rustc source code: {}", rustc_src.display());
165 if rustc_src.exists() {
166 Some(rustc_src)
167 } else {
168 None
169 }
170}
171
152fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> { 172fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
153 // Try the new path first since the old one still exists. 173 // Try the new path first since the old one still exists.
154 let rust_src = sysroot_path.join("lib/rustlib/src/rust"); 174 let rust_src = sysroot_path.join("lib/rustlib/src/rust");