Report better errors in project.json/sysroot

This commit is contained in:
Jonas Schievink 2020-09-11 14:48:56 +02:00
parent 4f1167d8dd
commit 681ac6294a
4 changed files with 36 additions and 17 deletions

View File

@ -33,7 +33,7 @@ pub enum ProjectWorkspace {
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
Cargo { cargo: CargoWorkspace, sysroot: Sysroot }, Cargo { cargo: CargoWorkspace, sysroot: Sysroot },
/// Project workspace was manually specified using a `rust-project.json` file. /// Project workspace was manually specified using a `rust-project.json` file.
Json { project: ProjectJson }, Json { project: ProjectJson, sysroot: Option<Sysroot> },
} }
impl fmt::Debug for ProjectWorkspace { impl fmt::Debug for ProjectWorkspace {
@ -44,10 +44,10 @@ impl fmt::Debug for ProjectWorkspace {
.field("n_packages", &cargo.packages().len()) .field("n_packages", &cargo.packages().len())
.field("n_sysroot_crates", &sysroot.crates().len()) .field("n_sysroot_crates", &sysroot.crates().len())
.finish(), .finish(),
ProjectWorkspace::Json { project } => { ProjectWorkspace::Json { project, sysroot } => {
let mut debug_struct = f.debug_struct("Json"); let mut debug_struct = f.debug_struct("Json");
debug_struct.field("n_crates", &project.n_crates()); debug_struct.field("n_crates", &project.n_crates());
if let Some(sysroot) = &project.sysroot { if let Some(sysroot) = sysroot {
debug_struct.field("n_sysroot_crates", &sysroot.crates().len()); debug_struct.field("n_sysroot_crates", &sysroot.crates().len());
} }
debug_struct.finish() debug_struct.finish()
@ -169,7 +169,11 @@ impl ProjectWorkspace {
})?; })?;
let project_location = project_json.parent().unwrap().to_path_buf(); let project_location = project_json.parent().unwrap().to_path_buf();
let project = ProjectJson::new(&project_location, data); let project = ProjectJson::new(&project_location, data);
ProjectWorkspace::Json { project } let sysroot = match &project.sysroot_src {
Some(path) => Some(Sysroot::load(path)?),
None => None,
};
ProjectWorkspace::Json { project, sysroot }
} }
ProjectManifest::CargoToml(cargo_toml) => { ProjectManifest::CargoToml(cargo_toml) => {
let cargo_version = utf8_stdout({ let cargo_version = utf8_stdout({
@ -203,12 +207,21 @@ impl ProjectWorkspace {
Ok(res) Ok(res)
} }
pub fn load_inline(project_json: ProjectJson) -> Result<ProjectWorkspace> {
let sysroot = match &project_json.sysroot_src {
Some(path) => Some(Sysroot::load(path)?),
None => None,
};
Ok(ProjectWorkspace::Json { project: project_json, sysroot })
}
/// Returns the roots for the current `ProjectWorkspace` /// Returns the roots for the current `ProjectWorkspace`
/// The return type contains the path and whether or not /// The return type contains the path and whether or not
/// the root is a member of the current workspace /// the root is a member of the current workspace
pub fn to_roots(&self) -> Vec<PackageRoot> { pub fn to_roots(&self) -> Vec<PackageRoot> {
match self { match self {
ProjectWorkspace::Json { project } => project ProjectWorkspace::Json { project, sysroot } => project
.crates() .crates()
.map(|(_, krate)| PackageRoot { .map(|(_, krate)| PackageRoot {
is_member: krate.is_workspace_member, is_member: krate.is_workspace_member,
@ -217,7 +230,7 @@ impl ProjectWorkspace {
}) })
.collect::<FxHashSet<_>>() .collect::<FxHashSet<_>>()
.into_iter() .into_iter()
.chain(project.sysroot.as_ref().into_iter().flat_map(|sysroot| { .chain(sysroot.as_ref().into_iter().flat_map(|sysroot| {
sysroot.crates().map(move |krate| PackageRoot { sysroot.crates().map(move |krate| PackageRoot {
is_member: false, is_member: false,
include: vec![sysroot[krate].root_dir().to_path_buf()], include: vec![sysroot[krate].root_dir().to_path_buf()],
@ -255,7 +268,7 @@ impl ProjectWorkspace {
pub fn proc_macro_dylib_paths(&self) -> Vec<AbsPathBuf> { pub fn proc_macro_dylib_paths(&self) -> Vec<AbsPathBuf> {
match self { match self {
ProjectWorkspace::Json { project } => project ProjectWorkspace::Json { project, sysroot: _ } => project
.crates() .crates()
.filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref()) .filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref())
.cloned() .cloned()
@ -285,9 +298,8 @@ impl ProjectWorkspace {
) -> CrateGraph { ) -> CrateGraph {
let mut crate_graph = CrateGraph::default(); let mut crate_graph = CrateGraph::default();
match self { match self {
ProjectWorkspace::Json { project } => { ProjectWorkspace::Json { project, sysroot } => {
let sysroot_dps = project let sysroot_dps = sysroot
.sysroot
.as_ref() .as_ref()
.map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load)); .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load));

View File

@ -7,12 +7,12 @@ use paths::{AbsPath, AbsPathBuf};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use serde::{de, Deserialize}; use serde::{de, Deserialize};
use crate::{cfg_flag::CfgFlag, Sysroot}; use crate::cfg_flag::CfgFlag;
/// Roots and crates that compose this Rust project. /// Roots and crates that compose this Rust project.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct ProjectJson { pub struct ProjectJson {
pub(crate) sysroot: Option<Sysroot>, pub(crate) sysroot_src: Option<AbsPathBuf>,
crates: Vec<Crate>, crates: Vec<Crate>,
} }
@ -35,7 +35,7 @@ pub struct Crate {
impl ProjectJson { impl ProjectJson {
pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson { pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson {
ProjectJson { ProjectJson {
sysroot: data.sysroot_src.map(|it| base.join(it)).map(|it| Sysroot::load(&it)), sysroot_src: data.sysroot_src.map(|it| base.join(it)),
crates: data crates: data
.crates .crates
.into_iter() .into_iter()

View File

@ -51,11 +51,11 @@ impl Sysroot {
pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> { pub fn discover(cargo_toml: &AbsPath) -> Result<Sysroot> {
let current_dir = cargo_toml.parent().unwrap(); let current_dir = cargo_toml.parent().unwrap();
let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?; let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?;
let res = Sysroot::load(&sysroot_src_dir); let res = Sysroot::load(&sysroot_src_dir)?;
Ok(res) Ok(res)
} }
pub fn load(sysroot_src_dir: &AbsPath) -> Sysroot { pub fn load(sysroot_src_dir: &AbsPath) -> Result<Sysroot> {
let mut sysroot = Sysroot { crates: Arena::default() }; let mut sysroot = Sysroot { crates: Arena::default() };
for name in SYSROOT_CRATES.trim().lines() { for name in SYSROOT_CRATES.trim().lines() {
@ -89,7 +89,14 @@ impl Sysroot {
} }
} }
sysroot if sysroot.by_name("core").is_none() {
anyhow::bail!(
"could not find libcore in sysroot path `{}`",
sysroot_src_dir.as_ref().display()
);
}
Ok(sysroot)
} }
fn by_name(&self, name: &str) -> Option<SysrootCrate> { fn by_name(&self, name: &str) -> Option<SysrootCrate> {

View File

@ -109,7 +109,7 @@ impl GlobalState {
) )
} }
LinkedProject::InlineJsonProject(it) => { LinkedProject::InlineJsonProject(it) => {
Ok(project_model::ProjectWorkspace::Json { project: it.clone() }) project_model::ProjectWorkspace::load_inline(it.clone())
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();