@@ -72,7 +72,8 @@ impl fmt::Display for VerificationError {
7272impl Error for VerificationError { }
7373
7474/// Relaxed version of `Encoding::equivalent_to_box` that allows
75- /// `*mut c_void` and `*const c_void` to be used in place of other pointers.
75+ /// `*mut c_void` and `*const c_void` to be used in place of other pointers,
76+ /// and allows signed types where unsigned types are excepted.
7677///
7778/// Note: This is a top-level comparison; `*mut *mut c_void` or structures
7879/// containing `*mut c_void` are not allowed differently than usual.
@@ -81,10 +82,32 @@ fn relaxed_equivalent_to_box(encoding: &Encoding, expected: &EncodingBox) -> boo
8182 && matches ! ( encoding, Encoding :: Pointer ( & Encoding :: Void ) )
8283 && matches ! ( expected, EncodingBox :: Pointer ( _) )
8384 {
84- true
85- } else {
86- encoding. equivalent_to_box ( expected)
85+ return true ;
8786 }
87+
88+ if cfg ! ( feature = "relax-sign-encoding" ) {
89+ let actual_signed = match encoding {
90+ Encoding :: UChar => & Encoding :: Char ,
91+ Encoding :: UShort => & Encoding :: Short ,
92+ Encoding :: UInt => & Encoding :: Int ,
93+ Encoding :: ULong => & Encoding :: Long ,
94+ Encoding :: ULongLong => & Encoding :: LongLong ,
95+ enc => enc,
96+ } ;
97+ let expected_signed = match expected {
98+ EncodingBox :: UChar => & EncodingBox :: Char ,
99+ EncodingBox :: UShort => & EncodingBox :: Short ,
100+ EncodingBox :: UInt => & EncodingBox :: Int ,
101+ EncodingBox :: ULong => & EncodingBox :: Long ,
102+ EncodingBox :: ULongLong => & EncodingBox :: LongLong ,
103+ enc => enc,
104+ } ;
105+ if actual_signed == expected_signed {
106+ return true ;
107+ }
108+ }
109+
110+ encoding. equivalent_to_box ( expected)
88111}
89112
90113pub ( crate ) fn verify_method_signature (
@@ -133,6 +156,7 @@ pub(crate) fn verify_method_signature(
133156#[ cfg( test) ]
134157mod tests {
135158 use super :: * ;
159+ use crate :: ffi;
136160 use crate :: runtime:: Sel ;
137161 use crate :: test_utils;
138162 use crate :: { msg_send, sel} ;
@@ -183,6 +207,17 @@ mod tests {
183207 "expected argument at index 0 to have type code 'I', but found ':'"
184208 ) ;
185209
210+ // <https://github.com/madsmtm/objc2/issues/566>
211+ let res = cls. verify_sel :: < ( ) , ffi:: NSUInteger > ( sel ! ( getNSInteger) ) ;
212+ let expected = if cfg ! ( feature = "relax-sign-encoding" ) {
213+ Ok ( ( ) )
214+ } else if cfg ! ( target_pointer_width = "64" ) {
215+ Err ( "expected return to have type code 'q', but found 'Q'" . to_string ( ) )
216+ } else {
217+ Err ( "expected return to have type code 'i', but found 'I'" . to_string ( ) )
218+ } ;
219+ assert_eq ! ( res. map_err( |e| e. to_string( ) ) , expected) ;
220+
186221 // Metaclass
187222 let metaclass = cls. metaclass ( ) ;
188223 let err = metaclass
@@ -193,10 +228,10 @@ mod tests {
193228
194229 #[ test]
195230 #[ cfg( debug_assertions) ]
196- #[ should_panic = "invalid message send to -[CustomObject foo]: expected return to have type code 'I', but found 'i'" ]
231+ #[ should_panic = "invalid message send to -[CustomObject foo]: expected return to have type code 'I', but found '^ i'" ]
197232 fn test_send_message_verified ( ) {
198233 let obj = test_utils:: custom_object ( ) ;
199- let _: i32 = unsafe { msg_send ! [ & obj, foo] } ;
234+ let _: * const i32 = unsafe { msg_send ! [ & obj, foo] } ;
200235 }
201236
202237 #[ test]
0 commit comments