diff options
author | Christian Poveda Ruiz <31802960+pvdrz@users.noreply.github.com> | 2022-11-23 12:48:24 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-23 12:48:24 -0500 |
commit | 6e5a666507bb5f4611dc31ca2e11e73cb5ffdbd1 (patch) | |
tree | 52fcbafb76cec8a149703d9a40789ff4957c9d39 | |
parent | c51591941e18a75c312c7c237c4969dd22c40467 (diff) |
Escape method fragments that happen to be rust keywords (#2359)
-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(); |