From fcc3cb03f0481884c455159627f665f4082c252a Mon Sep 17 00:00:00 2001 From: Martin Habovstiak Date: Sun, 11 Aug 2024 14:57:47 +0200 Subject: [PATCH] Support non-doc attrs in extension trait macro The `define_extension_trait` macro originally didn't support `#[inline]` or other attributes for simplicity. We still want them so this commit adds basic support for it. It adds the `doc` attributes to trait *definition* only and adds all other attributes to the *implementation* only. This should support `#[inline]` and other attributes. The downside is it doesn't support adding non-doc attributes to trait *definition* but I can't think of any relevant ones that we would want and we can find a solution later if we do. --- bitcoin/src/internal_macros.rs | 47 +++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/bitcoin/src/internal_macros.rs b/bitcoin/src/internal_macros.rs index 72819f103..32cc7e766 100644 --- a/bitcoin/src/internal_macros.rs +++ b/bitcoin/src/internal_macros.rs @@ -214,6 +214,38 @@ macro_rules! impl_asref_push_bytes { } pub(crate) use impl_asref_push_bytes; +macro_rules! only_doc_attrs { + ({}, {$($fun:tt)*}) => { + $($fun)* + }; + ({#[doc = $($doc:tt)*] $($all_attrs:tt)*}, {$($fun:tt)*}) => { + $crate::internal_macros::only_doc_attrs!({ $($all_attrs)* }, { #[doc = $($doc)*] $($fun)* }); + }; + ({#[doc($($doc:tt)*)] $($all_attrs:tt)*}, {$($fun:tt)*}) => { + $crate::internal_macros::only_doc_attrs!({ $($all_attrs)* }, { #[doc($($doc)*)] $($fun)* }); + }; + ({#[$($other:tt)*] $($all_attrs:tt)*}, {$($fun:tt)*}) => { + $crate::internal_macros::only_doc_attrs!({ $($all_attrs)* }, { $($fun)* }); + }; +} +pub(crate) use only_doc_attrs; + +macro_rules! only_non_doc_attrs { + ({}, {$($fun:tt)*}) => { + $($fun)* + }; + ({#[doc = $($doc:tt)*] $($all_attrs:tt)*}, {$($fun:tt)*}) => { + $crate::internal_macros::only_doc_attrs!({ $($all_attrs)* }, { #[doc = $($doc)*] $($fun)* }); + }; + ({#[doc($($doc:tt)*)] $($all_attrs:tt)*}, {$($fun:tt)*}) => { + $crate::internal_macros::only_doc_attrs!({ $($all_attrs)* }, { $($fun)* }); + }; + ({#[$($other:tt)*] $($all_attrs:tt)*}, {$($fun:tt)*}) => { + $crate::internal_macros::only_doc_attrs!({ $($all_attrs)* }, { #[$(other)*] $($fun)* }); + }; +} +pub(crate) use only_non_doc_attrs; + /// Defines an trait `$trait_name` and implements it for `ty`, used to define extension traits. macro_rules! define_extension_trait { ($(#[$($trait_attrs:tt)*])* $trait_vis:vis trait $trait_name:ident impl for $ty:ident { @@ -224,14 +256,23 @@ macro_rules! define_extension_trait { }) => { $(#[$($trait_attrs)*])* $trait_vis trait $trait_name { $( - $(#[$($fn_attrs)*])* - fn $fn$(<$($gen: $gent),*>)?($($param_name: $param_type),*) $( -> $ret )?; + $crate::internal_macros::only_doc_attrs! { + { $(#[$($fn_attrs)*])* }, + { + fn $fn$(<$($gen: $gent),*>)?($($param_name: $param_type),*) $( -> $ret )?; + } + } )* } impl $trait_name for $ty { $( - fn $fn$(<$($gen: $gent),*>)?($($param_name: $param_type),*) $( -> $ret )? $body + $crate::internal_macros::only_non_doc_attrs! { + { $(#[$($fn_attrs)*])* }, + { + fn $fn$(<$($gen: $gent),*>)?($($param_name: $param_type),*) $( -> $ret )? $body + } + } )* } };