Skip to content

Commit 9d8c74e

Browse files
authored
Fix TCFType macros for generic types (#652)
* Improve TCFType macros This adds the following new features: * `declare_TCFType!`: Generics are accepted. * `impl_TCFType!`: Non-defaulted generics are accepted, and impls are fixed to be for all generics. In addition, some warnings are silenced and the macros no longer depend on any traits being in scope in the caller. * Support generics in impl_CFComparison * Add generic test for macros
1 parent fb71d45 commit 9d8c74e

File tree

3 files changed

+45
-19
lines changed

3 files changed

+45
-19
lines changed

core-foundation/src/characterset.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
1212
pub use core_foundation_sys::characterset::*;
1313

14-
use crate::base::TCFType;
15-
1614
declare_TCFType! {
1715
/// An immutable set of Unicode characters.
1816
CFCharacterSet, CFCharacterSetRef

core-foundation/src/lib.rs

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,25 @@ macro_rules! declare_TCFType {
5252
(
5353
$(#[$doc:meta])*
5454
$ty:ident, $raw:ident
55+
) => {
56+
declare_TCFType!($(#[$doc])* $ty<>, $raw);
57+
};
58+
59+
(
60+
$(#[$doc:meta])*
61+
$ty:ident<$($p:ident $(: $bound:path)*),*>, $raw:ident
5562
) => {
5663
$(#[$doc])*
57-
pub struct $ty($raw);
64+
pub struct $ty<$($p $(: $bound)*),*>($raw, $(::std::marker::PhantomData<$p>),*);
5865

59-
impl Drop for $ty {
66+
#[allow(unused_imports)]
67+
impl<$($p $(: $bound)*),*> Drop for $ty<$($p),*> {
6068
fn drop(&mut self) {
69+
use $crate::base::TCFType;
6170
unsafe { $crate::base::CFRelease(self.as_CFTypeRef()) }
6271
}
6372
}
64-
}
73+
};
6574
}
6675

6776
/// Provide an implementation of the [`TCFType`] trait for the Rust
@@ -82,6 +91,7 @@ macro_rules! impl_TCFType {
8291
impl<$($p $(: $bound)*),*> $crate::base::TCFType for $ty<$($p),*> {
8392
type Ref = $ty_ref;
8493

94+
#[allow(non_snake_case)]
8595
#[inline]
8696
fn as_concrete_TypeRef(&self) -> $ty_ref {
8797
self.0
@@ -94,6 +104,7 @@ macro_rules! impl_TCFType {
94104
$crate::base::TCFType::wrap_under_create_rule(reference)
95105
}
96106

107+
#[allow(non_snake_case)]
97108
#[inline]
98109
fn as_CFTypeRef(&self) -> $crate::base::CFTypeRef {
99110
self.as_concrete_TypeRef() as $crate::base::CFTypeRef
@@ -115,39 +126,46 @@ macro_rules! impl_TCFType {
115126
}
116127
}
117128

118-
impl Clone for $ty {
129+
#[allow(unused_imports)]
130+
impl<$($p $(: $bound)*),*> Clone for $ty<$($p),*> {
119131
#[inline]
120-
fn clone(&self) -> $ty {
132+
fn clone(&self) -> Self {
133+
use $crate::base::TCFType;
121134
unsafe {
122135
$ty::wrap_under_get_rule(self.0)
123136
}
124137
}
125138
}
126139

127-
impl PartialEq for $ty {
140+
#[allow(unused_imports)]
141+
impl<$($p $(: $bound)*),*> PartialEq for $ty<$($p),*> {
128142
#[inline]
129-
fn eq(&self, other: &$ty) -> bool {
143+
fn eq(&self, other: &Self) -> bool {
144+
use $crate::base::TCFType;
130145
self.as_CFType().eq(&other.as_CFType())
131146
}
132147
}
133148

134-
impl Eq for $ty { }
149+
impl<$($p $(: $bound)*),*> Eq for $ty<$($p),*> { }
135150

136-
unsafe impl<'a> $crate::base::ToVoid<$ty> for &'a $ty {
151+
#[allow(unused_imports)]
152+
unsafe impl<'a, $($p $(: $bound)*),*> $crate::base::ToVoid<$ty<$($p),*>> for &'a $ty<$($p),*> {
137153
fn to_void(&self) -> *const ::core::ffi::c_void {
138-
use $crate::base::TCFTypeRef;
154+
use $crate::base::{TCFType, TCFTypeRef};
139155
self.as_concrete_TypeRef().as_void_ptr()
140156
}
141157
}
142158

143-
unsafe impl $crate::base::ToVoid<$ty> for $ty {
159+
#[allow(unused_imports)]
160+
unsafe impl<$($p $(: $bound)*),*> $crate::base::ToVoid<$ty<$($p),*>> for $ty<$($p),*> {
144161
fn to_void(&self) -> *const ::core::ffi::c_void {
145-
use $crate::base::TCFTypeRef;
162+
use $crate::base::{TCFType, TCFTypeRef};
146163
self.as_concrete_TypeRef().as_void_ptr()
147164
}
148165
}
149166

150-
unsafe impl $crate::base::ToVoid<$ty> for $ty_ref {
167+
#[allow(unused_imports)]
168+
unsafe impl<$($p $(: $bound)*),*> $crate::base::ToVoid<$ty<$($p),*>> for $ty_ref {
151169
fn to_void(&self) -> *const ::core::ffi::c_void {
152170
use $crate::base::TCFTypeRef;
153171
self.as_void_ptr()
@@ -178,8 +196,10 @@ macro_rules! impl_CFTypeDescription {
178196
impl_CFTypeDescription!($ty<>);
179197
};
180198
($ty:ident<$($p:ident $(: $bound:path)*),*>) => {
199+
#[allow(unused_imports)]
181200
impl<$($p $(: $bound)*),*> ::std::fmt::Debug for $ty<$($p),*> {
182201
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
202+
use $crate::base::TCFType;
183203
self.as_CFType().fmt(f)
184204
}
185205
}
@@ -189,9 +209,12 @@ macro_rules! impl_CFTypeDescription {
189209
#[macro_export]
190210
macro_rules! impl_CFComparison {
191211
($ty:ident, $compare:ident) => {
192-
impl PartialOrd for $ty {
212+
impl_CFComparison!($ty<>, $compare);
213+
};
214+
($ty:ident<$($p:ident $(: $bound:path)*),*>, $compare:ident) => {
215+
impl<$($p $(: $bound)*),*> PartialOrd for $ty<$($p),*> {
193216
#[inline]
194-
fn partial_cmp(&self, other: &$ty) -> Option<::std::cmp::Ordering> {
217+
fn partial_cmp(&self, other: &$ty<$($p),*>) -> Option<::std::cmp::Ordering> {
195218
unsafe {
196219
Some(
197220
$compare(
@@ -205,9 +228,9 @@ macro_rules! impl_CFComparison {
205228
}
206229
}
207230

208-
impl Ord for $ty {
231+
impl<$($p $(: $bound)*),*> Ord for $ty<$($p),*> {
209232
#[inline]
210-
fn cmp(&self, other: &$ty) -> ::std::cmp::Ordering {
233+
fn cmp(&self, other: &$ty<$($p),*>) -> ::std::cmp::Ordering {
211234
self.partial_cmp(other).unwrap()
212235
}
213236
}

core-foundation/tests/use_macro_outside_crate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ declare_TCFType!(CFFooBar, CFFooBarRef);
2424
impl_TCFType!(CFFooBar, CFFooBarRef, CFFooBarGetTypeID);
2525
impl_CFTypeDescription!(CFFooBar);
2626
impl_CFComparison!(CFFooBar, fake_compare);
27+
28+
declare_TCFType!(CFGenericFooBar<T: Clone>, CFFooBarRef);
29+
impl_TCFType!(CFGenericFooBar<T: Clone>, CFFooBarRef, CFFooBarGetTypeID);
30+
impl_CFTypeDescription!(CFGenericFooBar<T: Clone>);
31+
impl_CFComparison!(CFGenericFooBar<T: Clone>, fake_compare);

0 commit comments

Comments
 (0)