aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src/sysroot.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_project_model/src/sysroot.rs')
-rw-r--r--crates/ra_project_model/src/sysroot.rs102
1 files changed, 56 insertions, 46 deletions
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index 943ff92df..a10ade375 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -3,19 +3,19 @@
3use std::{convert::TryFrom, env, ops, path::Path, process::Command}; 3use std::{convert::TryFrom, env, ops, path::Path, process::Command};
4 4
5use anyhow::{bail, format_err, Result}; 5use anyhow::{bail, format_err, Result};
6use paths::{AbsPath, AbsPathBuf};
6use ra_arena::{Arena, Idx}; 7use ra_arena::{Arena, Idx};
7 8
8use crate::output; 9use crate::utf8_stdout;
9use paths::{AbsPath, AbsPathBuf};
10 10
11#[derive(Default, Debug, Clone)] 11#[derive(Default, Debug, Clone, Eq, PartialEq)]
12pub struct Sysroot { 12pub struct Sysroot {
13 crates: Arena<SysrootCrateData>, 13 crates: Arena<SysrootCrateData>,
14} 14}
15 15
16pub type SysrootCrate = Idx<SysrootCrateData>; 16pub type SysrootCrate = Idx<SysrootCrateData>;
17 17
18#[derive(Debug, Clone)] 18#[derive(Debug, Clone, Eq, PartialEq)]
19pub struct SysrootCrateData { 19pub struct SysrootCrateData {
20 pub name: String, 20 pub name: String,
21 pub root: AbsPathBuf, 21 pub root: AbsPathBuf,
@@ -54,6 +54,8 @@ impl Sysroot {
54 let src = get_or_install_rust_src(cargo_toml)?; 54 let src = get_or_install_rust_src(cargo_toml)?;
55 let mut sysroot = Sysroot { crates: Arena::default() }; 55 let mut sysroot = Sysroot { crates: Arena::default() };
56 for name in SYSROOT_CRATES.trim().lines() { 56 for name in SYSROOT_CRATES.trim().lines() {
57 // FIXME: remove this path when 1.47 comes out
58 // https://github.com/rust-lang/rust/pull/73265
57 let root = src.join(format!("lib{}", name)).join("lib.rs"); 59 let root = src.join(format!("lib{}", name)).join("lib.rs");
58 if root.exists() { 60 if root.exists() {
59 sysroot.crates.alloc(SysrootCrateData { 61 sysroot.crates.alloc(SysrootCrateData {
@@ -61,6 +63,15 @@ impl Sysroot {
61 root, 63 root,
62 deps: Vec::new(), 64 deps: Vec::new(),
63 }); 65 });
66 } else {
67 let root = src.join(name).join("src/lib.rs");
68 if root.exists() {
69 sysroot.crates.alloc(SysrootCrateData {
70 name: name.into(),
71 root,
72 deps: Vec::new(),
73 });
74 }
64 } 75 }
65 } 76 }
66 if let Some(std) = sysroot.std() { 77 if let Some(std) = sysroot.std() {
@@ -92,26 +103,40 @@ fn get_or_install_rust_src(cargo_toml: &AbsPath) -> Result<AbsPathBuf> {
92 let current_dir = cargo_toml.parent().unwrap(); 103 let current_dir = cargo_toml.parent().unwrap();
93 let mut rustc = Command::new(ra_toolchain::rustc()); 104 let mut rustc = Command::new(ra_toolchain::rustc());
94 rustc.current_dir(current_dir).args(&["--print", "sysroot"]); 105 rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
95 let rustc_output = output(rustc)?; 106 let stdout = utf8_stdout(rustc)?;
96 let stdout = String::from_utf8(rustc_output.stdout)?;
97 let sysroot_path = AbsPath::assert(Path::new(stdout.trim())); 107 let sysroot_path = AbsPath::assert(Path::new(stdout.trim()));
98 let src_path = sysroot_path.join("lib/rustlib/src/rust/src"); 108 let mut src = get_rust_src(sysroot_path);
99 109 if src.is_none() {
100 if !src_path.exists() {
101 let mut rustup = Command::new(ra_toolchain::rustup()); 110 let mut rustup = Command::new(ra_toolchain::rustup());
102 rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]); 111 rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]);
103 let _output = output(rustup)?; 112 utf8_stdout(rustup)?;
113 src = get_rust_src(sysroot_path);
104 } 114 }
105 if !src_path.exists() { 115 match src {
106 bail!( 116 Some(r) => Ok(r),
117 None => bail!(
107 "can't load standard library from sysroot\n\ 118 "can't load standard library from sysroot\n\
108 {}\n\ 119 {}\n\
109 (discovered via `rustc --print sysroot`)\n\ 120 (discovered via `rustc --print sysroot`)\n\
110 try running `rustup component add rust-src` or set `RUST_SRC_PATH`", 121 try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
111 src_path.display(), 122 sysroot_path.display(),
112 ) 123 ),
124 }
125}
126
127fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
128 // try the new path first since the old one still exists
129 let mut src_path = sysroot_path.join("lib/rustlib/src/rust/library");
130 if !src_path.exists() {
131 // FIXME: remove this path when 1.47 comes out
132 // https://github.com/rust-lang/rust/pull/73265
133 src_path = sysroot_path.join("lib/rustlib/src/rust/src");
134 }
135 if src_path.exists() {
136 Some(src_path)
137 } else {
138 None
113 } 139 }
114 Ok(src_path)
115} 140}
116 141
117impl SysrootCrateData { 142impl SysrootCrateData {
@@ -121,43 +146,28 @@ impl SysrootCrateData {
121} 146}
122 147
123const SYSROOT_CRATES: &str = " 148const SYSROOT_CRATES: &str = "
124std
125core
126alloc 149alloc
127collections 150core
128libc 151panic_abort
129panic_unwind 152panic_unwind
130proc_macro 153proc_macro
131rustc_unicode 154profiler_builtins
132std_unicode 155rtstartup
133test 156std
134alloc_jemalloc 157stdarch
135alloc_system
136compiler_builtins
137getopts
138panic_unwind
139panic_abort
140rand
141term 158term
142unwind 159test
143build_helper 160unwind";
144rustc_asan
145rustc_lsan
146rustc_msan
147rustc_tsan
148syntax";
149 161
150const STD_DEPS: &str = " 162const STD_DEPS: &str = "
151alloc 163alloc
152alloc_jemalloc
153alloc_system
154core 164core
155panic_abort 165panic_abort
156rand 166panic_unwind
157compiler_builtins 167profiler_builtins
158unwind 168rtstartup
159rustc_asan 169proc_macro
160rustc_lsan 170stdarch
161rustc_msan 171term
162rustc_tsan 172test
163build_helper"; 173unwind";