From 681ac6294ada917b8c5fbba60f9ba1c82da338aa Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 11 Sep 2020 14:48:56 +0200 Subject: Report better errors in project.json/sysroot --- crates/project_model/src/lib.rs | 32 ++++++++++++++++++++++---------- crates/project_model/src/project_json.rs | 6 +++--- crates/project_model/src/sysroot.rs | 13 ++++++++++--- crates/rust-analyzer/src/reload.rs | 2 +- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index 2d91939ce..288c39e49 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs @@ -33,7 +33,7 @@ pub enum ProjectWorkspace { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. Cargo { cargo: CargoWorkspace, sysroot: Sysroot }, /// Project workspace was manually specified using a `rust-project.json` file. - Json { project: ProjectJson }, + Json { project: ProjectJson, sysroot: Option }, } impl fmt::Debug for ProjectWorkspace { @@ -44,10 +44,10 @@ impl fmt::Debug for ProjectWorkspace { .field("n_packages", &cargo.packages().len()) .field("n_sysroot_crates", &sysroot.crates().len()) .finish(), - ProjectWorkspace::Json { project } => { + ProjectWorkspace::Json { project, sysroot } => { let mut debug_struct = f.debug_struct("Json"); 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.finish() @@ -169,7 +169,11 @@ impl ProjectWorkspace { })?; let project_location = project_json.parent().unwrap().to_path_buf(); 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) => { let cargo_version = utf8_stdout({ @@ -203,12 +207,21 @@ impl ProjectWorkspace { Ok(res) } + pub fn load_inline(project_json: ProjectJson) -> Result { + 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` /// The return type contains the path and whether or not /// the root is a member of the current workspace pub fn to_roots(&self) -> Vec { match self { - ProjectWorkspace::Json { project } => project + ProjectWorkspace::Json { project, sysroot } => project .crates() .map(|(_, krate)| PackageRoot { is_member: krate.is_workspace_member, @@ -217,7 +230,7 @@ impl ProjectWorkspace { }) .collect::>() .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 { is_member: false, include: vec![sysroot[krate].root_dir().to_path_buf()], @@ -255,7 +268,7 @@ impl ProjectWorkspace { pub fn proc_macro_dylib_paths(&self) -> Vec { match self { - ProjectWorkspace::Json { project } => project + ProjectWorkspace::Json { project, sysroot: _ } => project .crates() .filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref()) .cloned() @@ -285,9 +298,8 @@ impl ProjectWorkspace { ) -> CrateGraph { let mut crate_graph = CrateGraph::default(); match self { - ProjectWorkspace::Json { project } => { - let sysroot_dps = project - .sysroot + ProjectWorkspace::Json { project, sysroot } => { + let sysroot_dps = sysroot .as_ref() .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load)); diff --git a/crates/project_model/src/project_json.rs b/crates/project_model/src/project_json.rs index 5a0fe749a..979e90058 100644 --- a/crates/project_model/src/project_json.rs +++ b/crates/project_model/src/project_json.rs @@ -7,12 +7,12 @@ use paths::{AbsPath, AbsPathBuf}; use rustc_hash::FxHashMap; use serde::{de, Deserialize}; -use crate::{cfg_flag::CfgFlag, Sysroot}; +use crate::cfg_flag::CfgFlag; /// Roots and crates that compose this Rust project. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProjectJson { - pub(crate) sysroot: Option, + pub(crate) sysroot_src: Option, crates: Vec, } @@ -35,7 +35,7 @@ pub struct Crate { impl ProjectJson { pub fn new(base: &AbsPath, data: ProjectJsonData) -> 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 .into_iter() diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs index 74c0eda9a..871808d89 100644 --- a/crates/project_model/src/sysroot.rs +++ b/crates/project_model/src/sysroot.rs @@ -51,11 +51,11 @@ impl Sysroot { pub fn discover(cargo_toml: &AbsPath) -> Result { let current_dir = cargo_toml.parent().unwrap(); 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) } - pub fn load(sysroot_src_dir: &AbsPath) -> Sysroot { + pub fn load(sysroot_src_dir: &AbsPath) -> Result { let mut sysroot = Sysroot { crates: Arena::default() }; 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 { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 20019b944..bab6f8a71 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -109,7 +109,7 @@ impl GlobalState { ) } LinkedProject::InlineJsonProject(it) => { - Ok(project_model::ProjectWorkspace::Json { project: it.clone() }) + project_model::ProjectWorkspace::load_inline(it.clone()) } }) .collect::>(); -- cgit v1.2.3