diff options
-rw-r--r-- | bindgen-tests/tests/expectations/tests/objc_escape.rs | 38 | ||||
-rw-r--r-- | bindgen-tests/tests/headers/objc_escape.h | 6 | ||||
-rw-r--r-- | bindgen/ir/objc.rs | 12 |
3 files changed, 55 insertions, 1 deletions
diff --git a/bindgen-tests/tests/expectations/tests/objc_escape.rs b/bindgen-tests/tests/expectations/tests/objc_escape.rs new file mode 100644 index 00000000..c2f0ce31 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/objc_escape.rs @@ -0,0 +1,38 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] +#![cfg(target_os = "macos")] + +use objc::{self, class, msg_send, sel, sel_impl}; +#[allow(non_camel_case_types)] +pub type id = *mut objc::runtime::Object; +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct A(pub id); +impl std::ops::Deref for A { + type Target = objc::runtime::Object; + fn deref(&self) -> &Self::Target { + unsafe { &*self.0 } + } +} +unsafe impl objc::Message for A {} +impl A { + pub fn alloc() -> Self { + Self(unsafe { msg_send!(class!(A), alloc) }) + } +} +impl IA for A {} +pub trait IA: Sized + std::ops::Deref { + unsafe fn f_as_( + &self, + arg1: ::std::os::raw::c_int, + arg2: ::std::os::raw::c_int, + ) where + <Self as std::ops::Deref>::Target: objc::Message + Sized, + { + msg_send ! (* self , f : arg1 r#as : arg2) + } +} diff --git a/bindgen-tests/tests/headers/objc_escape.h b/bindgen-tests/tests/headers/objc_escape.h new file mode 100644 index 00000000..184d1da8 --- /dev/null +++ b/bindgen-tests/tests/headers/objc_escape.h @@ -0,0 +1,6 @@ +// bindgen-flags: -- -x objective-c +// bindgen-osx-only + +@interface A +-(void)f:(int)arg1 as:(int)arg2; +@end diff --git a/bindgen/ir/objc.rs b/bindgen/ir/objc.rs index 0845ad0f..7afa959b 100644 --- a/bindgen/ir/objc.rs +++ b/bindgen/ir/objc.rs @@ -261,7 +261,17 @@ impl ObjCMethod { if name.is_empty() { None } else { - Some(Ident::new(name, Span::call_site())) + // Try to parse the current name as an identifier. This might fail if the + // name is a keyword so we try to prepend "r#" to it and parse again. If + // this also fails, we panic with the first error. + Some( + syn::parse_str::<Ident>(name) + .or_else(|err| { + syn::parse_str::<Ident>(&format!("r#{}", name)) + .map_err(|_| err) + }) + .expect("Invalid identifier"), + ) } }) .collect(); |