From f0ee3e15fad34d97e0db7d7c6dbc97ee8f1b102a Mon Sep 17 00:00:00 2001 From: Tom Kirchner Date: Sat, 17 Aug 2019 08:37:13 -0700 Subject: [PATCH 1/7] Remove Rust v1.18 compatibility https://github.com/shepmaster/snafu/issues/154 --- .cirrus.yml | 19 ------ Cargo.toml | 1 - compatibility-tests/v1_18/.gitignore | 3 - compatibility-tests/v1_18/Cargo.toml | 15 ----- compatibility-tests/v1_18/rust-toolchain | 1 - compatibility-tests/v1_18/src/lib.rs | 83 ------------------------ src/guide/compatibility.md | 15 ++--- 7 files changed, 4 insertions(+), 133 deletions(-) delete mode 100644 compatibility-tests/v1_18/.gitignore delete mode 100644 compatibility-tests/v1_18/Cargo.toml delete mode 100644 compatibility-tests/v1_18/rust-toolchain delete mode 100644 compatibility-tests/v1_18/src/lib.rs diff --git a/.cirrus.yml b/.cirrus.yml index 16f15191..5a37bc49 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -77,22 +77,3 @@ v1_30_test_task: - rustc --version - cargo test before_cache_script: rm -rf $CARGO_HOME/registry/index - -v1_18_test_task: - name: "Rust 1.18" - container: - # No Docker container for 1.18 - image: rust:latest - cpu: 1 - memory: 2Gi - cargo_cache: - folder: $CARGO_HOME/registry - fingerprint_script: cat Cargo.toml - setup_script: - - rustup install 1.18.0 - - rustup default 1.18.0 - primary_test_script: - - cd compatibility-tests/v1_18/ - - rustc --version - - cargo test - before_cache_script: rm -rf $CARGO_HOME/registry/index diff --git a/Cargo.toml b/Cargo.toml index f33a077c..86350edc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,6 @@ exclude = [ "compatibility-tests/compile-fail", "compatibility-tests/v1_34", "compatibility-tests/v1_30", - "compatibility-tests/v1_18", "compatibility-tests/futures-0.1", "compatibility-tests/futures", "compatibility-tests/without-backtrace", diff --git a/compatibility-tests/v1_18/.gitignore b/compatibility-tests/v1_18/.gitignore deleted file mode 100644 index 69369904..00000000 --- a/compatibility-tests/v1_18/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target -**/*.rs.bk -Cargo.lock diff --git a/compatibility-tests/v1_18/Cargo.toml b/compatibility-tests/v1_18/Cargo.toml deleted file mode 100644 index 7639094c..00000000 --- a/compatibility-tests/v1_18/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "v1_18" -version = "0.1.0" -authors = ["Jake Goulding "] - -[dependencies] -snafu = { path = "../..", default-features = false, features = ["backtraces"] } -snafu-derive = { path = "../../snafu-derive" } - -# These versions are the last versions to support Rust 1.18 -backtrace = "= 0.3.0" -backtrace-sys = "= 0.1.3" -libc = "= 0.2.7" -rustc-demangle = "= 0.1.15" -syn = "= 0.15.37" diff --git a/compatibility-tests/v1_18/rust-toolchain b/compatibility-tests/v1_18/rust-toolchain deleted file mode 100644 index 84cc5294..00000000 --- a/compatibility-tests/v1_18/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.18.0 diff --git a/compatibility-tests/v1_18/src/lib.rs b/compatibility-tests/v1_18/src/lib.rs deleted file mode 100644 index f591b977..00000000 --- a/compatibility-tests/v1_18/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![cfg(test)] - -extern crate snafu; -#[macro_use] -extern crate snafu_derive; - -use snafu::{ResultExt, Backtrace, ErrorCompat}; -use std::io; -use std::path::{Path, PathBuf}; - -#[derive(Debug, Snafu)] -struct PublicError(Error); - -#[derive(Debug, Snafu)] -enum Error { - #[snafu(display = r#"("Could not open config file at {}: {}", filename.display(), source)"#)] - OpenConfig { filename: PathBuf, source: io::Error }, - #[snafu(display = r#"("Could not open config file at {}", source)"#)] - SaveConfig { source: io::Error }, - #[snafu(display = r#"("User ID {} is invalid", user_id)"#)] - InvalidUser { user_id: i32, backtrace: Backtrace }, - #[snafu(display = r#"("No user available")"#)] - MissingUser, -} - -type Result = std::result::Result; - -const CONFIG_FILENAME: &str = "/tmp/config"; - -fn example

(root: P, user_id: Option) -> Result<()> -where - P: AsRef, -{ - let root = root.as_ref(); - let filename = &root.join(CONFIG_FILENAME); - - let config = read(filename).context(OpenConfig { filename })?; - - let _user_id = match user_id { - None => MissingUser.fail()?, - Some(user_id) if user_id != 42 => InvalidUser { user_id }.fail()?, - Some(user_id) => user_id, - }; - - write(filename, &config).context(SaveConfig)?; - - Ok(()) -} - -fn read

(path: P) -> io::Result> -where - P: AsRef, -{ - use std::fs::File; - use std::io::Read; - - let mut f = File::open(path)?; - let mut v = Vec::new(); - f.read_to_end(&mut v)?; - Ok(v) -} - -fn write

