From 2202891221647c9c1a1c6bd47c0b0214b364803d Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Fri, 3 Jan 2020 14:04:46 +0100 Subject: Split errors into WorkspaceError enum --- crates/ra_db/src/lib.rs | 5 +- crates/ra_project_model/src/cargo_workspace.rs | 6 +- crates/ra_project_model/src/lib.rs | 87 +++++++++++++++++++++----- crates/ra_project_model/src/sysroot.rs | 21 +++---- 4 files changed, 89 insertions(+), 30 deletions(-) diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 21341b769..db55c3bb2 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -10,7 +10,10 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; pub use crate::{ cancellation::Canceled, - input::{CrateGraph, CrateId, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId}, + input::{ + CrateGraph, CrateId, Dependency, Edition, Env, FileId, ParseEditionError, SourceRoot, + SourceRootId, + }, }; pub use relative_path::{RelativePath, RelativePathBuf}; pub use salsa; diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 1b3c246c7..446ccfda0 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::Result; +use crate::WorkspaceError; /// `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| format!("cargo metadata failed: {}", e))?; + let meta = meta.exec().map_err(|e| WorkspaceError::CargoMetadataFailed(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 d71b7031a..49710b358 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -5,7 +5,7 @@ mod json_project; mod sysroot; use std::{ - error::Error, + fmt, fs::File, io::BufReader, path::{Path, PathBuf}, @@ -13,7 +13,7 @@ use std::{ }; use ra_cfg::CfgOptions; -use ra_db::{CrateGraph, CrateId, Edition, Env, FileId}; +use ra_db::{CrateGraph, CrateId, Edition, Env, FileId, ParseEditionError}; use rustc_hash::FxHashMap; use serde_json::from_reader; @@ -23,8 +23,57 @@ pub use crate::{ sysroot::Sysroot, }; -// FIXME use proper error enum -pub type Result = ::std::result::Result>; +#[derive(Debug)] +pub enum WorkspaceError { + CargoMetadataFailed(cargo_metadata::Error), + CargoTomlNotFound(PathBuf), + NoStdLib(PathBuf), + OpenWorkspaceError(std::io::Error), + ParseEditionError(ParseEditionError), + ReadWorkspaceError(serde_json::Error), + RustcCfgError, + RustcError(std::io::Error), + RustcOutputError(std::string::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 std::error::Error for WorkspaceError {} + +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()) + } +} #[derive(Debug, Clone)] pub enum ProjectWorkspace { @@ -60,7 +109,10 @@ 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) } @@ -68,12 +120,16 @@ 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)?; + let file = + File::open(json_path).map_err(|err| WorkspaceError::OpenWorkspaceError(err))?; let reader = BufReader::new(file); - Ok(ProjectWorkspace::Json { project: from_reader(reader)? }) + Ok(ProjectWorkspace::Json { + project: from_reader(reader) + .map_err(|err| WorkspaceError::ReadWorkspaceError(err))?, + }) } None => { let cargo_toml = find_cargo_toml(path)?; @@ -350,7 +406,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()); } @@ -362,7 +418,7 @@ fn find_cargo_toml(path: &Path) -> Result { } curr = path.parent(); } - Err(format!("can't find Cargo.toml at {}", path.display()))? + Err(WorkspaceError::CargoTomlNotFound(path.to_path_buf())) } pub fn get_rustc_cfg_options() -> CfgOptions { @@ -376,13 +432,16 @@ pub fn get_rustc_cfg_options() -> CfgOptions { } } - match (|| -> Result<_> { + match (|| -> Result<_, WorkspaceError> { // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here. - let output = Command::new("rustc").args(&["--print", "cfg", "-O"]).output()?; + let output = Command::new("rustc") + .args(&["--print", "cfg", "-O"]) + .output() + .map_err(|err| WorkspaceError::RustcError(err))?; if !output.status.success() { - Err("failed to get rustc cfgs")?; + Err(WorkspaceError::RustcCfgError)?; } - Ok(String::from_utf8(output.stdout)?) + Ok(String::from_utf8(output.stdout).map_err(|err| WorkspaceError::RustcOutputError(err))?) })() { 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 10ca391b6..24c3f47a2 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::Result; +use crate::WorkspaceError; #[derive(Default, Debug, Clone)] pub struct Sysroot { @@ -47,16 +47,11 @@ 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() { - Err(format!( - "can't load standard library from sysroot\n\ - {:?}\n\ - try running `rustup component add rust-src` or set `RUST_SRC_PATH`", - src, - ))?; + return Err(WorkspaceError::NoStdLib(src)); } let mut sysroot = Sysroot { crates: Arena::default() }; @@ -90,7 +85,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()); } @@ -98,11 +93,13 @@ 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()?; + .output() + .map_err(|err| WorkspaceError::RustcError(err))?; if !rustc_output.status.success() { - Err("failed to locate sysroot")?; + Err(WorkspaceError::SysrootNotFound)?; } - let stdout = String::from_utf8(rustc_output.stdout)?; + let stdout = String::from_utf8(rustc_output.stdout) + .map_err(|err| WorkspaceError::RustcOutputError(err))?; let sysroot_path = Path::new(stdout.trim()); Ok(sysroot_path.join("lib/rustlib/src/rust/src")) } -- cgit v1.2.3 From 6c321d7318b94ee93dc60dc88d1e68afa94e8c4f Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Fri, 3 Jan 2020 14:10:50 +0100 Subject: Move error to new file --- crates/ra_project_model/src/lib.rs | 58 ++------------------------ crates/ra_project_model/src/workspace_error.rs | 57 +++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 54 deletions(-) create mode 100644 crates/ra_project_model/src/workspace_error.rs diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 49710b358..c07c54936 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::{ - fmt, fs::File, io::BufReader, path::{Path, PathBuf}, @@ -13,68 +13,18 @@ use std::{ }; use ra_cfg::CfgOptions; -use ra_db::{CrateGraph, CrateId, Edition, Env, FileId, ParseEditionError}; +use ra_db::{CrateGraph, CrateId, Edition, Env, FileId}; use rustc_hash::FxHashMap; use serde_json::from_reader; +use crate::workspace_error::WorkspaceError; + pub use crate::{ cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, json_project::JsonProject, sysroot::Sysroot, }; -#[derive(Debug)] -pub enum WorkspaceError { - CargoMetadataFailed(cargo_metadata::Error), - CargoTomlNotFound(PathBuf), - NoStdLib(PathBuf), - OpenWorkspaceError(std::io::Error), - ParseEditionError(ParseEditionError), - ReadWorkspaceError(serde_json::Error), - RustcCfgError, - RustcError(std::io::Error), - RustcOutputError(std::string::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 std::error::Error for WorkspaceError {} - -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()) - } -} - #[derive(Debug, Clone)] pub enum ProjectWorkspace { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. diff --git a/crates/ra_project_model/src/workspace_error.rs b/crates/ra_project_model/src/workspace_error.rs new file mode 100644 index 000000000..5f7384968 --- /dev/null +++ b/crates/ra_project_model/src/workspace_error.rs @@ -0,0 +1,57 @@ +//! 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 From e7bb82c3a494e08cbcd283b8292579a9cf0bb1a3 Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Fri, 3 Jan 2020 15:04:54 +0100 Subject: Allow disabling Cargo.toml not found error --- crates/ra_ide/src/feature_flags.rs | 1 + crates/ra_lsp_server/src/main_loop.rs | 39 ++++++++++++++++++++--------------- crates/ra_project_model/src/lib.rs | 3 +-- docs/user/README.md | 2 ++ 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/crates/ra_ide/src/feature_flags.rs b/crates/ra_ide/src/feature_flags.rs index de4ae513d..85617640d 100644 --- a/crates/ra_ide/src/feature_flags.rs +++ b/crates/ra_ide/src/feature_flags.rs @@ -56,6 +56,7 @@ impl Default for FeatureFlags { ("completion.insertion.add-call-parenthesis", true), ("completion.enable-postfix", true), ("notifications.workspace-loaded", true), + ("notifications.cargo-toml-not-found", true), ]) } } diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 4336583fe..5ca37981e 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -13,6 +13,7 @@ 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; @@ -62,6 +63,22 @@ pub fn main_loop( let mut loop_state = LoopState::default(); let mut world_state = { + let feature_flags = { + let mut ff = FeatureFlags::default(); + for (flag, value) in config.feature_flags { + if ff.set(flag.as_str(), value).is_err() { + log::error!("unknown feature flag: {:?}", flag); + show_message( + req::MessageType::Error, + format!("unknown feature flag: {:?}", flag), + &connection.sender, + ); + } + } + ff + }; + log::info!("feature_flags: {:#?}", feature_flags); + // FIXME: support dynamic workspace loading. let workspaces = { let mut loaded_workspaces = Vec::new(); @@ -75,7 +92,11 @@ pub fn main_loop( Ok(workspace) => loaded_workspaces.push(workspace), Err(e) => { log::error!("loading workspace failed: {}", e); - + if let WorkspaceError::CargoTomlNotFound(_) = e { + if !feature_flags.get("notifications.cargo-toml-not-found") { + continue; + } + } show_message( req::MessageType::Error, format!("rust-analyzer failed to load workspace: {}", e), @@ -136,22 +157,6 @@ pub fn main_loop( } }; - let feature_flags = { - let mut ff = FeatureFlags::default(); - for (flag, value) in config.feature_flags { - if ff.set(flag.as_str(), value).is_err() { - log::error!("unknown feature flag: {:?}", flag); - show_message( - req::MessageType::Error, - format!("unknown feature flag: {:?}", flag), - &connection.sender, - ); - } - } - ff - }; - log::info!("feature_flags: {:#?}", feature_flags); - WorldState::new( ws_roots, workspaces, diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index c07c54936..2aa9270c8 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -17,12 +17,11 @@ use ra_db::{CrateGraph, CrateId, Edition, Env, FileId}; use rustc_hash::FxHashMap; use serde_json::from_reader; -use crate::workspace_error::WorkspaceError; - pub use crate::{ cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind}, json_project::JsonProject, sysroot::Sysroot, + workspace_error::WorkspaceError, }; #[derive(Debug, Clone)] diff --git a/docs/user/README.md b/docs/user/README.md index a4b081dbb..8cf4b68fd 100644 --- a/docs/user/README.md +++ b/docs/user/README.md @@ -118,6 +118,8 @@ host. "completion.enable-postfix": true, // Show notification when workspace is fully loaded "notifications.workspace-loaded": true, + // Show error when no Cargo.toml was found + "notifications.cargo-toml-not-found": true, } ``` -- cgit v1.2.3 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 From 738d5a7ec2e8f54e6084482c1d45abe93084cbff Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Wed, 8 Jan 2020 17:21:19 +0100 Subject: Derive debug --- crates/ra_project_model/src/lib.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index e36338860..e24801818 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -25,7 +25,7 @@ pub use crate::{ pub type Result = ::std::result::Result>; -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct CargoTomlNotFoundError(pub PathBuf); impl std::fmt::Display for CargoTomlNotFoundError { @@ -34,12 +34,6 @@ impl std::fmt::Display for CargoTomlNotFoundError { } } -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)] -- cgit v1.2.3 From 11caebe6cea4d0ec51a1b886280f8c53548eda8e Mon Sep 17 00:00:00 2001 From: Wilco Kusee Date: Wed, 8 Jan 2020 17:22:08 +0100 Subject: Remove unneeded Box::new Co-Authored-By: Aleksey Kladov --- crates/ra_project_model/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index e24801818..b7f6a9b57 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -372,7 +372,7 @@ fn find_cargo_toml(path: &Path) -> Result { } curr = path.parent(); } - Err(Box::new(CargoTomlNotFoundError(path.to_path_buf()))) + Err(CargoTomlNotFoundError(path.to_path_buf()))? } pub fn get_rustc_cfg_options() -> CfgOptions { -- cgit v1.2.3