From 003620f0d61c1c8792453294d9b2ef535afc2831 Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Wed, 8 Jan 2020 14:04:47 +0100 Subject: Use downcasting for CargoTomlNotFoundError --- crates/ra_db/src/lib.rs | 5 +-- crates/ra_lsp_server/src/main_loop.rs | 4 +- crates/ra_project_model/src/cargo_workspace.rs | 6 +-- crates/ra_project_model/src/lib.rs | 52 +++++++++++++---------- crates/ra_project_model/src/sysroot.rs | 21 ++++++---- crates/ra_project_model/src/workspace_error.rs | 57 -------------------------- 6 files changed, 48 insertions(+), 97 deletions(-) delete mode 100644 crates/ra_project_model/src/workspace_error.rs diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index db55c3bb2..21341b769 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -10,10 +10,7 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; pub use crate::{ cancellation::Canceled, - input::{ - CrateGraph, CrateId, Dependency, Edition, Env, FileId, ParseEditionError, SourceRoot, - SourceRootId, - }, + input::{CrateGraph, CrateId, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId}, }; pub use relative_path::{RelativePath, RelativePathBuf}; pub use salsa; diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 5ca37981e..53c6834d0 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -13,7 +13,6 @@ use lsp_types::{ClientCapabilities, NumberOrString}; use ra_cargo_watch::{CheckOptions, CheckTask}; use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; use ra_prof::profile; -use ra_project_model::WorkspaceError; use ra_vfs::{VfsTask, Watch}; use relative_path::RelativePathBuf; use rustc_hash::FxHashSet; @@ -92,7 +91,8 @@ pub fn main_loop( Ok(workspace) => loaded_workspaces.push(workspace), Err(e) => { log::error!("loading workspace failed: {}", e); - if let WorkspaceError::CargoTomlNotFound(_) = e { + if let Some(ra_project_model::CargoTomlNotFoundError(_)) = e.downcast_ref() + { if !feature_flags.get("notifications.cargo-toml-not-found") { continue; } diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 446ccfda0..1b3c246c7 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs @@ -8,7 +8,7 @@ use ra_db::Edition; use rustc_hash::FxHashMap; use serde::Deserialize; -use crate::WorkspaceError; +use crate::Result; /// `CargoWorkspace` represents the logical structure of, well, a Cargo /// workspace. It pretty closely mirrors `cargo metadata` output. @@ -156,7 +156,7 @@ impl CargoWorkspace { pub fn from_cargo_metadata( cargo_toml: &Path, cargo_features: &CargoFeatures, - ) -> Result { + ) -> Result { let mut meta = MetadataCommand::new(); meta.manifest_path(cargo_toml); if cargo_features.all_features { @@ -171,7 +171,7 @@ impl CargoWorkspace { if let Some(parent) = cargo_toml.parent() { meta.current_dir(parent); } - let meta = meta.exec().map_err(|e| WorkspaceError::CargoMetadataFailed(e))?; + let meta = meta.exec().map_err(|e| format!("cargo metadata failed: {}", e))?; let mut pkg_by_id = FxHashMap::default(); let mut packages = Arena::default(); let mut targets = Arena::default(); diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 2aa9270c8..e36338860 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -3,9 +3,9 @@ mod cargo_workspace; mod json_project; mod sysroot; -mod workspace_error; use std::{ + error::Error, fs::File, io::BufReader, path::{Path, PathBuf}, @@ -21,9 +21,27 @@ pub use crate::{ cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, json_project::JsonProject, sysroot::Sysroot, - workspace_error::WorkspaceError, }; +pub type Result = ::std::result::Result>; + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct CargoTomlNotFoundError(pub PathBuf); + +impl std::fmt::Display for CargoTomlNotFoundError { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(fmt, "can't find Cargo.toml at {}", self.0.display()) + } +} + +impl std::fmt::Debug for CargoTomlNotFoundError { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(fmt, "can't find Cargo.toml at {}", self.0.display()) + } +} + +impl Error for CargoTomlNotFoundError {} + #[derive(Debug, Clone)] pub enum ProjectWorkspace { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. @@ -58,10 +76,7 @@ impl PackageRoot { } impl ProjectWorkspace { - pub fn discover( - path: &Path, - cargo_features: &CargoFeatures, - ) -> Result { + pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result { ProjectWorkspace::discover_with_sysroot(path, true, cargo_features) } @@ -69,16 +84,12 @@ impl ProjectWorkspace { path: &Path, with_sysroot: bool, cargo_features: &CargoFeatures, - ) -> Result { + ) -> Result { match find_rust_project_json(path) { Some(json_path) => { - let file = - File::open(json_path).map_err(|err| WorkspaceError::OpenWorkspaceError(err))?; + let file = File::open(json_path)?; let reader = BufReader::new(file); - Ok(ProjectWorkspace::Json { - project: from_reader(reader) - .map_err(|err| WorkspaceError::ReadWorkspaceError(err))?, - }) + Ok(ProjectWorkspace::Json { project: from_reader(reader)? }) } None => { let cargo_toml = find_cargo_toml(path)?; @@ -355,7 +366,7 @@ fn find_rust_project_json(path: &Path) -> Option { None } -fn find_cargo_toml(path: &Path) -> Result { +fn find_cargo_toml(path: &Path) -> Result { if path.ends_with("Cargo.toml") { return Ok(path.to_path_buf()); } @@ -367,7 +378,7 @@ fn find_cargo_toml(path: &Path) -> Result { } curr = path.parent(); } - Err(WorkspaceError::CargoTomlNotFound(path.to_path_buf())) + Err(Box::new(CargoTomlNotFoundError(path.to_path_buf()))) } pub fn get_rustc_cfg_options() -> CfgOptions { @@ -381,16 +392,13 @@ pub fn get_rustc_cfg_options() -> CfgOptions { } } - match (|| -> Result<_, WorkspaceError> { + match (|| -> Result<_> { // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. - let output = Command::new("rustc") - .args(&["--print", "cfg", "-O"]) - .output() - .map_err(|err| WorkspaceError::RustcError(err))?; + let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?; if !output.status.success() { - Err(WorkspaceError::RustcCfgError)?; + Err("failed to get rustc cfgs")?; } - Ok(String::from_utf8(output.stdout).map_err(|err| WorkspaceError::RustcOutputError(err))?) + Ok(String::from_utf8(output.stdout)?) })() { Ok(rustc_cfgs) => { for line in rustc_cfgs.lines() { diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index 24c3f47a2..10ca391b6 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs @@ -8,7 +8,7 @@ use std::{ use ra_arena::{impl_arena_id, Arena, RawId}; -use crate::WorkspaceError; +use crate::Result; #[derive(Default, Debug, Clone)] pub struct Sysroot { @@ -47,11 +47,16 @@ impl Sysroot { self.crates.iter().map(|(id, _data)| id) } - pub fn discover(cargo_toml: &Path) -> Result { + pub fn discover(cargo_toml: &Path) -> Result { let src = try_find_src_path(cargo_toml)?; if !src.exists() { - return Err(WorkspaceError::NoStdLib(src)); + Err(format!( + "can't load standard library from sysroot\n\ + {:?}\n\ + try running `rustup component add rust-src` or set `RUST_SRC_PATH`", + src, + ))?; } let mut sysroot = Sysroot { crates: Arena::default() }; @@ -85,7 +90,7 @@ impl Sysroot { } } -fn try_find_src_path(cargo_toml: &Path) -> Result { +fn try_find_src_path(cargo_toml: &Path) -> Result { if let Ok(path) = env::var("RUST_SRC_PATH") { return Ok(path.into()); } @@ -93,13 +98,11 @@ fn try_find_src_path(cargo_toml: &Path) -> Result { let rustc_output = Command::new("rustc") .current_dir(cargo_toml.parent().unwrap()) .args(&["--print", "sysroot"]) - .output() - .map_err(|err| WorkspaceError::RustcError(err))?; + .output()?; if !rustc_output.status.success() { - Err(WorkspaceError::SysrootNotFound)?; + Err("failed to locate sysroot")?; } - let stdout = String::from_utf8(rustc_output.stdout) - .map_err(|err| WorkspaceError::RustcOutputError(err))?; + let stdout = String::from_utf8(rustc_output.stdout)?; let sysroot_path = Path::new(stdout.trim()); Ok(sysroot_path.join("lib/rustlib/src/rust/src")) } diff --git a/crates/ra_project_model/src/workspace_error.rs b/crates/ra_project_model/src/workspace_error.rs deleted file mode 100644 index 5f7384968..000000000 --- a/crates/ra_project_model/src/workspace_error.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! Workspace-related errors - -use std::{error::Error, fmt, io, path::PathBuf, string::FromUtf8Error}; - -use ra_db::ParseEditionError; - -#[derive(Debug)] -pub enum WorkspaceError { - CargoMetadataFailed(cargo_metadata::Error), - CargoTomlNotFound(PathBuf), - NoStdLib(PathBuf), - OpenWorkspaceError(io::Error), - ParseEditionError(ParseEditionError), - ReadWorkspaceError(serde_json::Error), - RustcCfgError, - RustcError(io::Error), - RustcOutputError(FromUtf8Error), - SysrootNotFound, -} - -impl fmt::Display for WorkspaceError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::OpenWorkspaceError(err) | Self::RustcError(err) => write!(f, "{}", err), - Self::ParseEditionError(err) => write!(f, "{}", err), - Self::ReadWorkspaceError(err) => write!(f, "{}", err), - Self::RustcOutputError(err) => write!(f, "{}", err), - Self::CargoMetadataFailed(err) => write!(f, "cargo metadata failed: {}", err), - Self::RustcCfgError => write!(f, "failed to get rustc cfgs"), - Self::SysrootNotFound => write!(f, "failed to locate sysroot"), - Self::CargoTomlNotFound(path) => { - write!(f, "can't find Cargo.toml at {}", path.display()) - } - Self::NoStdLib(sysroot) => write!( - f, - "can't load standard library from sysroot\n\ - {:?}\n\ - try running `rustup component add rust-src` or set `RUST_SRC_PATH`", - sysroot, - ), - } - } -} - -impl From for WorkspaceError { - fn from(err: ParseEditionError) -> Self { - Self::ParseEditionError(err.into()) - } -} - -impl From for WorkspaceError { - fn from(err: cargo_metadata::Error) -> Self { - Self::CargoMetadataFailed(err.into()) - } -} - -impl Error for WorkspaceError {} -- cgit v1.2.3