summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poveda Ruiz <31802960+pvdrz@users.noreply.github.com>2022-11-23 12:48:24 -0500
committerGitHub <noreply@github.com>2022-11-23 12:48:24 -0500
commit6e5a666507bb5f4611dc31ca2e11e73cb5ffdbd1 (patch)
tree52fcbafb76cec8a149703d9a40789ff4957c9d39
parentc51591941e18a75c312c7c237c4969dd22c40467 (diff)
Escape method fragments that happen to be rust keywords (#2359)
-rw-r--r--bindgen-tests/tests/expectations/tests/objc_escape.rs38
-rw-r--r--bindgen-tests/tests/headers/objc_escape.h6
-rw-r--r--bindgen/ir/objc.rs12
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();