@@ -23,6 +23,16 @@ pub trait MsgSendId<T, U> {
23
23
) -> Result < Option < U > , MessageError > ;
24
24
}
25
25
26
+ #[ doc( hidden) ]
27
+ pub trait MsgSendSuperId < T , U > {
28
+ unsafe fn send_super_message_id < A : MessageArguments > (
29
+ obj : T ,
30
+ superclass : & Class ,
31
+ sel : Sel ,
32
+ args : A ,
33
+ ) -> Result < Option < U > , MessageError > ;
34
+ }
35
+
26
36
// `new`
27
37
impl < T : ?Sized + Message , O : Ownership > MsgSendId < & ' _ Class , Id < T , O > >
28
38
for Assert < true , false , false , false >
@@ -104,6 +114,26 @@ impl<T: MessageReceiver, U: Message, O: Ownership> MsgSendId<T, Id<U, O>>
104
114
}
105
115
}
106
116
117
+ // Super: All other selectors
118
+ impl < T : MessageReceiver , U : Message , O : Ownership > MsgSendSuperId < T , Id < U , O > >
119
+ for Assert < false , false , false , false >
120
+ {
121
+ #[ inline( always) ]
122
+ unsafe fn send_super_message_id < A : MessageArguments > (
123
+ obj : T ,
124
+ superclass : & Class ,
125
+ sel : Sel ,
126
+ args : A ,
127
+ ) -> Result < Option < Id < U , O > > , MessageError > {
128
+ // All code between the message send and the `retain_autoreleased`
129
+ // must be able to be optimized away for this to work.
130
+ unsafe {
131
+ MessageReceiver :: send_super_message ( obj, superclass, sel, args)
132
+ . map ( |r| Id :: retain_autoreleased ( r) )
133
+ }
134
+ }
135
+ }
136
+
107
137
// https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-method-families
108
138
#[ doc( hidden) ]
109
139
pub const fn in_method_family ( mut selector : & [ u8 ] , mut family : & [ u8 ] ) -> bool {
@@ -206,6 +236,18 @@ mod tests {
206
236
let _desc: Option < Id < Object , Shared > > = unsafe { msg_send_id ! [ & obj, description] } ;
207
237
}
208
238
239
+ #[ test]
240
+ fn test_msg_send_super_id ( ) {
241
+ // We send the messages to the class itself instead of it's actual
242
+ // superclass, just to verify that the macro works.
243
+ // TODO: Better solution!
244
+ let cls = class ! ( NSObject ) ;
245
+ let obj: Id < Object , Owned > = unsafe { msg_send_id ! [ cls, new] . unwrap ( ) } ;
246
+
247
+ let _desc: Option < Id < Object , Shared > > =
248
+ unsafe { msg_send_id ! [ super ( & obj, cls) , description] } ;
249
+ }
250
+
209
251
#[ test]
210
252
fn test_in_method_family ( ) {
211
253
// Common cases
0 commit comments