From 6370f6014a0aa905c4901c836f094b740c44ecc9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 30 Nov 2019 14:00:07 -0800 Subject: [PATCH 1/6] Implement std::error::Error for ErrorKind --- Cargo.lock | 21 +++++++++++++++++++++ Cargo.toml | 1 + src/lib.rs | 31 +++++++++++++++---------------- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b858c031432..2904057d63e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,6 +815,7 @@ dependencies = [ "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -978,6 +979,24 @@ dependencies = [ "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thiserror" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thiserror-impl 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -1190,6 +1209,8 @@ dependencies = [ "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cc6b305ec0e323c7b6cfff6098a22516e0063d0bb7c3d88660a890217dca099a" +"checksum thiserror-impl 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45ba8d810d9c48fc456b7ad54574e8bfb7c7918a57ad7a6e6a0985d7959e8597" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" diff --git a/Cargo.toml b/Cargo.toml index 0a6d6dadd5e..f20abbe319a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ structopt = "0.3" rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" } lazy_static = "1.0.0" ansi_term = "0.12" +thiserror = "1.0" # A noop dependency that changes in the Rust repository, it's a bit of a hack. # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` diff --git a/src/lib.rs b/src/lib.rs index 506059c2b5d..b68edfd6894 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,9 +15,9 @@ use std::panic; use std::path::PathBuf; use std::rc::Rc; -use failure::Fail; use ignore; use syntax::ast; +use thiserror::Error; use crate::comment::LineClasses; use crate::emitter::Emitter; @@ -81,45 +81,44 @@ pub(crate) mod visitor; /// The various errors that can occur during formatting. Note that not all of /// these can currently be propagated to clients. -#[derive(Fail, Debug)] +#[derive(Error, Debug)] pub enum ErrorKind { /// Line has exceeded character limit (found, maximum). - #[fail( - display = "line formatted, but exceeded maximum width \ - (maximum: {} (see `max_width` option), found: {})", - _1, _0 + #[error( + "line formatted, but exceeded maximum width \ + (maximum: {1} (see `max_width` option), found: {0})" )] LineOverflow(usize, usize), /// Line ends in whitespace. - #[fail(display = "left behind trailing whitespace")] + #[error("left behind trailing whitespace")] TrailingWhitespace, /// TODO or FIXME item without an issue number. - #[fail(display = "found {}", _0)] + #[error("found {0}")] BadIssue(Issue), /// License check has failed. - #[fail(display = "license check failed")] + #[error("license check failed")] LicenseCheck, /// Used deprecated skip attribute. - #[fail(display = "`rustfmt_skip` is deprecated; use `rustfmt::skip`")] + #[error("`rustfmt_skip` is deprecated; use `rustfmt::skip`")] DeprecatedAttr, /// Used a rustfmt:: attribute other than skip or skip::macros. - #[fail(display = "invalid attribute")] + #[error("invalid attribute")] BadAttr, /// An io error during reading or writing. - #[fail(display = "io error: {}", _0)] + #[error("io error: {0}")] IoError(io::Error), /// Parse error occurred when parsing the input. - #[fail(display = "parse error")] + #[error("parse error")] ParseError, /// The user mandated a version and the current version of Rustfmt does not /// satisfy that requirement. - #[fail(display = "version mismatch")] + #[error("version mismatch")] VersionMismatch, /// If we had formatted the given node, then we would have lost a comment. - #[fail(display = "not formatted because a comment would be lost")] + #[error("not formatted because a comment would be lost")] LostComment, /// Invalid glob pattern in `ignore` configuration option. - #[fail(display = "Invalid glob pattern found in ignore list: {}", _0)] + #[error("Invalid glob pattern found in ignore list: {0}")] InvalidGlobPattern(ignore::Error), } From 9fec79118c777ea105866fb469d0bf9f8499035b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 30 Nov 2019 14:08:31 -0800 Subject: [PATCH 2/6] Implement std::error::Error for error of PartialConfig::to_toml --- src/config/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 27db11c2280..21aa5c828a5 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -6,6 +6,7 @@ use std::path::{Path, PathBuf}; use std::{env, fs}; use regex::Regex; +use thiserror::Error; use crate::config::config_type::ConfigType; #[allow(unreachable_pub)] @@ -156,8 +157,12 @@ create_config! { files that would be formated when used with `--check` mode. "; } +#[derive(Error, Debug)] +#[error("Could not output config: {0}")] +pub struct ToTomlError(toml::ser::Error); + impl PartialConfig { - pub fn to_toml(&self) -> Result { + pub fn to_toml(&self) -> Result { // Non-user-facing options can't be specified in TOML let mut cloned = self.clone(); cloned.file_lines = None; @@ -165,7 +170,7 @@ impl PartialConfig { cloned.width_heuristics = None; cloned.print_misformatted_file_names = None; - ::toml::to_string(&cloned).map_err(|e| format!("Could not output config: {}", e)) + ::toml::to_string(&cloned).map_err(ToTomlError) } } From 585f123fd213af7281f71a04f0e7bc159058c461 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 30 Nov 2019 14:15:00 -0800 Subject: [PATCH 3/6] Implement std::error::Error for error of FileLines::from_str --- src/config/file_lines.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index f0dc6c66597..c76dc17a8a6 100644 --- a/src/config/file_lines.rs +++ b/src/config/file_lines.rs @@ -8,6 +8,7 @@ use std::{cmp, fmt, iter, str}; use serde::{ser, Deserialize, Deserializer, Serialize, Serializer}; use serde_json as json; +use thiserror::Error; use syntax::source_map::{self, SourceFile}; @@ -288,12 +289,20 @@ fn canonicalize_path_string(file: &FileName) -> Option { } } +#[derive(Error, Debug)] +pub enum FileLinesError { + #[error("{0}")] + Json(json::Error), + #[error("Can't canonicalize {0}")] + CannotCanonicalize(FileName), +} + // This impl is needed for `Config::override_value` to work for use in tests. impl str::FromStr for FileLines { - type Err = String; + type Err = FileLinesError; - fn from_str(s: &str) -> Result { - let v: Vec = json::from_str(s).map_err(|e| e.to_string())?; + fn from_str(s: &str) -> Result { + let v: Vec = json::from_str(s).map_err(FileLinesError::Json)?; let mut m = HashMap::new(); for js in v { let (s, r) = JsonSpan::into_tuple(js)?; @@ -311,10 +320,10 @@ pub struct JsonSpan { } impl JsonSpan { - fn into_tuple(self) -> Result<(FileName, Range), String> { + fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> { let (lo, hi) = self.range; let canonical = canonicalize_path_string(&self.file) - .ok_or_else(|| format!("Can't canonicalize {}", &self.file))?; + .ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?; Ok((canonical, Range::new(lo, hi))) } } From 67f65df90fb21880665acc05be82833fe7df6604 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 30 Nov 2019 14:04:10 -0800 Subject: [PATCH 4/6] Drop failure dependency of rustfmt bin --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/bin/main.rs | 35 ++++++++++++++++++----------------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2904057d63e..a024e7389c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,11 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "anyhow" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayref" version = "0.3.5" @@ -793,6 +798,7 @@ version = "1.4.10" dependencies = [ "annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "bytecount 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1104,6 +1110,7 @@ dependencies = [ "checksum annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7021ce4924a3f25f802b2cccd1af585e39ea1a363a1aa2e72afe54b67a3a7a7" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" diff --git a/Cargo.toml b/Cargo.toml index f20abbe319a..6970a7e0411 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ structopt = "0.3" rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" } lazy_static = "1.0.0" ansi_term = "0.12" +anyhow = "1.0" thiserror = "1.0" # A noop dependency that changes in the Rust repository, it's a bit of a hack. diff --git a/src/bin/main.rs b/src/bin/main.rs index 75102aa0673..b0e1e487cc6 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,6 +1,7 @@ +use anyhow::{format_err, Result}; use env_logger; -use failure::{err_msg, format_err, Error as FailureError, Fail}; use io::Error as IoError; +use thiserror::Error; use rustfmt_nightly as rustfmt; @@ -61,23 +62,23 @@ enum Operation { } /// Rustfmt operations errors. -#[derive(Fail, Debug)] +#[derive(Error, Debug)] pub enum OperationError { /// An unknown help topic was requested. - #[fail(display = "Unknown help topic: `{}`.", _0)] + #[error("Unknown help topic: `{0}`.")] UnknownHelpTopic(String), /// An unknown print-config option was requested. - #[fail(display = "Unknown print-config option: `{}`.", _0)] + #[error("Unknown print-config option: `{0}`.")] UnknownPrintConfigTopic(String), /// Attempt to generate a minimal config from standard input. - #[fail(display = "The `--print-config=minimal` option doesn't work with standard input.")] + #[error("The `--print-config=minimal` option doesn't work with standard input.")] MinimalPathWithStdin, /// An io error during reading or writing. - #[fail(display = "io error: {}", _0)] + #[error("io error: {0}")] IoError(IoError), /// Attempt to use --emit with a mode which is not currently /// supported with stdandard input. - #[fail(display = "Emit mode {} not supported with standard output.", _0)] + #[error("Emit mode {0} not supported with standard output.")] StdinBadEmit(EmitMode), } @@ -189,7 +190,7 @@ fn is_nightly() -> bool { } // Returned i32 is an exit code -fn execute(opts: &Options) -> Result { +fn execute(opts: &Options) -> Result { let matches = opts.parse(env::args().skip(1))?; let options = GetOptsOptions::from_matches(&matches)?; @@ -211,7 +212,7 @@ fn execute(opts: &Options) -> Result { Ok(0) } Operation::ConfigOutputDefault { path } => { - let toml = Config::default().all_options().to_toml().map_err(err_msg)?; + let toml = Config::default().all_options().to_toml()?; if let Some(path) = path { let mut file = File::create(path)?; file.write_all(toml.as_bytes())?; @@ -230,7 +231,7 @@ fn execute(opts: &Options) -> Result { let file = file.canonicalize().unwrap_or(file); let (config, _) = load_config(Some(file.parent().unwrap()), Some(options.clone()))?; - let toml = config.all_options().to_toml().map_err(err_msg)?; + let toml = config.all_options().to_toml()?; io::stdout().write_all(toml.as_bytes())?; Ok(0) @@ -243,7 +244,7 @@ fn execute(opts: &Options) -> Result { } } -fn format_string(input: String, options: GetOptsOptions) -> Result { +fn format_string(input: String, options: GetOptsOptions) -> Result { // try to read config from local directory let (mut config, _) = load_config(Some(Path::new(".")), Some(options.clone()))?; @@ -289,7 +290,7 @@ fn format( files: Vec, minimal_config_path: Option, options: &GetOptsOptions, -) -> Result { +) -> Result { options.verify_file_lines(&files); let (config, config_path) = load_config(None, Some(options.clone()))?; @@ -337,7 +338,7 @@ fn format( // that were used during formatting as TOML. if let Some(path) = minimal_config_path { let mut file = File::create(path)?; - let toml = session.config.used_options().to_toml().map_err(err_msg)?; + let toml = session.config.used_options().to_toml()?; file.write_all(toml.as_bytes())?; } @@ -521,7 +522,7 @@ fn deprecate_skip_children() { } impl GetOptsOptions { - pub fn from_matches(matches: &Matches) -> Result { + pub fn from_matches(matches: &Matches) -> Result { let mut options = GetOptsOptions::default(); options.verbose = matches.opt_present("verbose"); options.quiet = matches.opt_present("quiet"); @@ -543,7 +544,7 @@ impl GetOptsOptions { options.error_on_unformatted = Some(true); } if let Some(ref file_lines) = matches.opt_str("file-lines") { - options.file_lines = file_lines.parse().map_err(err_msg)?; + options.file_lines = file_lines.parse()?; } } else { let mut unstable_options = vec![]; @@ -686,7 +687,7 @@ impl CliOptions for GetOptsOptions { } } -fn edition_from_edition_str(edition_str: &str) -> Result { +fn edition_from_edition_str(edition_str: &str) -> Result { match edition_str { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), @@ -694,7 +695,7 @@ fn edition_from_edition_str(edition_str: &str) -> Result } } -fn emit_mode_from_emit_str(emit_str: &str) -> Result { +fn emit_mode_from_emit_str(emit_str: &str) -> Result { match emit_str { "files" => Ok(EmitMode::Files), "stdout" => Ok(EmitMode::Stdout), From e4682a267ffde6be94b6ab175e4e4353eb5c0592 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 30 Nov 2019 14:18:13 -0800 Subject: [PATCH 5/6] Drop failure dependency of format-diff --- src/format-diff/main.rs | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/format-diff/main.rs b/src/format-diff/main.rs index afe1ec5d068..a73d2da4d03 100644 --- a/src/format-diff/main.rs +++ b/src/format-diff/main.rs @@ -6,12 +6,11 @@ use env_logger; #[macro_use] -extern crate failure; -#[macro_use] extern crate log; use regex; use serde::{Deserialize, Serialize}; use serde_json as json; +use thiserror::Error; use std::collections::HashSet; use std::io::{self, BufRead}; @@ -27,32 +26,14 @@ use structopt::StructOpt; /// We only want to format rust files by default. const DEFAULT_PATTERN: &str = r".*\.rs"; -#[derive(Fail, Debug)] +#[derive(Error, Debug)] enum FormatDiffError { - #[fail(display = "{}", _0)] - IncorrectOptions(#[cause] getopts::Fail), - #[fail(display = "{}", _0)] - IncorrectFilter(#[cause] regex::Error), - #[fail(display = "{}", _0)] - IoError(#[cause] io::Error), -} - -impl From for FormatDiffError { - fn from(fail: getopts::Fail) -> Self { - FormatDiffError::IncorrectOptions(fail) - } -} - -impl From for FormatDiffError { - fn from(err: regex::Error) -> Self { - FormatDiffError::IncorrectFilter(err) - } -} - -impl From for FormatDiffError { - fn from(fail: io::Error) -> Self { - FormatDiffError::IoError(fail) - } + #[error("{0}")] + IncorrectOptions(#[from] getopts::Fail), + #[error("{0}")] + IncorrectFilter(#[from] regex::Error), + #[error("{0}")] + IoError(#[from] io::Error), } #[derive(StructOpt, Debug)] From b6b6b94f307e81b29a56e4aa58e311071bafd1d3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 30 Nov 2019 14:18:22 -0800 Subject: [PATCH 6/6] Remove failure dependency from Cargo.toml --- Cargo.lock | 1 - Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a024e7389c5..769e019faf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -804,7 +804,6 @@ dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 6970a7e0411..c654ebf36c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,6 @@ log = "0.4" env_logger = "0.6" getopts = "0.2" cargo_metadata = "0.8" -failure = "0.1.3" bytecount = "0.6" unicode-width = "0.1.5" unicode_categories = "0.1.1"