@@ -18,11 +18,9 @@ use core::ptr;
1818use core:: ptr:: NonNull ;
1919use std:: ffi:: CString ;
2020
21- use crate :: encode:: { Encode , EncodeArgument , EncodeArguments , EncodeReturn , Encoding , RefEncode } ;
21+ use crate :: encode:: { Encode , EncodeArguments , EncodeReturn , Encoding } ;
2222use crate :: ffi;
23- use crate :: mutability:: IsMutable ;
24- use crate :: rc:: Allocated ;
25- use crate :: runtime:: { AnyClass , AnyObject , AnyProtocol , Bool , Imp , Sel } ;
23+ use crate :: runtime:: { AnyClass , AnyObject , AnyProtocol , Bool , Imp , MethodImplementation , Sel } ;
2624use crate :: sel;
2725use crate :: Message ;
2826
@@ -31,171 +29,6 @@ pub use ivar_bool::IvarBool;
3129pub use ivar_drop:: IvarDrop ;
3230pub use ivar_encode:: IvarEncode ;
3331
34- pub ( crate ) mod private {
35- pub trait Sealed { }
36- }
37-
38- /// Types that can be used as the implementation of an Objective-C method.
39- ///
40- /// This is a sealed trait that is implemented for a lot of `extern "C"`
41- /// function pointer types.
42- //
43- // Note: `Sized` is intentionally added to make the trait not object safe.
44- pub trait MethodImplementation : private:: Sealed + Sized {
45- /// The callee type of the method.
46- type Callee : RefEncode + ?Sized ;
47- /// The return type of the method.
48- type Ret : EncodeReturn ;
49- /// The argument types of the method.
50- type Args : EncodeArguments ;
51-
52- #[ doc( hidden) ]
53- fn __imp ( self ) -> Imp ;
54- }
55-
56- macro_rules! method_impl_generic {
57- ( <$( $l: lifetime) ,* > T : $t_bound: ident $( + $t_bound2: ident) ?, $r: ident, $f: ty, $( $t: ident) ,* ) => {
58- impl <$( $l, ) * T , $r, $( $t) ,* > private:: Sealed for $f
59- where
60- T : ?Sized + $t_bound $( + $t_bound2) ?,
61- $r: EncodeReturn ,
62- $( $t: EncodeArgument , ) *
63- { }
64-
65- impl <$( $l, ) * T , $r, $( $t) ,* > MethodImplementation for $f
66- where
67- T : ?Sized + $t_bound $( + $t_bound2) ?,
68- $r: EncodeReturn ,
69- $( $t: EncodeArgument , ) *
70- {
71- type Callee = T ;
72- type Ret = $r;
73- type Args = ( $( $t, ) * ) ;
74-
75- fn __imp( self ) -> Imp {
76- unsafe { mem:: transmute( self ) }
77- }
78- }
79- } ;
80- }
81-
82- macro_rules! method_impl_concrete {
83- ( <$( $l: lifetime) ,* > $callee: ident, $r: ident, $f: ty, $( $t: ident) ,* ) => {
84- impl <$( $l, ) * $r, $( $t) ,* > private:: Sealed for $f
85- where
86- $r: EncodeReturn ,
87- $( $t: EncodeArgument , ) *
88- { }
89-
90- impl <$( $l, ) * $r, $( $t) ,* > MethodImplementation for $f
91- where
92- $r: EncodeReturn ,
93- $( $t: EncodeArgument , ) *
94- {
95- type Callee = $callee;
96- type Ret = $r;
97- type Args = ( $( $t, ) * ) ;
98-
99- fn __imp( self ) -> Imp {
100- unsafe { mem:: transmute( self ) }
101- }
102- }
103- } ;
104- }
105-
106- macro_rules! method_impl_allocated {
107- ( <> Allocated <T >, $f: ty, $( $t: ident) ,* ) => {
108- #[ doc( hidden) ]
109- impl <T , $( $t) ,* > private:: Sealed for $f
110- where
111- T : ?Sized + Message ,
112- $( $t: EncodeArgument , ) *
113- { }
114-
115- #[ doc( hidden) ]
116- impl <T , $( $t) ,* > MethodImplementation for $f
117- where
118- T : ?Sized + Message ,
119- $( $t: EncodeArgument , ) *
120- {
121- type Callee = T ;
122- type Ret = __IdReturnValue;
123- type Args = ( $( $t, ) * ) ;
124-
125- fn __imp( self ) -> Imp {
126- // SAFETY: `Allocated<T>` is the same as `NonNull<T>`, except
127- // with the assumption of a +1 calling convention.
128- //
129- // The calling convention is ensured to be upheld by having
130- // `__IdReturnValue` in the type, since that type is private
131- // and hence only internal macros like `#[method_id]` will be
132- // able to produce it (and that, in turn, only allows it if
133- // the selector is `init` as checked by `MessageRecieveId`).
134- unsafe { mem:: transmute( self ) }
135- }
136- }
137- } ;
138- }
139-
140- macro_rules! method_impl_abi {
141- ( $abi: literal; $( $t: ident) ,* ) => {
142- method_impl_generic!( <' a> T : Message , R , extern $abi fn ( & ' a T , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
143- method_impl_generic!( <' a> T : Message + IsMutable , R , extern $abi fn ( & ' a mut T , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
144- method_impl_generic!( <> T : Message , R , unsafe extern $abi fn ( * const T , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
145- method_impl_generic!( <> T : Message , R , unsafe extern $abi fn ( * mut T , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
146- method_impl_generic!( <' a> T : Message , R , unsafe extern $abi fn ( & ' a T , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
147- method_impl_generic!( <' a> T : Message + IsMutable , R , unsafe extern $abi fn ( & ' a mut T , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
148-
149- method_impl_concrete!( <' a> AnyObject , R , extern $abi fn ( & ' a mut AnyObject , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
150- method_impl_concrete!( <' a> AnyObject , R , unsafe extern $abi fn ( & ' a mut AnyObject , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
151-
152- method_impl_concrete!( <' a> AnyClass , R , extern $abi fn ( & ' a AnyClass , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
153- method_impl_concrete!( <> AnyClass , R , unsafe extern $abi fn ( * const AnyClass , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
154- method_impl_concrete!( <' a> AnyClass , R , unsafe extern $abi fn ( & ' a AnyClass , Sel $( , $t) * ) -> R , $( $t) ,* ) ;
155-
156- method_impl_allocated!( <> Allocated <T >, extern $abi fn ( Allocated <T >, Sel $( , $t) * ) -> __IdReturnValue, $( $t) ,* ) ;
157- method_impl_allocated!( <> Allocated <T >, unsafe extern $abi fn ( Allocated <T >, Sel $( , $t) * ) -> __IdReturnValue, $( $t) ,* ) ;
158- } ;
159- }
160-
161- macro_rules! method_impl {
162- ( $( $t: ident) ,* ) => {
163- method_impl_abi!( "C" ; $( $t) ,* ) ;
164- #[ cfg( feature = "unstable-c-unwind" ) ]
165- method_impl_abi!( "C-unwind" ; $( $t) ,* ) ;
166- } ;
167- }
168-
169- method_impl ! ( ) ;
170- method_impl ! ( A ) ;
171- method_impl ! ( A , B ) ;
172- method_impl ! ( A , B , C ) ;
173- method_impl ! ( A , B , C , D ) ;
174- method_impl ! ( A , B , C , D , E ) ;
175- method_impl ! ( A , B , C , D , E , F ) ;
176- method_impl ! ( A , B , C , D , E , F , G ) ;
177- method_impl ! ( A , B , C , D , E , F , G , H ) ;
178- method_impl ! ( A , B , C , D , E , F , G , H , I ) ;
179- method_impl ! ( A , B , C , D , E , F , G , H , I , J ) ;
180- method_impl ! ( A , B , C , D , E , F , G , H , I , J , K ) ;
181- method_impl ! ( A , B , C , D , E , F , G , H , I , J , K , L ) ;
182- method_impl ! ( A , B , C , D , E , F , G , H , I , J , K , L , M ) ;
183- method_impl ! ( A , B , C , D , E , F , G , H , I , J , K , L , M , N ) ;
184- method_impl ! ( A , B , C , D , E , F , G , H , I , J , K , L , M , N , O ) ;
185- method_impl ! ( A , B , C , D , E , F , G , H , I , J , K , L , M , N , O , P ) ;
186-
187- /// Helper type for implementing `MethodImplementation` with a receiver of
188- /// `Allocated<T>`, without exposing that implementation to users.
189- #[ doc( hidden) ]
190- #[ repr( transparent) ]
191- #[ derive( Debug ) ]
192- pub struct __IdReturnValue ( pub ( crate ) * mut AnyObject ) ;
193-
194- // SAFETY: `__IdReturnValue` is `#[repr(transparent)]`
195- unsafe impl Encode for __IdReturnValue {
196- const ENCODING : Encoding = <* mut AnyObject >:: ENCODING ;
197- }
198-
19932fn method_type_encoding ( ret : & Encoding , args : & [ Encoding ] ) -> CString {
20033 // First two arguments are always self and the selector
20134 let mut types = format ! ( "{ret}{}{}" , <* mut AnyObject >:: ENCODING , Sel :: ENCODING ) ;
@@ -778,6 +611,7 @@ mod tests {
778611 use std:: hash:: Hash ;
779612
780613 use super :: * ;
614+ use crate :: encode:: RefEncode ;
781615 use crate :: mutability:: Immutable ;
782616 use crate :: rc:: Id ;
783617 use crate :: runtime:: { NSObject , NSObjectProtocol } ;
0 commit comments