Skip to content

Commit ad7e7d6

Browse files
bors[bot]matklad
andauthored
Merge #5876
5876: Prep work for overriding sysroot r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 81a3404 + 6b8bc13 commit ad7e7d6

File tree

2 files changed

+61
-54
lines changed

2 files changed

+61
-54
lines changed

crates/project_model/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,5 +561,5 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> {
561561
}
562562
}
563563
let stdout = String::from_utf8(output.stdout)?;
564-
Ok(stdout)
564+
Ok(stdout.trim().to_string())
565565
}

crates/project_model/src/sysroot.rs

Lines changed: 60 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
//! FIXME: write short doc here
1+
//! Loads "sysroot" crate.
2+
//!
3+
//! One confusing point here is that normally sysroot is a bunch of `.rlib`s,
4+
//! but we can't process `.rlib` and need source code instead. The source code
5+
//! is typically installed with `rustup component add rust-src` command.
26
3-
use std::{convert::TryFrom, env, ops, path::Path, process::Command};
7+
use std::{convert::TryFrom, env, ops, path::PathBuf, process::Command};
48

5-
use anyhow::{bail, format_err, Result};
9+
use anyhow::{format_err, Result};
610
use arena::{Arena, Idx};
711
use paths::{AbsPath, AbsPathBuf};
812

@@ -51,92 +55,95 @@ impl Sysroot {
5155
}
5256

5357
pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
54-
let src = get_or_install_rust_src(cargo_toml)?;
58+
let current_dir = cargo_toml.parent().unwrap();
59+
let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?;
60+
let res = Sysroot::load(&sysroot_src_dir);
61+
Ok(res)
62+
}
63+
64+
pub fn load(sysroot_src_dir: &AbsPath) -> Sysroot {
5565
let mut sysroot = Sysroot { crates: Arena::default() };
66+
5667
for name in SYSROOT_CRATES.trim().lines() {
57-
// FIXME: remove this path when 1.47 comes out
68+
// FIXME: first path when 1.47 comes out
5869
// https://github.com/rust-lang/rust/pull/73265
59-
let root = src.join(format!("lib{}", name)).join("lib.rs");
60-
if root.exists() {
70+
let root = [format!("lib{}/lib.rs", name), format!("{}/src/lib.rs", name)]
71+
.iter()
72+
.map(|it| sysroot_src_dir.join(it))
73+
.find(|it| it.exists());
74+
75+
if let Some(root) = root {
6176
sysroot.crates.alloc(SysrootCrateData {
6277
name: name.into(),
6378
root,
6479
deps: Vec::new(),
6580
});
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-
}
7581
}
7682
}
83+
7784
if let Some(std) = sysroot.std() {
7885
for dep in STD_DEPS.trim().lines() {
7986
if let Some(dep) = sysroot.by_name(dep) {
8087
sysroot.crates[std].deps.push(dep)
8188
}
8289
}
8390
}
91+
8492
if let Some(alloc) = sysroot.alloc() {
8593
if let Some(core) = sysroot.core() {
8694
sysroot.crates[alloc].deps.push(core);
8795
}
8896
}
89-
Ok(sysroot)
97+
98+
sysroot
9099
}
91100

92101
fn by_name(&self, name: &str) -> Option<SysrootCrate> {
93-
self.crates.iter().find(|(_id, data)| data.name == name).map(|(id, _data)| id)
102+
let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?;
103+
Some(id)
94104
}
95105
}
96106

97-
fn get_or_install_rust_src(cargo_toml: &AbsPath) -> Result<AbsPathBuf> {
107+
fn discover_sysroot_src_dir(current_dir: &AbsPath) -> Result<AbsPathBuf> {
98108
if let Ok(path) = env::var("RUST_SRC_PATH") {
99109
let path = AbsPathBuf::try_from(path.as_str())
100110
.map_err(|path| format_err!("RUST_SRC_PATH must be absolute: {}", path.display()))?;
101111
return Ok(path);
102112
}
103-
let current_dir = cargo_toml.parent().unwrap();
104-
let mut rustc = Command::new(toolchain::rustc());
105-
rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
106-
let stdout = utf8_stdout(rustc)?;
107-
let sysroot_path = AbsPath::assert(Path::new(stdout.trim()));
108-
let mut src = get_rust_src(sysroot_path);
109-
if src.is_none() {
110-
let mut rustup = Command::new(toolchain::rustup());
111-
rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]);
112-
utf8_stdout(rustup)?;
113-
src = get_rust_src(sysroot_path);
114-
}
115-
match src {
116-
Some(r) => Ok(r),
117-
None => bail!(
118-
"can't load standard library from sysroot\n\
119-
{}\n\
120-
(discovered via `rustc --print sysroot`)\n\
121-
try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
122-
sysroot_path.display(),
123-
),
124-
}
113+
114+
let sysroot_path = {
115+
let mut rustc = Command::new(toolchain::rustc());
116+
rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
117+
let stdout = utf8_stdout(rustc)?;
118+
AbsPathBuf::assert(PathBuf::from(stdout))
119+
};
120+
121+
get_rust_src(&sysroot_path)
122+
.or_else(|| {
123+
let mut rustup = Command::new(toolchain::rustup());
124+
rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]);
125+
utf8_stdout(rustup).ok()?;
126+
get_rust_src(&sysroot_path)
127+
})
128+
.ok_or_else(|| {
129+
format_err!(
130+
"\
131+
can't load standard library from sysroot
132+
{}
133+
(discovered via `rustc --print sysroot`)
134+
try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
135+
sysroot_path.display(),
136+
)
137+
})
125138
}
126139

127140
fn 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
139-
}
141+
// Try the new path first since the old one still exists.
142+
//
143+
// FIXME: remove `src` when 1.47 comes out
144+
// https://github.com/rust-lang/rust/pull/73265
145+
let rust_src = sysroot_path.join("lib/rustlib/src/rust");
146+
["library", "src"].iter().map(|it| rust_src.join(it)).find(|it| it.exists())
140147
}
141148

142149
impl SysrootCrateData {

0 commit comments

Comments
 (0)