diff options
Diffstat (limited to 'crates/ra_project_model')
-rw-r--r-- | crates/ra_project_model/src/sysroot.rs | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index 43b062023..b426fc107 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use anyhow::{anyhow, bail, Context, Result}; | 3 | use anyhow::{bail, Context, Result}; |
4 | use std::{ | 4 | use std::{ |
5 | env, | 5 | env, |
6 | path::{Path, PathBuf}, | 6 | path::{Path, PathBuf}, |
@@ -48,17 +48,6 @@ impl Sysroot { | |||
48 | 48 | ||
49 | pub fn discover(cargo_toml: &Path) -> Result<Sysroot> { | 49 | pub fn discover(cargo_toml: &Path) -> Result<Sysroot> { |
50 | let src = get_or_install_rust_src(cargo_toml)?; | 50 | let src = get_or_install_rust_src(cargo_toml)?; |
51 | |||
52 | if !src.exists() { | ||
53 | Err(anyhow!( | ||
54 | "can't load standard library from sysroot\n\ | ||
55 | {}\n\ | ||
56 | (discovered via `rustc --print sysroot`)\n\ | ||
57 | try running `rustup component add rust-src` or set `RUST_SRC_PATH`", | ||
58 | src.display(), | ||
59 | ))?; | ||
60 | } | ||
61 | |||
62 | let mut sysroot = Sysroot { crates: Arena::default() }; | 51 | let mut sysroot = Sysroot { crates: Arena::default() }; |
63 | for name in SYSROOT_CRATES.trim().lines() { | 52 | for name in SYSROOT_CRATES.trim().lines() { |
64 | let root = src.join(format!("lib{}", name)).join("lib.rs"); | 53 | let root = src.join(format!("lib{}", name)).join("lib.rs"); |
@@ -91,33 +80,7 @@ impl Sysroot { | |||
91 | } | 80 | } |
92 | 81 | ||
93 | fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> { | 82 | fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> { |
94 | fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> { | 83 | fn try_install_rust_src(cargo_toml: &Path) -> Result<()> { |
95 | if let Ok(path) = env::var("RUST_SRC_PATH") { | ||
96 | return Ok(path.into()); | ||
97 | } | ||
98 | |||
99 | let rustc_output = Command::new("rustc") | ||
100 | .current_dir(cargo_toml.parent().unwrap()) | ||
101 | .args(&["--print", "sysroot"]) | ||
102 | .output() | ||
103 | .context("rustc --print sysroot failed")?; | ||
104 | if !rustc_output.status.success() { | ||
105 | match rustc_output.status.code() { | ||
106 | Some(code) => bail!( | ||
107 | "failed to locate sysroot: rustc --print sysroot exited with code {}", | ||
108 | code | ||
109 | ), | ||
110 | None => { | ||
111 | bail!("failed to locate sysroot: rustc --print sysroot terminated by signal") | ||
112 | } | ||
113 | }; | ||
114 | } | ||
115 | let stdout = String::from_utf8(rustc_output.stdout)?; | ||
116 | let sysroot_path = Path::new(stdout.trim()); | ||
117 | Ok(sysroot_path.join("lib/rustlib/src/rust/src")) | ||
118 | } | ||
119 | |||
120 | fn try_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> { | ||
121 | let rustup_output = Command::new("rustup") | 84 | let rustup_output = Command::new("rustup") |
122 | .current_dir(cargo_toml.parent().unwrap()) | 85 | .current_dir(cargo_toml.parent().unwrap()) |
123 | .args(&["component", "add", "rust-src"]) | 86 | .args(&["component", "add", "rust-src"]) |
@@ -134,15 +97,42 @@ fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> { | |||
134 | ), | 97 | ), |
135 | }; | 98 | }; |
136 | } | 99 | } |
137 | try_find_src_path(cargo_toml) | 100 | Ok(()) |
138 | } | 101 | } |
139 | 102 | ||
140 | let src = try_find_src_path(cargo_toml)?; | 103 | if let Ok(path) = env::var("RUST_SRC_PATH") { |
141 | if !src.exists() { | 104 | return Ok(path.into()); |
142 | try_install_rust_src(cargo_toml) | 105 | } |
143 | } else { | 106 | let rustc_output = Command::new("rustc") |
144 | Ok(src) | 107 | .current_dir(cargo_toml.parent().unwrap()) |
108 | .args(&["--print", "sysroot"]) | ||
109 | .output() | ||
110 | .context("rustc --print sysroot failed")?; | ||
111 | if !rustc_output.status.success() { | ||
112 | match rustc_output.status.code() { | ||
113 | Some(code) => { | ||
114 | bail!("failed to locate sysroot: rustc --print sysroot exited with code {}", code) | ||
115 | } | ||
116 | None => bail!("failed to locate sysroot: rustc --print sysroot terminated by signal"), | ||
117 | }; | ||
118 | } | ||
119 | let stdout = String::from_utf8(rustc_output.stdout)?; | ||
120 | let sysroot_path = Path::new(stdout.trim()); | ||
121 | let src_path = sysroot_path.join("lib/rustlib/src/rust/src"); | ||
122 | |||
123 | if !src_path.exists() { | ||
124 | try_install_rust_src(cargo_toml)? | ||
125 | } | ||
126 | if !src_path.exists() { | ||
127 | bail!( | ||
128 | "can't load standard library from sysroot\n\ | ||
129 | {}\n\ | ||
130 | (discovered via `rustc --print sysroot`)\n\ | ||
131 | try running `rustup component add rust-src` or set `RUST_SRC_PATH`", | ||
132 | src_path.display(), | ||
133 | ) | ||
145 | } | 134 | } |
135 | Ok(src_path) | ||
146 | } | 136 | } |
147 | 137 | ||
148 | impl SysrootCrate { | 138 | impl SysrootCrate { |