(path: P, data: &[u8]) -> io::Result<()> -where - P: AsRef, -{ - use std::fs::File; - use std::io::Write; - - let mut f = File::open(path)?; - f.write_all(data)?; - Ok(()) -} - -#[test] -fn implements_error() { - fn check() {} - check::(); - check::(); - - let e = example("/some/directory/that/does/not/exist", None).unwrap_err(); - ErrorCompat::backtrace(&e); -} diff --git a/src/guide/compatibility.md b/src/guide/compatibility.md index c3c9ff39..10fad759 100644 --- a/src/guide/compatibility.md +++ b/src/guide/compatibility.md @@ -1,7 +1,7 @@ ## Rust version compatibility -SNAFU is tested and compatible back to Rust 1.18, released on -2017-06-08. Compatibility is controlled by Cargo feature flags. +SNAFU is tested and compatible back to Rust 1.31, released on +2018-12-06. Compatibility is controlled by Cargo feature flags. ### Default @@ -9,13 +9,6 @@ SNAFU is tested and compatible back to Rust 1.18, released on release of the crate. Check the Cargo.toml for the exact version. -### No features - supports Rust 1.18 +### No features - supports Rust 1.31 -- Implements [`Error`](std::error::Error) and [`Display`](std::fmt::Display). -- Creates context selectors. - -### `rust_1_30` - supports Rust 1.30 - -- Adds an implementation for [`Error::source`](std::error::Error::source). -- Adds support for re-exporting the `Snafu` macro directly from - the `snafu` crate. +- Currently there are no feature differences required to support Rust 1.31. From 9f9fa507a1cf114e29e987796b9f07d83251d0ec Mon Sep 17 00:00:00 2001 From: Tom Kirchner Date: Sat, 17 Aug 2019 08:57:31 -0700 Subject: [PATCH 2/7] Remove the rust_1_30 feature and test for 1.31 compatibility The new minimum supported Rust version will be 1.31. This removes the rust_1_30 feature, which was used to opt into better support for higher-than-minimum versions of Rust; it's no longer needed because there we have no features that require beyond Rust 1.31. Code that was conditional on rust_1_30 is now required. Compatibility tests for 1.30 were replaced with 1.31. Background: https://github.com/shepmaster/snafu/issues/154 --- .cirrus.yml | 8 +-- Cargo.toml | 9 ++-- compatibility-tests/v1_30/Cargo.toml | 13 ----- compatibility-tests/v1_30/rust-toolchain | 1 - compatibility-tests/v1_30/src/lib.rs | 52 ------------------- .../{v1_30 => v1_31}/.gitignore | 0 compatibility-tests/v1_31/Cargo.toml | 10 ++++ compatibility-tests/v1_31/rust-toolchain | 1 + compatibility-tests/v1_31/src/lib.rs | 1 + .../without-backtrace/Cargo.toml | 2 +- snafu-derive/Cargo.toml | 1 - snafu-derive/src/lib.rs | 25 +++------ src/guide/compatibility.md | 12 +---- src/lib.rs | 6 --- 14 files changed, 30 insertions(+), 111 deletions(-) delete mode 100644 compatibility-tests/v1_30/Cargo.toml delete mode 100644 compatibility-tests/v1_30/rust-toolchain delete mode 100644 compatibility-tests/v1_30/src/lib.rs rename compatibility-tests/{v1_30 => v1_31}/.gitignore (100%) create mode 100644 compatibility-tests/v1_31/Cargo.toml create mode 100644 compatibility-tests/v1_31/rust-toolchain create mode 100644 compatibility-tests/v1_31/src/lib.rs diff --git a/.cirrus.yml b/.cirrus.yml index 5a37bc49..5311c0f5 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -63,17 +63,17 @@ v1_34_test_task: - cargo test before_cache_script: rm -rf $CARGO_HOME/registry/index -v1_30_test_task: - name: "Rust 1.30" +v1_31_test_task: + name: "Rust 1.31" container: - image: rust:1.30 + image: rust:1.31 cpu: 1 memory: 2Gi cargo_cache: folder: $CARGO_HOME/registry fingerprint_script: cat Cargo.toml primary_test_script: - - cd compatibility-tests/v1_30/ + - cd compatibility-tests/v1_31/ - rustc --version - cargo test before_cache_script: rm -rf $CARGO_HOME/registry/index diff --git a/Cargo.toml b/Cargo.toml index 86350edc..f15fc98e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ exclude = [ all-features = true [features] -default = ["rust_1_30", "backtraces"] +default = ["backtraces"] # Adds the backtrace type backtraces = ["snafu-derive/backtraces", "backtrace"] @@ -34,9 +34,6 @@ backtrace-crate = ["backtraces"] # Add extension traits for the futures 0.1 crate "futures-01" = ["futures01"] -# New methods on `Error`; re-export of proc-macro -rust_1_30 = ["snafu-derive/rust_1_30", "doc-comment"] - # The standard library's implementation of futures "unstable-futures" = ["futures-core-preview", "pin-project"] @@ -50,7 +47,7 @@ rust_1_30 = ["snafu-derive/rust_1_30", "doc-comment"] exclude = [ "compatibility-tests/compile-fail", "compatibility-tests/v1_34", - "compatibility-tests/v1_30", + "compatibility-tests/v1_31", "compatibility-tests/futures-0.1", "compatibility-tests/futures", "compatibility-tests/without-backtrace", @@ -58,9 +55,9 @@ exclude = [ [dependencies] snafu-derive = { path = "snafu-derive", version = "0.5.0" } +doc-comment = { version = "0.3.1", default-features = false } backtrace = { version = "0.3.0", optional = true } futures01 = { version = "0.1", optional = true, default-features = false } futures-preview = { version = "0.3.0-alpha.16", optional = true, default-features = false } futures-core-preview = { version = "0.3.0-alpha.16", optional = true, default-features = false } pin-project = { version = "0.3.2", optional = true, default-features = false } -doc-comment = { version = "0.3.1", optional = true, default-features = false } diff --git a/compatibility-tests/v1_30/Cargo.toml b/compatibility-tests/v1_30/Cargo.toml deleted file mode 100644 index 9bdd167e..00000000 --- a/compatibility-tests/v1_30/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "v1_30" -version = "0.1.0" -authors = ["Jake Goulding "] - -[dependencies] -snafu = { path = "../..", default-features = false, features = ["rust_1_30", "backtraces"] } - -# These versions are the last versions to support Rust 1.30 -backtrace = "= 0.3.30" -backtrace-sys = "= 0.1.28" -cc = "= 1.0.41" -rustc-demangle = "= 0.1.13" diff --git a/compatibility-tests/v1_30/rust-toolchain b/compatibility-tests/v1_30/rust-toolchain deleted file mode 100644 index 7f3c3aff..00000000 --- a/compatibility-tests/v1_30/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.30.1 diff --git a/compatibility-tests/v1_30/src/lib.rs b/compatibility-tests/v1_30/src/lib.rs deleted file mode 100644 index 54d9146b..00000000 --- a/compatibility-tests/v1_30/src/lib.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![cfg(test)] - -extern crate snafu; - -use snafu::{Snafu, ResultExt, Backtrace, ErrorCompat}; -use std::{fs, io, path::{Path, PathBuf}}; - -#[derive(Debug, Snafu)] -struct PublicError(Error); - -#[derive(Debug, Snafu)] -enum Error { - #[snafu(display = r#"("Could not open config file at {}: {}", filename.display(), source)"#)] - OpenConfig { filename: PathBuf, source: io::Error }, - #[snafu(display = r#"("Could not open config file at {}", source)"#)] - SaveConfig { source: io::Error }, - #[snafu(display = r#"("User ID {} is invalid", user_id)"#)] - InvalidUser { user_id: i32, backtrace: Backtrace }, - #[snafu(display = r#"("No user available")"#)] - MissingUser, -} - -type Result = std::result::Result; - -const CONFIG_FILENAME: &str = "/tmp/config"; - -fn example(root: impl AsRef, user_id: Option) -> Result<()> { - let root = root.as_ref(); - let filename = &root.join(CONFIG_FILENAME); - - let config = fs::read(filename).context(OpenConfig { filename })?; - - let _user_id = match user_id { - None => MissingUser.fail()?, - Some(user_id) if user_id != 42 => InvalidUser { user_id }.fail()?, - Some(user_id) => user_id, - }; - - fs::write(filename, config).context(SaveConfig)?; - - Ok(()) -} - -#[test] -fn implements_error() { - fn check() {} - check::(); - check::(); - - let e = example("/some/directory/that/does/not/exist", None).unwrap_err(); - ErrorCompat::backtrace(&e); -} diff --git a/compatibility-tests/v1_30/.gitignore b/compatibility-tests/v1_31/.gitignore similarity index 100% rename from compatibility-tests/v1_30/.gitignore rename to compatibility-tests/v1_31/.gitignore diff --git a/compatibility-tests/v1_31/Cargo.toml b/compatibility-tests/v1_31/Cargo.toml new file mode 100644 index 00000000..6783e25a --- /dev/null +++ b/compatibility-tests/v1_31/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "v1_31" +version = "0.1.0" +authors = ["Jake Goulding "] + +[dependencies] +snafu = { path = "../..", default-features = false, features = ["backtraces"] } + +# These versions are the last versions to support Rust 1.31 +backtrace = "= 0.3.35" diff --git a/compatibility-tests/v1_31/rust-toolchain b/compatibility-tests/v1_31/rust-toolchain new file mode 100644 index 00000000..34aae156 --- /dev/null +++ b/compatibility-tests/v1_31/rust-toolchain @@ -0,0 +1 @@ +1.31.0 diff --git a/compatibility-tests/v1_31/src/lib.rs b/compatibility-tests/v1_31/src/lib.rs new file mode 100644 index 00000000..a9fcf695 --- /dev/null +++ b/compatibility-tests/v1_31/src/lib.rs @@ -0,0 +1 @@ +// There are not yet any feature differences that require testing for Rust 1.31 compatibility. diff --git a/compatibility-tests/without-backtrace/Cargo.toml b/compatibility-tests/without-backtrace/Cargo.toml index a41d60d5..91e9d4e3 100644 --- a/compatibility-tests/without-backtrace/Cargo.toml +++ b/compatibility-tests/without-backtrace/Cargo.toml @@ -5,4 +5,4 @@ authors = ["Jake Goulding "] edition = "2018" [dependencies] -snafu = { path = "../..", default-features = false, features = ["rust_1_30"] } +snafu = { path = "../..", default-features = false, features = [] } diff --git a/snafu-derive/Cargo.toml b/snafu-derive/Cargo.toml index 486c8d54..162a5048 100644 --- a/snafu-derive/Cargo.toml +++ b/snafu-derive/Cargo.toml @@ -11,7 +11,6 @@ license = "MIT OR Apache-2.0" [features] backtraces = [] -rust_1_30 = [] [lib] proc-macro = true diff --git a/snafu-derive/src/lib.rs b/snafu-derive/src/lib.rs index 417773f3..10473b6b 100644 --- a/snafu-derive/src/lib.rs +++ b/snafu-derive/src/lib.rs @@ -1371,7 +1371,6 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { { type Source = #source_ty; - #[allow(unused_variables)] // Workaround Rust 1.18 bug fn into_error(self, error: Self::Source) -> #parameterized_enum_name { #enum_name::#variant_name { #source_xfer_field @@ -1551,17 +1550,13 @@ impl<'a> quote::ToTokens for ErrorImpl<'a> { } }; - let source_fn = if cfg!(feature = "rust_1_30") { - quote! { - fn source(&self) -> Option<&(std::error::Error + 'static)> { - use snafu::AsErrorSource; - match *self { - #(#variants_to_source)* - } + let source_fn = quote! { + fn source(&self) -> Option<&(std::error::Error + 'static)> { + use snafu::AsErrorSource; + match *self { + #(#variants_to_source)* } } - } else { - quote! {} }; stream.extend({ @@ -1687,14 +1682,10 @@ impl StructInfo { } }; - let source_fn = if cfg!(feature = "rust_1_30") { - quote! { - fn source(&self) -> Option<&(std::error::Error + 'static)> { - std::error::Error::source(&self.0) - } + let source_fn = quote! { + fn source(&self) -> Option<&(std::error::Error + 'static)> { + std::error::Error::source(&self.0) } - } else { - quote! {} }; let backtrace_fn = if cfg!(feature = "backtraces") { diff --git a/src/guide/compatibility.md b/src/guide/compatibility.md index 10fad759..3e8962f6 100644 --- a/src/guide/compatibility.md +++ b/src/guide/compatibility.md @@ -2,13 +2,5 @@ SNAFU is tested and compatible back to Rust 1.31, released on 2018-12-06. Compatibility is controlled by Cargo feature flags. - -### Default - -- Targets the current stable version of Rust at the time of - release of the crate. Check the Cargo.toml for the exact - version. - -### No features - supports Rust 1.31 - -- Currently there are no feature differences required to support Rust 1.31. +(There are currently no features that require Rust beyond 1.31, +and therefore no version-specific feature flags.) diff --git a/src/lib.rs b/src/lib.rs index 20bbaf3a..b6193f03 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,15 +94,11 @@ extern crate pin_project; #[cfg(feature = "unstable-futures")] pub mod futures; -#[cfg(feature = "rust_1_30")] extern crate snafu_derive; -#[cfg(feature = "rust_1_30")] pub use snafu_derive::Snafu; -#[cfg(feature = "rust_1_30")] extern crate doc_comment; -#[cfg(feature = "rust_1_30")] macro_rules! generate_guide { (pub mod $name:ident; $($rest:tt)*) => { generate_guide!(@gen ".", pub mod $name { } $($rest)*); @@ -125,7 +121,6 @@ macro_rules! generate_guide { }; } -#[cfg(feature = "rust_1_30")] generate_guide! { pub mod guide { pub mod attributes; @@ -142,7 +137,6 @@ generate_guide! { } } -#[cfg(feature = "rust_1_30")] doc_comment::doctest!("../README.md", readme_tests); use std::error; From 2d66a89febf0c1177280a7c71a70dd5ee4b2981d Mon Sep 17 00:00:00 2001 From: Tom Kirchner Date: Sat, 17 Aug 2019 09:48:20 -0700 Subject: [PATCH 3/7] Update to Rust 2018 edition Now that Rust 1.31 is the minimum version, we can update to the Rust 2018 edition and use some of its simpler idioms. This doesn't change every single location that could be simplified with Rust 2018 syntax, but does clean up via `cargo fix --edition` and remove some of the more obnoxious extra reference operators that are now implied. --- Cargo.toml | 1 + compatibility-tests/v1_31/Cargo.toml | 1 + snafu-derive/Cargo.toml | 1 + snafu-derive/src/lib.rs | 14 +++++++------- src/futures/try_future.rs | 2 +- src/futures/try_stream.rs | 2 +- src/futures01/future.rs | 2 +- src/futures01/stream.rs | 2 +- src/lib.rs | 2 +- tests/visibility.rs | 2 +- 10 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f15fc98e..0f6b2374 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "snafu" version = "0.5.0" authors = ["Jake Goulding "] +edition = "2018" readme = "README.md" description = "An ergonomic error handling library" diff --git a/compatibility-tests/v1_31/Cargo.toml b/compatibility-tests/v1_31/Cargo.toml index 6783e25a..0c3d66e8 100644 --- a/compatibility-tests/v1_31/Cargo.toml +++ b/compatibility-tests/v1_31/Cargo.toml @@ -2,6 +2,7 @@ name = "v1_31" version = "0.1.0" authors = ["Jake Goulding "] +edition = "2018" [dependencies] snafu = { path = "../..", default-features = false, features = ["backtraces"] } diff --git a/snafu-derive/Cargo.toml b/snafu-derive/Cargo.toml index 162a5048..1296c00e 100644 --- a/snafu-derive/Cargo.toml +++ b/snafu-derive/Cargo.toml @@ -2,6 +2,7 @@ name = "snafu-derive" version = "0.5.0" authors = ["Jake Goulding "] +edition = "2018" description = "An ergonomic error handling library" documentation = "https://docs.rs/snafu" diff --git a/snafu-derive/src/lib.rs b/snafu-derive/src/lib.rs index 10473b6b..c6c9616d 100644 --- a/snafu-derive/src/lib.rs +++ b/snafu-derive/src/lib.rs @@ -513,7 +513,7 @@ fn parse_snafu_enum( // `Some` value in `source_attrs`. let seen_source_from = source_attrs .iter() - .map(|&(ref val, ref _location)| val) + .map(|(val, _location)| val) .any(Option::is_some); if !v && seen_source_from { errors.add( @@ -646,7 +646,7 @@ fn parse_snafu_enum( errors.extend(errs); match (&source, &backtrace) { - (&Some(ref source), &Some(ref backtrace)) if source.0.backtrace_delegate => { + (Some(source), Some(backtrace)) if source.0.backtrace_delegate => { let source_location = source.1.clone(); let backtrace_location = backtrace.1.clone(); errors.add( @@ -1413,15 +1413,15 @@ impl<'a> DisplayImpl<'a> { } = *variant; let format = match (display_format, source_field) { - (&Some(ref v), _) => quote! { #v }, - (&None, _) if !doc_comment.is_empty() => { + (Some(ref v), _) => quote! { #v }, + (None, _) if !doc_comment.is_empty() => { quote! { #doc_comment } } - (&None, &Some(ref f)) => { + (None, Some(ref f)) => { let field_name = &f.name; quote! { concat!(stringify!(#variant_name), ": {}"), #field_name } } - (&None, &None) => quote! { stringify!(#variant_name)}, + (None, None) => quote! { stringify!(#variant_name)}, }; let field_names = user_fields @@ -1590,7 +1590,7 @@ impl<'a> ErrorCompatImpl<'a> { match (source_field, backtrace_field) { - (&Some(ref source_field), _) if source_field.backtrace_delegate => { + (Some(ref source_field), _) if source_field.backtrace_delegate => { let SourceField { name: ref field_name, .. diff --git a/src/futures/try_future.rs b/src/futures/try_future.rs index b48a2152..04adee2d 100644 --- a/src/futures/try_future.rs +++ b/src/futures/try_future.rs @@ -2,6 +2,7 @@ //! //! [`TryFuture`]: futures_core::future::TryFuture +use crate::{ErrorCompat, IntoError}; use futures_core::future::TryFuture; use pin_project::unsafe_project; use std::{ @@ -10,7 +11,6 @@ use std::{ pin::Pin, task::{Context as TaskContext, Poll}, }; -use {ErrorCompat, IntoError}; /// Additions to [`TryFuture`]. pub trait TryFutureExt: TryFuture + Sized { diff --git a/src/futures/try_stream.rs b/src/futures/try_stream.rs index b8488a1e..3af9def3 100644 --- a/src/futures/try_stream.rs +++ b/src/futures/try_stream.rs @@ -2,6 +2,7 @@ //! //! [`TryStream`]: futures_core::TryStream +use crate::{ErrorCompat, IntoError}; use futures_core::stream::{Stream, TryStream}; use pin_project::unsafe_project; use std::{ @@ -9,7 +10,6 @@ use std::{ pin::Pin, task::{Context as TaskContext, Poll}, }; -use {ErrorCompat, IntoError}; /// Additions to [`TryStream`]. pub trait TryStreamExt: TryStream + Sized { diff --git a/src/futures01/future.rs b/src/futures01/future.rs index 7a7d925a..1ee3b758 100644 --- a/src/futures01/future.rs +++ b/src/futures01/future.rs @@ -2,10 +2,10 @@ //! //! [`Future`]: futures01_crate::Future +use crate::{ErrorCompat, IntoError}; use futures01_crate::{Async, Future}; use std::error; use std::marker::PhantomData; -use {ErrorCompat, IntoError}; /// Additions to [`Future`]. pub trait FutureExt: Future + Sized { diff --git a/src/futures01/stream.rs b/src/futures01/stream.rs index 3a17d702..047ffcd6 100644 --- a/src/futures01/stream.rs +++ b/src/futures01/stream.rs @@ -2,10 +2,10 @@ //! //! [`Stream`]: futures01_crate::Stream +use crate::{ErrorCompat, IntoError}; use futures01_crate::{Async, Stream}; use std::error; use std::marker::PhantomData; -use {ErrorCompat, IntoError}; /// Additions to [`Stream`]. pub trait StreamExt: Stream + Sized { diff --git a/src/lib.rs b/src/lib.rs index b6193f03..78145763 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,7 +80,7 @@ extern crate backtrace; #[cfg(feature = "backtraces")] mod backtrace_shim; #[cfg(feature = "backtraces")] -pub use backtrace_shim::*; +pub use crate::backtrace_shim::*; #[cfg(feature = "futures-01")] extern crate futures01 as futures01_crate; diff --git a/tests/visibility.rs b/tests/visibility.rs index a4992dec..7d1ebf88 100644 --- a/tests/visibility.rs +++ b/tests/visibility.rs @@ -12,7 +12,7 @@ mod outer { PubCrate { id: i32, }, - #[snafu(visibility = "pub(in ::outer)")] + #[snafu(visibility = "pub(in crate::outer)")] PubInPath { id: i32, }, From a4c3bd492f795819f03ad920ec7c9853096fcd82 Mon Sep 17 00:00:00 2001 From: Tom Kirchner Date: Sat, 17 Aug 2019 08:33:59 -0700 Subject: [PATCH 4/7] Update to 1.0 of syn, quote, and proc-macro2 The only mandatory change is the two places we're accessing the field named "tts" on syn::Attribute, which changed to "tokens". The other changes are us following suit, changing fields and variables named "tts" to "tokens". --- snafu-derive/Cargo.toml | 6 +-- snafu-derive/src/lib.rs | 95 +++++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/snafu-derive/Cargo.toml b/snafu-derive/Cargo.toml index 1296c00e..9243d5b1 100644 --- a/snafu-derive/Cargo.toml +++ b/snafu-derive/Cargo.toml @@ -17,6 +17,6 @@ backtraces = [] proc-macro = true [dependencies] -syn = { version = "0.15.19", features = ["full"] } -quote = "0.6" -proc-macro2 = "0.4" +syn = { version = "1.0", features = ["full"] } +quote = "1.0" +proc-macro2 = "1.0" diff --git a/snafu-derive/src/lib.rs b/snafu-derive/src/lib.rs index c6c9616d..012305aa 100644 --- a/snafu-derive/src/lib.rs +++ b/snafu-derive/src/lib.rs @@ -113,12 +113,13 @@ impl SyntaxErrors { /// Adds a new syntax error. The given description will be used in the compile error pointing /// to the given span. Helper structs are available to format common descriptions, e.g. /// OnlyValidOn and DuplicateAttribute. - fn add(&mut self, tts: T, description: D) + fn add(&mut self, tokens: T, description: D) where D: fmt::Display, T: quote::ToTokens, { - self.inner.push(syn::Error::new_spanned(tts, description)); + self.inner + .push(syn::Error::new_spanned(tokens, description)); } /// Adds the given list of errors. @@ -243,18 +244,18 @@ where } } - /// Add an occurence of the attribute found at the given token tree `tts`. - fn add(&mut self, item: T, tts: U) { + /// Add an occurence of the attribute found at the given token tree `tokens`. + fn add(&mut self, item: T, tokens: U) { if !self.values.is_empty() { self.errors.add( - tts.clone(), + tokens.clone(), DuplicateAttribute { attribute: self.name, location: self.location, }, ); } - self.values.push_back((item, tts)); + self.values.push_back((item, tokens)); } #[allow(dead_code)] @@ -349,12 +350,12 @@ fn parse_snafu_enum( for attr in attributes_from_syn(attrs)? { match attr { - SnafuAttribute::Visibility(tts, v) => { - default_visibilities.add(v, tts); + SnafuAttribute::Visibility(tokens, v) => { + default_visibilities.add(v, tokens); } - SnafuAttribute::Display(tts, ..) => { + SnafuAttribute::Display(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "display", valid_on: "variants of an error enum", @@ -362,12 +363,12 @@ fn parse_snafu_enum( }, ); } - SnafuAttribute::Source(tts, ss) => { + SnafuAttribute::Source(tokens, ss) => { for s in ss { match s { Source::Flag(..) => { errors.add( - tts.clone(), + tokens.clone(), OnlyValidOn { attribute: "source(bool)", valid_on: "fields of an error variant", @@ -377,7 +378,7 @@ fn parse_snafu_enum( } Source::From(_t, _e) => { errors.add( - tts.clone(), + tokens.clone(), OnlyValidOn { attribute: "source(from)", valid_on: "fields of an error variant", @@ -388,9 +389,9 @@ fn parse_snafu_enum( } } } - SnafuAttribute::Backtrace(tts, ..) => { + SnafuAttribute::Backtrace(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "backtrace", valid_on: "fields of an error variant", @@ -419,11 +420,11 @@ fn parse_snafu_enum( for attr in attributes_from_syn(variant.attrs)? { match attr { - SnafuAttribute::Display(tts, d) => display_formats.add(d, tts), - SnafuAttribute::Visibility(tts, v) => visibilities.add(v, tts), - SnafuAttribute::Source(tts, ..) => { + SnafuAttribute::Display(tokens, d) => display_formats.add(d, tokens), + SnafuAttribute::Visibility(tokens, v) => visibilities.add(v, tokens), + SnafuAttribute::Source(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "source", valid_on: "fields of an error variant", @@ -431,9 +432,9 @@ fn parse_snafu_enum( }, ); } - SnafuAttribute::Backtrace(tts, ..) => { + SnafuAttribute::Backtrace(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "backtrace", valid_on: "fields of an error variant", @@ -504,7 +505,7 @@ fn parse_snafu_enum( for attr in attributes_from_syn(syn_field.attrs.clone())? { match attr { - SnafuAttribute::Source(tts, ss) => { + SnafuAttribute::Source(tokens, ss) => { static INCOMPATIBLE: &[&str] = &["source(false)", "source(from)"]; for s in ss { match s { @@ -517,7 +518,7 @@ fn parse_snafu_enum( .any(Option::is_some); if !v && seen_source_from { errors.add( - tts.clone(), + tokens.clone(), IncompatibleAttributes { attributes: INCOMPATIBLE, location: "a field", @@ -525,12 +526,12 @@ fn parse_snafu_enum( ); } if v { - source_attrs.add(None, tts.clone()); + source_attrs.add(None, tokens.clone()); } else if name == "source" { source_opt_out = true; } else { errors.add( - tts.clone(), + tokens.clone(), OnlyValidOn { attribute: "source(false)", valid_on: "a field named \"source\"", @@ -542,26 +543,26 @@ fn parse_snafu_enum( Source::From(t, e) => { if source_opt_out { errors.add( - tts.clone(), + tokens.clone(), IncompatibleAttributes { attributes: INCOMPATIBLE, location: "a field", }, ); } - source_attrs.add(Some((t, e)), tts.clone()); + source_attrs.add(Some((t, e)), tokens.clone()); } } } } - SnafuAttribute::Backtrace(tts, v) => { + SnafuAttribute::Backtrace(tokens, v) => { if v { - backtrace_attrs.add((), tts); + backtrace_attrs.add((), tokens); } else if name == "backtrace" { backtrace_opt_out = true; } else { errors.add( - tts, + tokens, OnlyValidOn { attribute: "backtrace(false)", valid_on: "a field named \"backtrace\"", @@ -570,9 +571,9 @@ fn parse_snafu_enum( ); } } - SnafuAttribute::Visibility(tts, ..) => { + SnafuAttribute::Visibility(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "visibility", valid_on: "an error enum and its variants", @@ -580,9 +581,9 @@ fn parse_snafu_enum( }, ); } - SnafuAttribute::Display(tts, ..) => { + SnafuAttribute::Display(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "display", valid_on: "variants of an error enum", @@ -706,9 +707,9 @@ fn parse_snafu_struct( for attr in attributes_from_syn(attrs)? { match attr { - SnafuAttribute::Display(tts, ..) => { + SnafuAttribute::Display(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "display", valid_on: "variants of an error enum", @@ -716,9 +717,9 @@ fn parse_snafu_struct( }, ); } - SnafuAttribute::Visibility(tts, ..) => { + SnafuAttribute::Visibility(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "visibility", valid_on: "an error enum and its variants", @@ -726,12 +727,12 @@ fn parse_snafu_struct( }, ); } - SnafuAttribute::Source(tts, ss) => { + SnafuAttribute::Source(tokens, ss) => { for s in ss { match s { Source::Flag(..) => { errors.add( - tts.clone(), + tokens.clone(), OnlyValidOn { attribute: "source(bool)", valid_on: "fields of an error variant", @@ -739,13 +740,13 @@ fn parse_snafu_struct( }, ); } - Source::From(t, e) => transformations.add((t, e), tts.clone()), + Source::From(t, e) => transformations.add((t, e), tokens.clone()), } } } - SnafuAttribute::Backtrace(tts, ..) => { + SnafuAttribute::Backtrace(tokens, ..) => { errors.add( - tts, + tokens, OnlyValidOn { attribute: "backtrace", valid_on: "fields of an error variant", @@ -1046,10 +1047,10 @@ impl syn::parse::Parse for DocComment { use syn::LitStr; let _: Eq = input.parse()?; - let tts = input.cursor().token_stream(); + let tokens = input.cursor().token_stream(); let doc: LitStr = input.parse()?; - Ok(DocComment(SnafuAttribute::DocComment(tts, doc.value()))) + Ok(DocComment(SnafuAttribute::DocComment(tokens, doc.value()))) } } @@ -1061,12 +1062,12 @@ fn attributes_from_syn(attrs: Vec) -> MultiSynResult(attr.tts).map(|body| body.0)) + Some(parse2::(attr.tokens).map(|body| body.0)) } else if attr.path.is_ident("doc") { // Ignore any errors that occur while parsing the doc // comment. This isn't our attribute so we shouldn't // assume that we know what values are acceptable. - parse2::(attr.tts) + parse2::(attr.tokens) .ok() .map(|comment| Ok(vec![comment.0])) } else { From 32004a53dec29bf36c15d9f58f68dd3c91b3c394 Mon Sep 17 00:00:00 2001 From: Tom Kirchner Date: Mon, 2 Sep 2019 14:20:25 -0700 Subject: [PATCH 5/7] Remove duplicate bindings needed for quote < 1.0 See "Duplicate interpolations in a repetition" in https://github.com/dtolnay/quote/releases/tag/1.0.0 --- snafu-derive/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/snafu-derive/src/lib.rs b/snafu-derive/src/lib.rs index 012305aa..be1b582c 100644 --- a/snafu-derive/src/lib.rs +++ b/snafu-derive/src/lib.rs @@ -1274,7 +1274,6 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { let selector_name = quote! { #variant_name<#(#generic_names,)*> }; let names: &Vec<_> = &user_fields.iter().map(|f| f.name.clone()).collect(); - let types = generic_names; let variant_selector_struct = { if user_fields.is_empty() { @@ -1288,7 +1287,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { quote! { #[derive(Debug, Copy, Clone)] #visibility struct #selector_name { - #( #visibilities #names: #types ),* + #( #visibilities #names: #generic_names ),* } } } @@ -1313,8 +1312,6 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { .collect(); let inherent_impl = if source_field.is_none() { - let names2 = names; - quote! { impl<#(#generic_names,)*> #selector_name { @@ -1325,7 +1322,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { let Self { #(#names),* } = self; let error = #enum_name::#variant_name { #backtrace_field - #( #names: std::convert::Into::into(#names2) ),* + #( #names: std::convert::Into::into(#names) ),* }; std::result::Result::Err(error) } From 421759f73d208ac6d92b561b141c70077683a3fe Mon Sep 17 00:00:00 2001 From: Tom Kirchner Date: Mon, 2 Sep 2019 14:35:32 -0700 Subject: [PATCH 6/7] Use `format_ident!` from quote 1.0 to simplify Ident creation See "Macro for creating an ident" in https://github.com/dtolnay/quote/releases/tag/1.0.0 --- snafu-derive/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/snafu-derive/src/lib.rs b/snafu-derive/src/lib.rs index be1b582c..3c674685 100644 --- a/snafu-derive/src/lib.rs +++ b/snafu-derive/src/lib.rs @@ -1241,9 +1241,6 @@ struct ContextSelector<'a>(&'a EnumInfo, &'a VariantInfo); impl<'a> quote::ToTokens for ContextSelector<'a> { fn to_tokens(&self, stream: &mut proc_macro2::TokenStream) { - use proc_macro2::Span; - use syn::Ident; - let enum_name = &self.0.name; let original_lifetimes = self.0.provided_generic_lifetimes(); let original_generic_types_without_defaults = @@ -1261,7 +1258,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { } = *self.1; let generic_names: &Vec<_> = &(0..user_fields.len()) - .map(|i| Ident::new(&format!("__T{}", i), Span::call_site())) + .map(|i| format_ident!("__T{}", i)) .collect(); let visibility = self From 5e41b13ba1abc52d6419d6f1a154153e9b3587ce Mon Sep 17 00:00:00 2001 From: Tom Kirchner Date: Mon, 23 Sep 2019 20:08:13 -0700 Subject: [PATCH 7/7] Remove unnecessary references from vars used in 'quote!' --- snafu-derive/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/snafu-derive/src/lib.rs b/snafu-derive/src/lib.rs index 3c674685..e88414ce 100644 --- a/snafu-derive/src/lib.rs +++ b/snafu-derive/src/lib.rs @@ -1257,7 +1257,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { .. } = *self.1; - let generic_names: &Vec<_> = &(0..user_fields.len()) + let generic_names: Vec<_> = (0..user_fields.len()) .map(|i| format_ident!("__T{}", i)) .collect(); @@ -1270,7 +1270,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { let generics_list = quote! { <#(#original_lifetimes,)* #(#generic_names,)* #(#original_generic_types_without_defaults,)*> }; let selector_name = quote! { #variant_name<#(#generic_names,)*> }; - let names: &Vec<_> = &user_fields.iter().map(|f| f.name.clone()).collect(); + let names: Vec<_> = user_fields.iter().map(|f| f.name.clone()).collect(); let variant_selector_struct = { if user_fields.is_empty() { @@ -1298,7 +1298,7 @@ impl<'a> quote::ToTokens for ContextSelector<'a> { None => quote! {}, }; - let where_clauses: &Vec<_> = &generic_names + let where_clauses: Vec<_> = generic_names .iter() .zip(user_fields) .map(|(gen_ty, f)| { @@ -1522,7 +1522,7 @@ impl<'a> quote::ToTokens for ErrorImpl<'a> { fn to_tokens(&self, stream: &mut proc_macro2::TokenStream) { let original_generics = self.0.provided_generics_without_defaults(); let parameterized_enum_name = &self.0.parameterized_name(); - let where_clauses: &Vec<_> = &self.0.provided_where_clauses(); + let where_clauses: Vec<_> = self.0.provided_where_clauses(); let variants_to_description = &self.variants_to_description(); @@ -1659,7 +1659,7 @@ impl StructInfo { let inner_type = transformation.ty(); let transformation = transformation.transformation(); - let where_clauses: &Vec<_> = &generics + let where_clauses: Vec<_> = generics .where_clause .iter() .flat_map(|c| c.predicates.iter().map(|p| quote! { #p }))