From 7b10f6f6be3d8ce1e9bd45761d3bcb5d4ad1ac1c Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sat, 15 Jul 2023 16:51:31 +0200 Subject: [PATCH 01/11] Re-export traits This is blocked until [trait aliases are allowed][1]. Because right new we'd also export any derives from std with the same name. This showed up with the Debug derive. But if rust starts implementing more derives for their built in types in std, then the same issue would occur for other traits. [1]: https://github.com/rust-lang/rust/issues/41517 --- impl/src/add_like.rs | 2 +- impl/src/as_mut.rs | 1 - impl/src/as_ref.rs | 1 - impl/src/deref.rs | 1 - impl/src/deref_mut.rs | 1 - impl/src/error.rs | 14 +++--- impl/src/from_str.rs | 1 - impl/src/index.rs | 1 - impl/src/index_mut.rs | 1 - impl/src/into_iterator.rs | 1 - impl/src/is_variant.rs | 1 - impl/src/mul_assign_like.rs | 1 - impl/src/mul_like.rs | 1 - impl/src/sum_like.rs | 1 - impl/src/try_into.rs | 1 - impl/src/try_unwrap.rs | 1 - impl/src/unwrap.rs | 1 - impl/src/utils.rs | 22 +-------- src/fmt.rs | 2 + src/lib.rs | 98 +++++++++++++++++++++++++++++++++++-- tests/display.rs | 1 - tests/error/mod.rs | 5 -- 22 files changed, 104 insertions(+), 55 deletions(-) diff --git a/impl/src/add_like.rs b/impl/src/add_like.rs index 58296217..58076461 100644 --- a/impl/src/add_like.rs +++ b/impl/src/add_like.rs @@ -42,7 +42,7 @@ pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream { quote! { #[automatically_derived] - impl #impl_generics ::core::ops::#trait_ident for #input_type #ty_generics #where_clause { + impl #impl_generics ::derive_more::#trait_ident for #input_type #ty_generics #where_clause { type Output = #output_type; #[inline] diff --git a/impl/src/as_mut.rs b/impl/src/as_mut.rs index 2e6979a7..1d05adc5 100644 --- a/impl/src/as_mut.rs +++ b/impl/src/as_mut.rs @@ -10,7 +10,6 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result Result Result Result Option<&(dyn ::derive_more::__private::Error + 'static)> { + fn source(&self) -> Option<&(dyn ::derive_more::Error + 'static)> { use ::derive_more::__private::AsDynError; #source } @@ -73,7 +72,7 @@ pub fn expand( &generics, quote! { where - #(#bounds: ::core::fmt::Debug + ::core::fmt::Display + ::derive_more::__private::Error + 'static),* + #(#bounds: ::core::fmt::Debug + ::core::fmt::Display + ::derive_more::Error + 'static),* }, ); } @@ -82,7 +81,7 @@ pub fn expand( let render = quote! { #[automatically_derived] - impl #impl_generics ::derive_more::__private::Error for #ident #ty_generics #where_clause { + impl #impl_generics ::derive_more::Error for #ident #ty_generics #where_clause { #source #provide } @@ -120,7 +119,6 @@ fn render_enum( let state = State::from_variant( state.input, state.trait_name, - state.trait_module.clone(), state.trait_attr.clone(), allowed_attr_params(), variant, @@ -207,7 +205,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { let source_provider = self.source.map(|source| { let source_expr = &self.data.members[source]; quote! { - ::derive_more::__private::Error::provide(&#source_expr, demand); + ::derive_more::Error::provide(&#source_expr, demand); } }); let backtrace_provider = self @@ -237,7 +235,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { let pattern = self.data.matcher(&[source], &[quote! { source }]); Some(quote! { #pattern => { - ::derive_more::__private::Error::provide(source, demand); + ::derive_more::Error::provide(source, demand); } }) } @@ -249,7 +247,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { Some(quote! { #pattern => { demand.provide_ref::<::std::backtrace::Backtrace>(backtrace); - ::derive_more::__private::Error::provide(source, demand); + ::derive_more::Error::provide(source, demand); } }) } diff --git a/impl/src/from_str.rs b/impl/src/from_str.rs index 0d3773dd..aefd670c 100644 --- a/impl/src/from_str.rs +++ b/impl/src/from_str.rs @@ -9,7 +9,6 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result Result Result Result Result Result Result Result Result Result Result { pub trait_name: &'static str, pub trait_ident: Ident, pub method_ident: Ident, - pub trait_module: TokenStream, pub trait_path: TokenStream, pub trait_path_params: Vec, pub trait_attr: String, @@ -314,13 +313,11 @@ impl<'input> State<'input> { pub fn new<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, AttrParams::default(), true, @@ -330,13 +327,11 @@ impl<'input> State<'input> { pub fn with_field_ignore<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, AttrParams::new(vec!["ignore"]), true, @@ -346,13 +341,11 @@ impl<'input> State<'input> { pub fn with_field_ignore_and_forward<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, AttrParams::new(vec!["ignore", "forward"]), true, @@ -362,13 +355,11 @@ impl<'input> State<'input> { pub fn with_field_ignore_and_refs<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, AttrParams::new(vec!["ignore", "owned", "ref", "ref_mut"]), true, @@ -378,14 +369,12 @@ impl<'input> State<'input> { pub fn with_attr_params<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, allowed_attr_params, true, @@ -395,7 +384,6 @@ impl<'input> State<'input> { pub fn with_type_bound<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, add_type_bound: bool, @@ -403,7 +391,6 @@ impl<'input> State<'input> { Self::new_impl( input, trait_name, - trait_module, trait_attr, allowed_attr_params, add_type_bound, @@ -413,7 +400,6 @@ impl<'input> State<'input> { fn new_impl<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, add_type_bound: bool, @@ -421,7 +407,7 @@ impl<'input> State<'input> { let trait_name = trait_name.trim_end_matches("ToInner"); let trait_ident = format_ident!("{trait_name}"); let method_ident = format_ident!("{trait_attr}"); - let trait_path = quote! { #trait_module::#trait_ident }; + let trait_path = quote! { ::derive_more::#trait_ident }; let (derive_type, fields, variants): (_, Vec<_>, Vec<_>) = match input.data { Data::Struct(ref data_struct) => match data_struct.fields { Fields::Unnamed(ref fields) => { @@ -516,7 +502,6 @@ impl<'input> State<'input> { State::from_variant( input, trait_name, - trait_module.clone(), trait_attr.clone(), allowed_attr_params.clone(), variant, @@ -539,7 +524,6 @@ impl<'input> State<'input> { trait_name, trait_ident, method_ident, - trait_module, trait_path, trait_path_params: vec![], trait_attr, @@ -558,7 +542,6 @@ impl<'input> State<'input> { pub fn from_variant<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, variant: &'arg_input Variant, @@ -567,7 +550,7 @@ impl<'input> State<'input> { let trait_name = trait_name.trim_end_matches("ToInner"); let trait_ident = format_ident!("{trait_name}"); let method_ident = format_ident!("{trait_attr}"); - let trait_path = quote! { #trait_module::#trait_ident }; + let trait_path = quote! { ::derive_more::#trait_ident }; let (derive_type, fields): (_, Vec<_>) = match variant.fields { Fields::Unnamed(ref fields) => { (DeriveType::Unnamed, unnamed_to_vec(fields)) @@ -593,7 +576,6 @@ impl<'input> State<'input> { Ok(State { input, trait_name, - trait_module, trait_path, trait_path_params: vec![], trait_attr, diff --git a/src/fmt.rs b/src/fmt.rs index 311bfb77..80d7a774 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -1,6 +1,8 @@ //! [`core::fmt::DebugTuple`] reimplementation with //! [`DebugTuple::finish_non_exhaustive()`] method. +use ::core; +use core::prelude::v1::*; use core::fmt::{Debug, Formatter, Result, Write}; /// Same as [`core::fmt::DebugTuple`], but with diff --git a/src/lib.rs b/src/lib.rs index 19b642a8..0ccdf88a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,11 +77,6 @@ mod vendor; // Not public API. #[doc(hidden)] pub mod __private { - #[cfg(all(feature = "error", not(feature = "std")))] - pub use ::core::error::Error; - #[cfg(all(feature = "error", feature = "std"))] - pub use ::std::error::Error; - #[cfg(feature = "error")] pub use crate::vendor::thiserror::aserror::AsDynError; @@ -89,6 +84,99 @@ pub mod __private { pub use crate::fmt::{debug_tuple, DebugTuple}; } +// re-export all the traits for easy usage. But hide their docs because otherwise they clutter +// the actual docs +#[cfg(feature = "add")] +#[doc(hidden)] +pub use core::ops::{Add, BitAnd, BitOr, BitXor, Sub}; + +#[cfg(feature = "add_assign")] +#[doc(hidden)] +pub use core::ops::{AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign}; + +#[cfg(feature = "as_ref")] +#[doc(hidden)] +pub use core::convert::AsRef; + +#[cfg(feature = "as_mut")] +#[doc(hidden)] +pub use core::convert::AsMut; + +// XXX: Uncommenting this causes our own derive to not be visible anymore, because the derive +// from std takes precedence somehow. +// #[cfg(feature = "debug")] +// #[doc(hidden)] +// pub use core::fmt::Debug; + +#[cfg(feature = "deref")] +#[doc(hidden)] +pub use core::ops::Deref; + +#[cfg(feature = "deref_mut")] +#[doc(hidden)] +pub use core::ops::DerefMut; + +#[cfg(feature = "display")] +#[doc(hidden)] +pub use core::fmt::{ + Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, +}; + +#[cfg(all(feature = "error", not(feature = "std")))] +#[doc(hidden)] +pub use core::error::Error; +#[cfg(all(feature = "error", feature = "std"))] +#[doc(hidden)] +pub use std::error::Error; + +#[cfg(feature = "from")] +#[doc(hidden)] +pub use core::convert::From; + +#[cfg(feature = "from_str")] +#[doc(hidden)] +pub use core::str::FromStr; + +#[cfg(feature = "index")] +#[doc(hidden)] +pub use core::ops::Index; + +#[cfg(feature = "index_mut")] +#[doc(hidden)] +pub use core::ops::IndexMut; + +#[cfg(feature = "into")] +#[doc(hidden)] +pub use core::convert::Into; + +#[cfg(feature = "into_iterator")] +#[doc(hidden)] +pub use core::iter::IntoIterator; + +#[cfg(feature = "iterator")] +#[doc(hidden)] +pub use core::iter::Iterator; + +#[cfg(feature = "mul")] +#[doc(hidden)] +pub use core::ops::{Div, Mul, Rem, Shl, Shr}; + +#[cfg(feature = "mul_assign")] +#[doc(hidden)] +pub use core::ops::{DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign}; + +#[cfg(feature = "not")] +#[doc(hidden)] +pub use core::ops::{Neg, Not}; + +#[cfg(feature = "sum")] +#[doc(hidden)] +pub use core::iter::{Product, Sum}; + +#[cfg(feature = "try_into")] +#[doc(hidden)] +pub use core::convert::TryInto; + #[cfg(not(any( feature = "full", feature = "add_assign", diff --git a/tests/display.rs b/tests/display.rs index 8683c8c3..cab2c047 100644 --- a/tests/display.rs +++ b/tests/display.rs @@ -11,7 +11,6 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; -use core::fmt::{Binary, Display}; use derive_more::{Binary, Display, Octal, UpperHex}; diff --git a/tests/error/mod.rs b/tests/error/mod.rs index a041ec17..352d40aa 100644 --- a/tests/error/mod.rs +++ b/tests/error/mod.rs @@ -1,8 +1,3 @@ -#[cfg(not(feature = "std"))] -use core::error::Error; -#[cfg(feature = "std")] -use std::error::Error; - use derive_more::Error; /// Derives `std::fmt::Display` for structs/enums. From a5a7809ce8888eea58e88d7dd26f8c7b346a62f5 Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 20 Jul 2023 13:52:31 +0300 Subject: [PATCH 02/11] Refactor to gimmicking `std` definitions --- Cargo.toml | 8 +- impl/Cargo.toml | 9 +- impl/src/deref_mut.rs | 7 +- impl/src/from_str.rs | 6 +- impl/src/index.rs | 7 +- impl/src/index_mut.rs | 6 +- impl/src/into_iterator.rs | 7 +- impl/src/sum_like.rs | 6 +- impl/src/utils.rs | 16 +-- src/fmt.rs | 2 +- src/lib.rs | 279 ++++++++++++++++++++++++++------------ 11 files changed, 212 insertions(+), 141 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 32999fb7..961de47e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,6 @@ index = ["derive_more-impl/index"] index_mut = ["derive_more-impl/index_mut"] into = ["derive_more-impl/into"] into_iterator = ["derive_more-impl/into_iterator"] -iterator = ["derive_more-impl/iterator"] mul_assign = ["derive_more-impl/mul_assign"] mul = ["derive_more-impl/mul"] not = ["derive_more-impl/not"] @@ -73,8 +72,8 @@ try_unwrap = ["derive_more-impl/try_unwrap"] std = [] full = [ - "add_assign", "add", + "add_assign", "as_mut", "as_ref", "constructor", @@ -90,14 +89,13 @@ full = [ "into", "into_iterator", "is_variant", - "iterator", - "mul_assign", "mul", + "mul_assign", "not", "sum", "try_into", - "unwrap", "try_unwrap", + "unwrap", ] testing-helpers = ["derive_more-impl/testing-helpers", "dep:rustc_version"] diff --git a/impl/Cargo.toml b/impl/Cargo.toml index 51719c39..2760eed3 100644 --- a/impl/Cargo.toml +++ b/impl/Cargo.toml @@ -45,8 +45,8 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = [] -add_assign = [] add = [] +add_assign = [] as_mut = [] as_ref = [] constructor = [] @@ -61,14 +61,13 @@ index = [] index_mut = [] into = ["syn/extra-traits"] into_iterator = [] -iterator = [] -mul_assign = ["syn/extra-traits"] +is_variant = ["dep:convert_case"] mul = ["syn/extra-traits"] +mul_assign = ["syn/extra-traits"] not = ["syn/extra-traits"] sum = [] try_into = ["syn/extra-traits"] -is_variant = ["dep:convert_case"] -unwrap = ["dep:convert_case"] try_unwrap = ["dep:convert_case"] +unwrap = ["dep:convert_case"] testing-helpers = ["dep:rustc_version"] diff --git a/impl/src/deref_mut.rs b/impl/src/deref_mut.rs index 59adbabd..2d7a79db 100644 --- a/impl/src/deref_mut.rs +++ b/impl/src/deref_mut.rs @@ -5,11 +5,8 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(DerefMut)]` into an implementation of `DerefMut` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { - let state = State::with_field_ignore_and_forward( - input, - trait_name, - "deref_mut".into(), - )?; + let state = + State::with_field_ignore_and_forward(input, trait_name, "deref_mut".into())?; let SingleFieldData { input_type, trait_path, diff --git a/impl/src/from_str.rs b/impl/src/from_str.rs index aefd670c..bc0ec541 100644 --- a/impl/src/from_str.rs +++ b/impl/src/from_str.rs @@ -6,11 +6,7 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(FromStr)]` into an implementation of `FromStr` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { - let state = State::new( - input, - trait_name, - trait_name.to_lowercase(), - )?; + let state = State::new(input, trait_name, trait_name.to_lowercase())?; if state.derive_type == DeriveType::Enum { Ok(enum_from(input, state, trait_name)) diff --git a/impl/src/index.rs b/impl/src/index.rs index e006e4b2..bf4f0d7b 100644 --- a/impl/src/index.rs +++ b/impl/src/index.rs @@ -6,11 +6,8 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(Index)]` into an implementation of `Index` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { let index_type = format_ident!("__IdxT"); - let mut state = State::with_field_ignore( - input, - trait_name, - trait_name.to_lowercase(), - )?; + let mut state = + State::with_field_ignore(input, trait_name, trait_name.to_lowercase())?; state.add_trait_path_type_param(quote! { #index_type }); let SingleFieldData { field, diff --git a/impl/src/index_mut.rs b/impl/src/index_mut.rs index 3ddefab3..0e030cf6 100644 --- a/impl/src/index_mut.rs +++ b/impl/src/index_mut.rs @@ -6,11 +6,7 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(IndexMut)]` into an implementation of `IndexMut` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { let index_type = format_ident!("__IdxT"); - let mut state = State::with_field_ignore( - input, - trait_name, - "index_mut".into(), - )?; + let mut state = State::with_field_ignore(input, trait_name, "index_mut".into())?; state.add_trait_path_type_param(quote! { #index_type }); let SingleFieldData { field, diff --git a/impl/src/into_iterator.rs b/impl/src/into_iterator.rs index 52ad0148..f10dbf7a 100644 --- a/impl/src/into_iterator.rs +++ b/impl/src/into_iterator.rs @@ -7,11 +7,8 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(IntoIterator)]` into an implementation of `IntoIterator` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { - let state = State::with_field_ignore_and_refs( - input, - trait_name, - "into_iterator".into(), - )?; + let state = + State::with_field_ignore_and_refs(input, trait_name, "into_iterator".into())?; let SingleFieldData { input_type, info, diff --git a/impl/src/sum_like.rs b/impl/src/sum_like.rs index c68daf5f..97d73fce 100644 --- a/impl/src/sum_like.rs +++ b/impl/src/sum_like.rs @@ -6,11 +6,7 @@ use quote::{format_ident, quote}; use syn::{DeriveInput, Result}; pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { - let state = State::new( - input, - trait_name, - trait_name.to_lowercase(), - )?; + let state = State::new(input, trait_name, trait_name.to_lowercase())?; let multi_field_data = state.enabled_fields_data(); let MultiFieldData { input_type, diff --git a/impl/src/utils.rs b/impl/src/utils.rs index 03fe7af7..9523591b 100644 --- a/impl/src/utils.rs +++ b/impl/src/utils.rs @@ -315,13 +315,7 @@ impl<'input> State<'input> { trait_name: &'static str, trait_attr: String, ) -> Result> { - State::new_impl( - input, - trait_name, - trait_attr, - AttrParams::default(), - true, - ) + State::new_impl(input, trait_name, trait_attr, AttrParams::default(), true) } pub fn with_field_ignore<'arg_input>( @@ -372,13 +366,7 @@ impl<'input> State<'input> { trait_attr: String, allowed_attr_params: AttrParams, ) -> Result> { - State::new_impl( - input, - trait_name, - trait_attr, - allowed_attr_params, - true, - ) + State::new_impl(input, trait_name, trait_attr, allowed_attr_params, true) } pub fn with_type_bound<'arg_input>( diff --git a/src/fmt.rs b/src/fmt.rs index 80d7a774..0acd4ca2 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -2,8 +2,8 @@ //! [`DebugTuple::finish_non_exhaustive()`] method. use ::core; -use core::prelude::v1::*; use core::fmt::{Debug, Formatter, Result, Write}; +use core::prelude::v1::*; /// Same as [`core::fmt::DebugTuple`], but with /// [`DebugTuple::finish_non_exhaustive()`] method. diff --git a/src/lib.rs b/src/lib.rs index 0ccdf88a..00114323 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,140 +47,248 @@ #![forbid(non_ascii_idents, unsafe_code)] #![warn(clippy::nonstandard_macro_braces)] -#[doc(inline)] -pub use derive_more_impl::*; - -#[cfg(feature = "try_into")] -mod convert; -#[cfg(feature = "try_into")] -pub use self::convert::TryIntoError; - -#[cfg(feature = "try_unwrap")] -mod try_unwrap; -#[cfg(feature = "try_unwrap")] -pub use self::try_unwrap::TryUnwrapError; - -#[cfg(feature = "debug")] -mod fmt; - -#[cfg(any(feature = "add", feature = "not"))] -pub mod ops; - -#[cfg(feature = "from_str")] -mod r#str; -#[cfg(feature = "from_str")] -pub use self::r#str::FromStrError; - -#[cfg(feature = "error")] -mod vendor; - -// Not public API. +// Not public, but exported API. For macro expansion internals only. #[doc(hidden)] pub mod __private { + #[cfg(feature = "debug")] + pub use crate::fmt::{debug_tuple, DebugTuple}; + #[cfg(feature = "error")] pub use crate::vendor::thiserror::aserror::AsDynError; +} - #[cfg(feature = "debug")] - pub use crate::fmt::{debug_tuple, DebugTuple}; +/// Module containing macro definitions only, without corresponding traits. +/// +/// Use it in your import paths, if you don't want to import traits, but only macros. +pub mod macros { + #[doc(inline)] + pub use derive_more_impl::*; } -// re-export all the traits for easy usage. But hide their docs because otherwise they clutter -// the actual docs +#[cfg(any(feature = "add", feature = "not"))] +pub mod ops; #[cfg(feature = "add")] -#[doc(hidden)] -pub use core::ops::{Add, BitAnd, BitOr, BitXor, Sub}; +mod gimmick_add { + pub use crate::macros::{Add, BitAnd, BitOr, BitXor, Sub}; + pub use core::ops::*; +} +#[cfg(feature = "add")] +#[doc(inline)] +pub use self::gimmick_add::{Add, BitAnd, BitOr, BitXor, Sub}; #[cfg(feature = "add_assign")] -#[doc(hidden)] -pub use core::ops::{AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign}; +mod gimmick_add_assign { + pub use crate::macros::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign, + }; + pub use core::ops::*; +} +#[cfg(feature = "add_assign")] +#[doc(inline)] +pub use self::gimmick_add_assign::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign, +}; + +#[cfg(feature = "as_mut")] +mod gimmick_as_mut { + pub use crate::macros::AsMut; + pub use core::convert::*; +} +#[cfg(feature = "as_mut")] +#[doc(inline)] +pub use self::gimmick_as_mut::AsMut; #[cfg(feature = "as_ref")] -#[doc(hidden)] -pub use core::convert::AsRef; +mod gimmick_as_ref { + pub use crate::macros::AsRef; + pub use core::convert::*; +} +#[cfg(feature = "as_ref")] +#[doc(inline)] +pub use self::gimmick_as_ref::AsRef; -#[cfg(feature = "as_mut")] -#[doc(hidden)] -pub use core::convert::AsMut; +#[cfg(feature = "constructor")] +#[doc(inline)] +pub use self::macros::Constructor; -// XXX: Uncommenting this causes our own derive to not be visible anymore, because the derive -// from std takes precedence somehow. -// #[cfg(feature = "debug")] -// #[doc(hidden)] -// pub use core::fmt::Debug; +#[cfg(feature = "debug")] +mod fmt; +#[cfg(feature = "debug")] +mod gimmick_debug { + pub use crate::macros::Debug; + pub use core::fmt::*; +} +#[cfg(feature = "debug")] +#[doc(inline)] +pub use self::gimmick_debug::Debug; #[cfg(feature = "deref")] -#[doc(hidden)] -pub use core::ops::Deref; +mod gimmick_deref { + pub use crate::macros::Deref; + pub use core::ops::*; +} +#[cfg(feature = "deref")] +#[doc(inline)] +pub use self::gimmick_deref::Deref; #[cfg(feature = "deref_mut")] -#[doc(hidden)] -pub use core::ops::DerefMut; +mod gimmick_deref_mut { + pub use crate::macros::DerefMut; + pub use core::ops::*; +} +#[cfg(feature = "deref_mut")] +#[doc(inline)] +pub use self::gimmick_deref_mut::DerefMut; #[cfg(feature = "display")] -#[doc(hidden)] -pub use core::fmt::{ +mod gimmick_display { + pub use crate::macros::{ + Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, + }; + pub use core::fmt::*; +} +#[cfg(feature = "display")] +#[doc(inline)] +pub use self::gimmick_display::{ Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, }; -#[cfg(all(feature = "error", not(feature = "std")))] -#[doc(hidden)] -pub use core::error::Error; -#[cfg(all(feature = "error", feature = "std"))] -#[doc(hidden)] -pub use std::error::Error; +#[cfg(feature = "error")] +mod vendor; +#[cfg(feature = "error")] +mod gimmick_error { + pub use crate::macros::Error; + #[cfg(not(feature = "std"))] + pub use core::error::*; + #[cfg(feature = "std")] + pub use std::error::*; +} +#[cfg(feature = "error")] +pub use self::gimmick_error::Error; #[cfg(feature = "from")] -#[doc(hidden)] -pub use core::convert::From; +mod gimmick_from { + pub use crate::macros::From; + pub use core::convert::*; +} +#[cfg(feature = "from")] +#[doc(inline)] +pub use self::gimmick_from::From; +#[cfg(feature = "from_str")] +mod r#str; +#[cfg(feature = "from_str")] +mod gimmick_from_str { + pub use crate::{macros::FromStr, r#str::FromStrError}; + pub use core::str::*; +} #[cfg(feature = "from_str")] #[doc(hidden)] -pub use core::str::FromStr; +pub use self::gimmick_from_str::{FromStr, FromStrError}; #[cfg(feature = "index")] -#[doc(hidden)] -pub use core::ops::Index; +mod gimmick_index { + pub use crate::macros::Index; + pub use core::ops::*; +} +#[cfg(feature = "index")] +#[doc(inline)] +pub use self::gimmick_index::Index; #[cfg(feature = "index_mut")] -#[doc(hidden)] -pub use core::ops::IndexMut; +mod gimmick_index_mut { + pub use crate::macros::IndexMut; + pub use core::ops::*; +} +#[cfg(feature = "index_mut")] +#[doc(inline)] +pub use self::gimmick_index_mut::IndexMut; #[cfg(feature = "into")] -#[doc(hidden)] -pub use core::convert::Into; +mod gimmick_into { + pub use crate::macros::Into; + pub use core::convert::*; +} +#[cfg(feature = "into")] +#[doc(inline)] +pub use self::gimmick_into::Into; #[cfg(feature = "into_iterator")] -#[doc(hidden)] -pub use core::iter::IntoIterator; +mod gimmick_into_iterator { + pub use crate::macros::IntoIterator; + pub use core::iter::*; +} +#[cfg(feature = "into_iterator")] +#[doc(inline)] +pub use self::gimmick_into_iterator::IntoIterator; -#[cfg(feature = "iterator")] -#[doc(hidden)] -pub use core::iter::Iterator; +#[cfg(feature = "is_variant")] +#[doc(inline)] +pub use self::macros::IsVariant; #[cfg(feature = "mul")] -#[doc(hidden)] -pub use core::ops::{Div, Mul, Rem, Shl, Shr}; +mod gimmick_mul { + pub use crate::macros::{Div, Mul, Rem, Shl, Shr}; + pub use core::ops::*; +} +#[cfg(feature = "mul")] +#[doc(inline)] +pub use self::gimmick_mul::{Div, Mul, Rem, Shl, Shr}; #[cfg(feature = "mul_assign")] -#[doc(hidden)] -pub use core::ops::{DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign}; +mod gimmick_mul_assign { + pub use crate::macros::{DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign}; + pub use core::ops::*; +} +#[cfg(feature = "mul_assign")] +#[doc(inline)] +pub use self::gimmick_mul_assign::{ + DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign, +}; #[cfg(feature = "not")] -#[doc(hidden)] -pub use core::ops::{Neg, Not}; +mod gimmick_not { + pub use crate::macros::{Neg, Not}; + pub use core::ops::*; +} +#[cfg(feature = "not")] +#[doc(inline)] +pub use self::gimmick_not::{Neg, Not}; #[cfg(feature = "sum")] -#[doc(hidden)] -pub use core::iter::{Product, Sum}; +mod gimmick_sum { + pub use crate::macros::{Product, Sum}; + pub use core::iter::*; +} +#[cfg(feature = "sum")] +#[doc(inline)] +pub use self::gimmick_sum::{Product, Sum}; #[cfg(feature = "try_into")] -#[doc(hidden)] -pub use core::convert::TryInto; +mod convert; +#[cfg(feature = "try_into")] +mod gimmick_try_into { + pub use crate::{convert::TryIntoError, macros::TryInto}; + pub use core::convert::*; +} +#[cfg(feature = "try_into")] +#[doc(inline)] +pub use self::gimmick_try_into::{TryInto, TryIntoError}; + +#[cfg(feature = "try_unwrap")] +mod try_unwrap; +#[cfg(feature = "try_unwrap")] +#[doc(inline)] +pub use self::{macros::TryUnwrap, try_unwrap::TryUnwrapError}; + +#[cfg(feature = "unwrap")] +#[doc(inline)] +pub use self::macros::Unwrap; #[cfg(not(any( feature = "full", - feature = "add_assign", feature = "add", + feature = "add_assign", feature = "as_mut", feature = "as_ref", feature = "constructor", @@ -196,14 +304,13 @@ pub use core::convert::TryInto; feature = "into", feature = "into_iterator", feature = "is_variant", - feature = "iterator", - feature = "mul_assign", feature = "mul", + feature = "mul_assign", feature = "not", feature = "sum", feature = "try_into", - feature = "unwrap", feature = "try_unwrap", + feature = "unwrap", )))] compile_error!( "at least one derive feature must be enabled (or the \"full\" one enabling all the derives)" From 2efe373cf22d2ae9834071102e0fc52dba9d67e6 Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 20 Jul 2023 14:08:11 +0300 Subject: [PATCH 03/11] Fix doc tests --- impl/Cargo.toml | 2 +- impl/doc/display.md | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/impl/Cargo.toml b/impl/Cargo.toml index 2760eed3..a1874637 100644 --- a/impl/Cargo.toml +++ b/impl/Cargo.toml @@ -33,7 +33,7 @@ unicode-xid = { version = "0.2.2", optional = true } rustc_version = { version = "0.4", optional = true } [dev-dependencies] -derive_more = { path = "..", features = ["add", "debug", "error", "from_str", "not", "std", "try_into", "try_unwrap"] } +derive_more = { path = "..", features = ["full"] } itertools = "0.11.0" [badges] diff --git a/impl/doc/display.md b/impl/doc/display.md index 64782124..5b616ca4 100644 --- a/impl/doc/display.md +++ b/impl/doc/display.md @@ -86,8 +86,6 @@ Note how we have to bound `U` and `V` by `Display` in the following example, as Not even `Display`. ```rust -# use std::fmt::Display; -# # use derive_more::Display; # # trait MyTrait { fn my_function(&self) -> i32; } From e2ecaf1bd414c9b7a7d06611811c2cb1c18fe230 Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 20 Jul 2023 14:14:32 +0300 Subject: [PATCH 04/11] Mention in CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1105d765..be797ccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). and ignores field type itself. - The `Into` derive now uses `#[into()]` instead of `#[into(types())]` and ignores field type itself. +- Importing derive macro now also import its corresponding trait. To import macro only, + `macros` module should be used. ### Added From 69cc221ed361aae515c2cffac5ac628b2db169c3 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 03:36:52 +0200 Subject: [PATCH 05/11] Re-order create_derive! macro calls --- impl/src/lib.rs | 144 +++++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 70 deletions(-) diff --git a/impl/src/lib.rs b/impl/src/lib.rs index 8c028fe6..0d042cc6 100644 --- a/impl/src/lib.rs +++ b/impl/src/lib.rs @@ -108,27 +108,12 @@ macro_rules! create_derive( } ); -create_derive!("from", from, From, from_derive, from); - -create_derive!("into", into, Into, into_derive, into); - -create_derive!("constructor", constructor, Constructor, constructor_derive); - -create_derive!("not", not_like, Not, not_derive); -create_derive!("not", not_like, Neg, neg_derive); - create_derive!("add", add_like, Add, add_derive); create_derive!("add", add_like, Sub, sub_derive); create_derive!("add", add_like, BitAnd, bit_and_derive); create_derive!("add", add_like, BitOr, bit_or_derive); create_derive!("add", add_like, BitXor, bit_xor_derive); -create_derive!("mul", mul_like, Mul, mul_derive, mul); -create_derive!("mul", mul_like, Div, div_derive, div); -create_derive!("mul", mul_like, Rem, rem_derive, rem); -create_derive!("mul", mul_like, Shr, shr_derive, shr); -create_derive!("mul", mul_like, Shl, shl_derive, shl); - create_derive!("add_assign", add_assign_like, AddAssign, add_assign_derive,); create_derive!("add_assign", add_assign_like, SubAssign, sub_assign_derive,); create_derive!( @@ -150,51 +135,24 @@ create_derive!( bit_xor_assign_derive, ); -create_derive!( - "mul_assign", - mul_assign_like, - MulAssign, - mul_assign_derive, - mul_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - DivAssign, - div_assign_derive, - div_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - RemAssign, - rem_assign_derive, - rem_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - ShrAssign, - shr_assign_derive, - shr_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - ShlAssign, - shl_assign_derive, - shl_assign, -); - -create_derive!("sum", sum_like, Sum, sum_derive); -create_derive!("sum", sum_like, Product, product_derive); +create_derive!("as_mut", as_mut, AsMut, as_mut_derive, as_mut); -create_derive!("error", error, Error, error_derive, error); +create_derive!("as_ref", as_ref, AsRef, as_ref_derive, as_ref); -create_derive!("from_str", from_str, FromStr, from_str_derive); +create_derive!("constructor", constructor, Constructor, constructor_derive); create_derive!("debug", fmt::debug, Debug, debug_derive, debug); +create_derive!("deref", deref, Deref, deref_derive, deref); + +create_derive!( + "deref_mut", + deref_mut, + DerefMut, + deref_mut_derive, + deref_mut, +); + create_derive!("display", fmt::display, Display, display_derive, display); create_derive!("display", fmt::display, Binary, binary_derive, binary); create_derive!("display", fmt::display, Octal, octal_derive, octal); @@ -228,7 +186,14 @@ create_derive!( ); create_derive!("display", fmt::display, Pointer, pointer_derive, pointer); +create_derive!("error", error, Error, error_derive, error); + +create_derive!("from", from, From, from_derive, from); + +create_derive!("from_str", from_str, FromStr, from_str_derive); + create_derive!("index", index, Index, index_derive, index); + create_derive!( "index_mut", index_mut, @@ -237,6 +202,8 @@ create_derive!( index_mut, ); +create_derive!("into", into, Into, into_derive, into); + create_derive!( "into_iterator", into_iterator, @@ -245,20 +212,6 @@ create_derive!( into_iterator, ); -create_derive!("try_into", try_into, TryInto, try_into_derive, try_into); - -create_derive!("deref", deref, Deref, deref_derive, deref); -create_derive!( - "deref_mut", - deref_mut, - DerefMut, - deref_mut_derive, - deref_mut, -); - -create_derive!("as_ref", as_ref, AsRef, as_ref_derive, as_ref); -create_derive!("as_mut", as_mut, AsMut, as_mut_derive, as_mut); - create_derive!( "is_variant", is_variant, @@ -267,7 +220,56 @@ create_derive!( is_variant, ); -create_derive!("unwrap", unwrap, Unwrap, unwrap_derive, unwrap); +create_derive!("mul", mul_like, Mul, mul_derive, mul); +create_derive!("mul", mul_like, Div, div_derive, div); +create_derive!("mul", mul_like, Rem, rem_derive, rem); +create_derive!("mul", mul_like, Shr, shr_derive, shr); +create_derive!("mul", mul_like, Shl, shl_derive, shl); + +create_derive!( + "mul_assign", + mul_assign_like, + MulAssign, + mul_assign_derive, + mul_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + DivAssign, + div_assign_derive, + div_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + RemAssign, + rem_assign_derive, + rem_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + ShrAssign, + shr_assign_derive, + shr_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + ShlAssign, + shl_assign_derive, + shl_assign, +); + +create_derive!("not", not_like, Not, not_derive); +create_derive!("not", not_like, Neg, neg_derive); + +create_derive!("sum", sum_like, Sum, sum_derive); +create_derive!("sum", sum_like, Product, product_derive); + +create_derive!("try_into", try_into, TryInto, try_into_derive, try_into); + create_derive!( "try_unwrap", try_unwrap, @@ -275,3 +277,5 @@ create_derive!( try_unwrap_derive, try_unwrap, ); + +create_derive!("unwrap", unwrap, Unwrap, unwrap_derive, unwrap); From e81f61d61b4ef6e72792b5a9a6203bdca3d084d3 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 05:26:57 +0200 Subject: [PATCH 06/11] Use a macro and don't show docs for traits --- README.md | 9 ++ src/lib.rs | 303 ++++++++++++++++++++--------------------------------- 2 files changed, 122 insertions(+), 190 deletions(-) diff --git a/README.md b/README.md index 9ef4be14..c8e80e9b 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,15 @@ extern crate derive_more; # fn main() {} // omit wrapping statements above into `main()` in tests ``` +## Re-exports + +This crate also re-exports all of the standard library traits that it adds +derives for. So both the `Display` derive and the `Display` trait will be in +scope when you add the following code: +```rust +use derive_more::Display; +``` + [`cargo-expand`]: https://github.com/dtolnay/cargo-expand [`derive-new`]: https://github.com/nrc/derive-new diff --git a/src/lib.rs b/src/lib.rs index 00114323..b95d1cb4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,225 +65,148 @@ pub mod macros { pub use derive_more_impl::*; } +// The modules containing error types and other helpers #[cfg(any(feature = "add", feature = "not"))] pub mod ops; -#[cfg(feature = "add")] -mod gimmick_add { - pub use crate::macros::{Add, BitAnd, BitOr, BitXor, Sub}; - pub use core::ops::*; -} -#[cfg(feature = "add")] -#[doc(inline)] -pub use self::gimmick_add::{Add, BitAnd, BitOr, BitXor, Sub}; - -#[cfg(feature = "add_assign")] -mod gimmick_add_assign { - pub use crate::macros::{ - AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign, - }; - pub use core::ops::*; -} -#[cfg(feature = "add_assign")] -#[doc(inline)] -pub use self::gimmick_add_assign::{ - AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign, -}; - -#[cfg(feature = "as_mut")] -mod gimmick_as_mut { - pub use crate::macros::AsMut; - pub use core::convert::*; -} -#[cfg(feature = "as_mut")] -#[doc(inline)] -pub use self::gimmick_as_mut::AsMut; - -#[cfg(feature = "as_ref")] -mod gimmick_as_ref { - pub use crate::macros::AsRef; - pub use core::convert::*; -} -#[cfg(feature = "as_ref")] -#[doc(inline)] -pub use self::gimmick_as_ref::AsRef; - -#[cfg(feature = "constructor")] -#[doc(inline)] -pub use self::macros::Constructor; #[cfg(feature = "debug")] mod fmt; -#[cfg(feature = "debug")] -mod gimmick_debug { - pub use crate::macros::Debug; - pub use core::fmt::*; -} -#[cfg(feature = "debug")] -#[doc(inline)] -pub use self::gimmick_debug::Debug; - -#[cfg(feature = "deref")] -mod gimmick_deref { - pub use crate::macros::Deref; - pub use core::ops::*; -} -#[cfg(feature = "deref")] -#[doc(inline)] -pub use self::gimmick_deref::Deref; - -#[cfg(feature = "deref_mut")] -mod gimmick_deref_mut { - pub use crate::macros::DerefMut; - pub use core::ops::*; -} -#[cfg(feature = "deref_mut")] -#[doc(inline)] -pub use self::gimmick_deref_mut::DerefMut; - -#[cfg(feature = "display")] -mod gimmick_display { - pub use crate::macros::{ - Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, - }; - pub use core::fmt::*; -} -#[cfg(feature = "display")] -#[doc(inline)] -pub use self::gimmick_display::{ - Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, -}; #[cfg(feature = "error")] mod vendor; -#[cfg(feature = "error")] -mod gimmick_error { - pub use crate::macros::Error; - #[cfg(not(feature = "std"))] - pub use core::error::*; - #[cfg(feature = "std")] - pub use std::error::*; -} -#[cfg(feature = "error")] -pub use self::gimmick_error::Error; - -#[cfg(feature = "from")] -mod gimmick_from { - pub use crate::macros::From; - pub use core::convert::*; -} -#[cfg(feature = "from")] -#[doc(inline)] -pub use self::gimmick_from::From; #[cfg(feature = "from_str")] mod r#str; #[cfg(feature = "from_str")] -mod gimmick_from_str { - pub use crate::{macros::FromStr, r#str::FromStrError}; - pub use core::str::*; -} -#[cfg(feature = "from_str")] -#[doc(hidden)] -pub use self::gimmick_from_str::{FromStr, FromStrError}; - -#[cfg(feature = "index")] -mod gimmick_index { - pub use crate::macros::Index; - pub use core::ops::*; -} -#[cfg(feature = "index")] #[doc(inline)] -pub use self::gimmick_index::Index; +pub use crate::r#str::FromStrError; -#[cfg(feature = "index_mut")] -mod gimmick_index_mut { - pub use crate::macros::IndexMut; - pub use core::ops::*; -} -#[cfg(feature = "index_mut")] +#[cfg(feature = "try_into")] +mod convert; +#[cfg(feature = "try_into")] #[doc(inline)] -pub use self::gimmick_index_mut::IndexMut; +pub use crate::convert::TryIntoError; -#[cfg(feature = "into")] -mod gimmick_into { - pub use crate::macros::Into; - pub use core::convert::*; -} -#[cfg(feature = "into")] +#[cfg(feature = "try_unwrap")] +mod try_unwrap; +#[cfg(feature = "try_unwrap")] #[doc(inline)] -pub use self::gimmick_into::Into; +pub use self::try_unwrap::TryUnwrapError; + + +// When re-exporting traits from std we need to do a pretty crazy trick, because we ONLY want +// to re-export the traits and not derives that are called the same in the std module, +// because those would conflict with our own. The way we do this is by first importing both +// the trait and possible derive into a separate module and re-export them. Then we wildcard import +// all the things from that module into the main module, but we also import our own derive by its +// exact name. Due to the way wildcard imports work in rust, that results in our own derive taking +// precedence over any derive from std. +macro_rules! re_export_traits(( + $feature:literal, $new_module_name:ident, $module:path $(, $traits:ident)* $(,)?) => { + #[cfg(feature = $feature)] + mod $new_module_name { + pub use $module::{$($traits),*}; + } + + #[cfg(feature = $feature)] + #[doc(hidden)] + pub use crate::$new_module_name::*; + #[cfg(feature = $feature)] + #[doc(inline)] + // Seems there's a bug in this warning because it considers the next line a glob import, + // even though when expanded it is not. + #[allow(ambiguous_glob_reexports)] + pub use crate::macros::{$($traits),*}; + + } +); +re_export_traits!( + "add", + add_traits, + core::ops, + Add, + BitAnd, + BitOr, + BitXor, + Sub, +); +re_export_traits!( + "add_assign", + add_assign_traits, + core::ops, + AddAssign, + BitAndAssign, + BitOrAssign, + BitXorAssign, + SubAssign, +); +re_export_traits!("as_mut", as_mut_traits, core::convert, AsMut); +re_export_traits!("as_ref", as_ref_traits, core::convert, AsRef); +re_export_traits!("debug", debug_traits, core::fmt, Debug); +re_export_traits!("deref", deref_traits, core::ops, Deref); +re_export_traits!("deref_mut", deref_mut_traits, core::ops, DerefMut); +re_export_traits!( + "display", + display_traits, + core::fmt, + Binary, + Display, + LowerExp, + LowerHex, + Octal, + Pointer, + UpperExp, + UpperHex, +); -#[cfg(feature = "into_iterator")] -mod gimmick_into_iterator { - pub use crate::macros::IntoIterator; - pub use core::iter::*; -} -#[cfg(feature = "into_iterator")] -#[doc(inline)] -pub use self::gimmick_into_iterator::IntoIterator; +#[cfg(not(feature = "std"))] +re_export_traits!("error", error_traits, core::error, Error); +#[cfg(feature = "std")] +re_export_traits!("error", error_traits, std::error, Error); -#[cfg(feature = "is_variant")] -#[doc(inline)] -pub use self::macros::IsVariant; +re_export_traits!("from", from_traits, core::convert, From); -#[cfg(feature = "mul")] -mod gimmick_mul { - pub use crate::macros::{Div, Mul, Rem, Shl, Shr}; - pub use core::ops::*; -} -#[cfg(feature = "mul")] -#[doc(inline)] -pub use self::gimmick_mul::{Div, Mul, Rem, Shl, Shr}; +re_export_traits!("from_str", from_str_traits, core::str, FromStr); + +re_export_traits!("index", index_traits, core::ops, Index); + +re_export_traits!("index_mut", index_mut_traits, core::ops, IndexMut); + +re_export_traits!("into", into_traits, core::convert, Into); + +re_export_traits!( + "into_iterator", + into_iterator_traits, + core::iter, + IntoIterator, +); + +re_export_traits!("mul", mul_traits, core::ops, Div, Mul, Rem, Shl, Shr); #[cfg(feature = "mul_assign")] -mod gimmick_mul_assign { - pub use crate::macros::{DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign}; - pub use core::ops::*; -} -#[cfg(feature = "mul_assign")] -#[doc(inline)] -pub use self::gimmick_mul_assign::{ - DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign, -}; +re_export_traits!( + "mul_assign", + mul_assign_traits, + core::ops, + DivAssign, + MulAssign, + RemAssign, + ShlAssign, + ShrAssign, +); -#[cfg(feature = "not")] -mod gimmick_not { - pub use crate::macros::{Neg, Not}; - pub use core::ops::*; -} -#[cfg(feature = "not")] -#[doc(inline)] -pub use self::gimmick_not::{Neg, Not}; +re_export_traits!("not", not_traits, core::ops, Neg, Not); #[cfg(feature = "sum")] -mod gimmick_sum { - pub use crate::macros::{Product, Sum}; - pub use core::iter::*; -} -#[cfg(feature = "sum")] -#[doc(inline)] -pub use self::gimmick_sum::{Product, Sum}; +re_export_traits!("sum", sum_traits, core::iter, Product, Sum); -#[cfg(feature = "try_into")] -mod convert; -#[cfg(feature = "try_into")] -mod gimmick_try_into { - pub use crate::{convert::TryIntoError, macros::TryInto}; - pub use core::convert::*; -} -#[cfg(feature = "try_into")] -#[doc(inline)] -pub use self::gimmick_try_into::{TryInto, TryIntoError}; +re_export_traits!("try_into", try_into_traits, core::convert, TryInto); -#[cfg(feature = "try_unwrap")] -mod try_unwrap; -#[cfg(feature = "try_unwrap")] -#[doc(inline)] -pub use self::{macros::TryUnwrap, try_unwrap::TryUnwrapError}; -#[cfg(feature = "unwrap")] +// Then finally also wildcard export the other derives, to also export the derives that don't have +// a trait (e.g. Constructor). #[doc(inline)] -pub use self::macros::Unwrap; +pub use crate::macros::*; #[cfg(not(any( feature = "full", From 16c592f01bc500a1020132b560a6c74b274853e1 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 05:39:29 +0200 Subject: [PATCH 07/11] Fix fmt + clippy --- src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b95d1cb4..ca957633 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,7 +93,6 @@ mod try_unwrap; #[doc(inline)] pub use self::try_unwrap::TryUnwrapError; - // When re-exporting traits from std we need to do a pretty crazy trick, because we ONLY want // to re-export the traits and not derives that are called the same in the std module, // because those would conflict with our own. The way we do this is by first importing both @@ -114,8 +113,8 @@ macro_rules! re_export_traits(( #[cfg(feature = $feature)] #[doc(inline)] // Seems there's a bug in this warning because it considers the next line a glob import, - // even though when expanded it is not. - #[allow(ambiguous_glob_reexports)] + // even though when expanded it is not. Also make clippy not complain about it. + #[allow(ambiguous_glob_reexports, clippy::useless_attribute)] pub use crate::macros::{$($traits),*}; } @@ -202,7 +201,6 @@ re_export_traits!("sum", sum_traits, core::iter, Product, Sum); re_export_traits!("try_into", try_into_traits, core::convert, TryInto); - // Then finally also wildcard export the other derives, to also export the derives that don't have // a trait (e.g. Constructor). #[doc(inline)] From 8e5fc1c4baad179737d4eb9b9d9314b4f01adc65 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 14:21:25 +0200 Subject: [PATCH 08/11] Remove macros module and make safer for future --- src/lib.rs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ca957633..3fd3711a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,14 +57,6 @@ pub mod __private { pub use crate::vendor::thiserror::aserror::AsDynError; } -/// Module containing macro definitions only, without corresponding traits. -/// -/// Use it in your import paths, if you don't want to import traits, but only macros. -pub mod macros { - #[doc(inline)] - pub use derive_more_impl::*; -} - // The modules containing error types and other helpers #[cfg(any(feature = "add", feature = "not"))] pub mod ops; @@ -115,7 +107,7 @@ macro_rules! re_export_traits(( // Seems there's a bug in this warning because it considers the next line a glob import, // even though when expanded it is not. Also make clippy not complain about it. #[allow(ambiguous_glob_reexports, clippy::useless_attribute)] - pub use crate::macros::{$($traits),*}; + pub use derive_more_impl::{$($traits),*}; } ); @@ -196,15 +188,29 @@ re_export_traits!( re_export_traits!("not", not_traits, core::ops, Neg, Not); -#[cfg(feature = "sum")] re_export_traits!("sum", sum_traits, core::iter, Product, Sum); re_export_traits!("try_into", try_into_traits, core::convert, TryInto); -// Then finally also wildcard export the other derives, to also export the derives that don't have -// a trait (e.g. Constructor). +// Then finally also re-export the other derives, to also export the derives that don't have +// a trait. We could have used a wildcard re-export here, but that might inadvertently hide that we +// missed a trait derive. +#[cfg(feature = "constructor")] +#[doc(inline)] +pub use derive_more_impl::Constructor; + +#[cfg(feature = "is_variant")] +#[doc(inline)] +pub use derive_more_impl::IsVariant; + +#[cfg(feature = "try_unwrap")] #[doc(inline)] -pub use crate::macros::*; +pub use derive_more_impl::TryUnwrap; + +#[cfg(feature = "unwrap")] +#[doc(inline)] +pub use derive_more_impl::Unwrap; + #[cfg(not(any( feature = "full", From 12328c0305d2082f6d194b928342548455622fcb Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 14:23:02 +0200 Subject: [PATCH 09/11] rustfmt --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3fd3711a..9f5c573d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -211,7 +211,6 @@ pub use derive_more_impl::TryUnwrap; #[doc(inline)] pub use derive_more_impl::Unwrap; - #[cfg(not(any( feature = "full", feature = "add", From 532995100777c0dfa03577755acdfce9e80b37dc Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 14:36:07 +0200 Subject: [PATCH 10/11] Update changelog after removing macros module --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be797ccd..2cf78f30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,8 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). and ignores field type itself. - The `Into` derive now uses `#[into()]` instead of `#[into(types())]` and ignores field type itself. -- Importing derive macro now also import its corresponding trait. To import macro only, - `macros` module should be used. +- Importing a derive macro now also import its corresponding trait. ### Added From db4734e603073297cb9e8ebb135dc507a019d5f3 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 15:32:13 +0200 Subject: [PATCH 11/11] Fix... --- src/lib.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9f5c573d..57d677b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,7 +91,10 @@ pub use self::try_unwrap::TryUnwrapError; // the trait and possible derive into a separate module and re-export them. Then we wildcard import // all the things from that module into the main module, but we also import our own derive by its // exact name. Due to the way wildcard imports work in rust, that results in our own derive taking -// precedence over any derive from std. +// precedence over any derive from std. For some reason the named re-export of our own derive +// cannot be in in this (or really any) macro too. It will somehow still consider it a wildcard +// then and will result in this warning ambiguous_glob_reexports, and not actually exporting of our +// derive. macro_rules! re_export_traits(( $feature:literal, $new_module_name:ident, $module:path $(, $traits:ident)* $(,)?) => { #[cfg(feature = $feature)] @@ -102,15 +105,10 @@ macro_rules! re_export_traits(( #[cfg(feature = $feature)] #[doc(hidden)] pub use crate::$new_module_name::*; - #[cfg(feature = $feature)] - #[doc(inline)] - // Seems there's a bug in this warning because it considers the next line a glob import, - // even though when expanded it is not. Also make clippy not complain about it. - #[allow(ambiguous_glob_reexports, clippy::useless_attribute)] - pub use derive_more_impl::{$($traits),*}; } ); + re_export_traits!( "add", add_traits, @@ -192,25 +190,85 @@ re_export_traits!("sum", sum_traits, core::iter, Product, Sum); re_export_traits!("try_into", try_into_traits, core::convert, TryInto); -// Then finally also re-export the other derives, to also export the derives that don't have -// a trait. We could have used a wildcard re-export here, but that might inadvertently hide that we -// missed a trait derive. +// Now re-export our own derives by their exact name to overwrite any derives that the trait +// re-exporting might inadvertently pull into scope. +#[cfg(feature = "add")] +pub use derive_more_impl::{Add, BitAnd, BitOr, BitXor, Sub}; + +#[cfg(feature = "add_assign")] +pub use derive_more_impl::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign, +}; + +#[cfg(feature = "as_mut")] +pub use derive_more_impl::AsMut; + +#[cfg(feature = "as_ref")] +pub use derive_more_impl::AsRef; + #[cfg(feature = "constructor")] -#[doc(inline)] pub use derive_more_impl::Constructor; +#[cfg(feature = "debug")] +pub use derive_more_impl::Debug; + +#[cfg(feature = "deref")] +pub use derive_more_impl::Deref; + +#[cfg(feature = "deref_mut")] +pub use derive_more_impl::DerefMut; + +#[cfg(feature = "display")] +pub use derive_more_impl::{ + Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, +}; + +#[cfg(feature = "error")] +pub use derive_more_impl::Error; + +#[cfg(feature = "from")] +pub use derive_more_impl::From; + +#[cfg(feature = "from_str")] +pub use derive_more_impl::FromStr; + +#[cfg(feature = "index")] +pub use derive_more_impl::Index; + +#[cfg(feature = "index_mut")] +pub use derive_more_impl::IndexMut; + +#[cfg(feature = "into")] +pub use derive_more_impl::Into; + +#[cfg(feature = "into_iterator")] +pub use derive_more_impl::IntoIterator; + #[cfg(feature = "is_variant")] -#[doc(inline)] pub use derive_more_impl::IsVariant; +#[cfg(feature = "mul")] +pub use derive_more_impl::{Div, Mul, Rem, Shl, Shr}; + +#[cfg(feature = "mul_assign")] +pub use derive_more_impl::{DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign}; + +#[cfg(feature = "not")] +pub use derive_more_impl::{Neg, Not}; + +#[cfg(feature = "sum")] +pub use derive_more_impl::{Product, Sum}; + +#[cfg(feature = "try_into")] +pub use derive_more_impl::TryInto; + #[cfg(feature = "try_unwrap")] -#[doc(inline)] pub use derive_more_impl::TryUnwrap; #[cfg(feature = "unwrap")] -#[doc(inline)] pub use derive_more_impl::Unwrap; +// Check if any feature is enabled #[cfg(not(any( feature = "full", feature = "add",