diff options
Diffstat (limited to 'crates/project_model/src/sysroot.rs')
-rw-r--r-- | crates/project_model/src/sysroot.rs | 40 |
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 | ||
113 | fn discover_sysroot_src_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> { | 120 | fn 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 | |||
128 | fn 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 | ||
162 | fn 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 | |||
152 | fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> { | 172 | fn 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"); |