diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 4b51d21603..7ae202bf96 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3806,7 +3806,7 @@ fn objc_method_codegen( } } else { let fn_args = fn_args.clone(); - let args = iter::once(quote! { self }).chain(fn_args.into_iter()); + let args = iter::once(quote! { &self }).chain(fn_args.into_iter()); quote! { ( #( #args ),* ) #fn_ret } @@ -3825,7 +3825,7 @@ fn objc_method_codegen( } } else { quote! { - msg_send!(self, #methods_and_args) + msg_send!(*self, #methods_and_args) } }; @@ -3901,7 +3901,7 @@ impl CodeGenerator for ObjCInterface { if !self.is_category() && !self.is_protocol() { let struct_block = quote! { #[repr(transparent)] - #[derive(Clone, Copy)] + #[derive(Clone)] pub struct #class_name(pub id); impl std::ops::Deref for #class_name { type Target = objc::runtime::Object; @@ -3962,6 +3962,17 @@ impl CodeGenerator for ObjCInterface { } }; result.push(impl_trait); + if !parent.is_template() { + let parent_struct_name = ctx.rust_ident(parent.name()); + let from_block = quote! { + impl From<#class_name> for #parent_struct_name { + fn from(child: #class_name) -> #parent_struct_name { + #parent_struct_name(child.0) + } + } + }; + result.push(from_block); + } parent.parent_class } else { None diff --git a/tests/expectations/tests/libclang-9/objc_inheritance.rs b/tests/expectations/tests/libclang-9/objc_inheritance.rs index cd2b085dc3..ef16325e15 100644 --- a/tests/expectations/tests/libclang-9/objc_inheritance.rs +++ b/tests/expectations/tests/libclang-9/objc_inheritance.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -28,7 +28,7 @@ impl Foo { impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref {} #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Bar(pub id); impl std::ops::Deref for Bar { type Target = objc::runtime::Object; @@ -43,10 +43,15 @@ impl Bar { } } impl IFoo for Bar {} +impl From for Foo { + fn from(child: Bar) -> Foo { + Foo(child.0) + } +} impl IBar for Bar {} pub trait IBar: Sized + std::ops::Deref {} #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Baz(pub id); impl std::ops::Deref for Baz { type Target = objc::runtime::Object; @@ -61,6 +66,16 @@ impl Baz { } } impl IBar for Baz {} +impl From for Bar { + fn from(child: Baz) -> Bar { + Bar(child.0) + } +} impl IFoo for Baz {} +impl From for Foo { + fn from(child: Baz) -> Foo { + Foo(child.0) + } +} impl IBaz for Baz {} pub trait IBaz: Sized + std::ops::Deref {} diff --git a/tests/expectations/tests/libclang-9/objc_template.rs b/tests/expectations/tests/libclang-9/objc_template.rs index 09cc739c1c..88cf209bdf 100644 --- a/tests/expectations/tests/libclang-9/objc_template.rs +++ b/tests/expectations/tests/libclang-9/objc_template.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -27,15 +27,15 @@ impl Foo { } impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { - unsafe fn get(self) -> u64 + unsafe fn get(&self) -> u64 where ::Target: objc::Message + Sized, { - msg_send!(self, get) + msg_send!(*self, get) } } #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct FooMultiGeneric(pub id); impl std::ops::Deref for FooMultiGeneric { type Target = objc::runtime::Object; @@ -56,10 +56,10 @@ impl pub trait IFooMultiGeneric: Sized + std::ops::Deref { - unsafe fn objectForKey_(self, key: u64) -> u64 + unsafe fn objectForKey_(&self, key: u64) -> u64 where ::Target: objc::Message + Sized, { - msg_send!(self, objectForKey: key) + msg_send!(*self, objectForKey: key) } } diff --git a/tests/expectations/tests/objc_category.rs b/tests/expectations/tests/objc_category.rs index 2c39be96be..e0328c708f 100644 --- a/tests/expectations/tests/objc_category.rs +++ b/tests/expectations/tests/objc_category.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -27,19 +27,19 @@ impl Foo { } impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { - unsafe fn method(self) + unsafe fn method(&self) where ::Target: objc::Message + Sized, { - msg_send!(self, method) + msg_send!(*self, method) } } impl Foo_BarCategory for Foo {} pub trait Foo_BarCategory: Sized + std::ops::Deref { - unsafe fn categoryMethod(self) + unsafe fn categoryMethod(&self) where ::Target: objc::Message + Sized, { - msg_send!(self, categoryMethod) + msg_send!(*self, categoryMethod) } } diff --git a/tests/expectations/tests/objc_class.rs b/tests/expectations/tests/objc_class.rs index a1de91fb99..5a8a71d164 100644 --- a/tests/expectations/tests/objc_class.rs +++ b/tests/expectations/tests/objc_class.rs @@ -14,7 +14,7 @@ extern "C" { pub static mut fooVar: Foo; } #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -30,10 +30,10 @@ impl Foo { } impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { - unsafe fn method(self) + unsafe fn method(&self) where ::Target: objc::Message + Sized, { - msg_send!(self, method) + msg_send!(*self, method) } } diff --git a/tests/expectations/tests/objc_class_method.rs b/tests/expectations/tests/objc_class_method.rs index d28a233da2..d1f39b0c7d 100644 --- a/tests/expectations/tests/objc_class_method.rs +++ b/tests/expectations/tests/objc_class_method.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; diff --git a/tests/expectations/tests/objc_interface.rs b/tests/expectations/tests/objc_interface.rs index 7cabf762af..c5ba2758b9 100644 --- a/tests/expectations/tests/objc_interface.rs +++ b/tests/expectations/tests/objc_interface.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; diff --git a/tests/expectations/tests/objc_interface_type.rs b/tests/expectations/tests/objc_interface_type.rs index e8a1596378..2585df6ec1 100644 --- a/tests/expectations/tests/objc_interface_type.rs +++ b/tests/expectations/tests/objc_interface_type.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; diff --git a/tests/expectations/tests/objc_method.rs b/tests/expectations/tests/objc_method.rs index e24768d28e..7c4fbd4309 100644 --- a/tests/expectations/tests/objc_method.rs +++ b/tests/expectations/tests/objc_method.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -27,48 +27,48 @@ impl Foo { } impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { - unsafe fn method(self) + unsafe fn method(&self) where ::Target: objc::Message + Sized, { - msg_send!(self, method) + msg_send!(*self, method) } - unsafe fn methodWithInt_(self, foo: ::std::os::raw::c_int) + unsafe fn methodWithInt_(&self, foo: ::std::os::raw::c_int) where ::Target: objc::Message + Sized, { - msg_send!(self, methodWithInt: foo) + msg_send!(*self, methodWithInt: foo) } - unsafe fn methodWithFoo_(self, foo: Foo) + unsafe fn methodWithFoo_(&self, foo: Foo) where ::Target: objc::Message + Sized, { - msg_send!(self, methodWithFoo: foo) + msg_send!(*self, methodWithFoo: foo) } - unsafe fn methodReturningInt(self) -> ::std::os::raw::c_int + unsafe fn methodReturningInt(&self) -> ::std::os::raw::c_int where ::Target: objc::Message + Sized, { - msg_send!(self, methodReturningInt) + msg_send!(*self, methodReturningInt) } - unsafe fn methodReturningFoo(self) -> Foo + unsafe fn methodReturningFoo(&self) -> Foo where ::Target: objc::Message + Sized, { - msg_send!(self, methodReturningFoo) + msg_send!(*self, methodReturningFoo) } unsafe fn methodWithArg1_andArg2_andArg3_( - self, + &self, intvalue: ::std::os::raw::c_int, ptr: *mut ::std::os::raw::c_char, floatvalue: f32, ) where ::Target: objc::Message + Sized, { - msg_send ! ( self , methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue ) + msg_send ! ( * self , methodWithArg1 : intvalue andArg2 : ptr andArg3 : floatvalue ) } unsafe fn methodWithAndWithoutKeywords_arg2Name__arg4Name_( - self, + &self, arg1: ::std::os::raw::c_int, arg2: f32, arg3: f32, @@ -77,7 +77,7 @@ pub trait IFoo: Sized + std::ops::Deref { where ::Target: objc::Message + Sized, { - msg_send ! ( self , methodWithAndWithoutKeywords : arg1 arg2Name : arg2 arg3 : arg3 arg4Name : arg4 ) + msg_send ! ( * self , methodWithAndWithoutKeywords : arg1 arg2Name : arg2 arg3 : arg3 arg4Name : arg4 ) } } pub type instancetype = id; diff --git a/tests/expectations/tests/objc_method_clash.rs b/tests/expectations/tests/objc_method_clash.rs index ba741f8d3a..8370f33fc2 100644 --- a/tests/expectations/tests/objc_method_clash.rs +++ b/tests/expectations/tests/objc_method_clash.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -27,11 +27,11 @@ impl Foo { } impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { - unsafe fn foo(self) + unsafe fn foo(&self) where ::Target: objc::Message + Sized, { - msg_send!(self, foo) + msg_send!(*self, foo) } unsafe fn class_foo() where diff --git a/tests/expectations/tests/objc_pointer_return_types.rs b/tests/expectations/tests/objc_pointer_return_types.rs index 0f222c8b48..c9b6b52a6b 100644 --- a/tests/expectations/tests/objc_pointer_return_types.rs +++ b/tests/expectations/tests/objc_pointer_return_types.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Bar(pub id); impl std::ops::Deref for Bar { type Target = objc::runtime::Object; @@ -28,7 +28,7 @@ impl Bar { impl IBar for Bar {} pub trait IBar: Sized + std::ops::Deref {} #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -44,11 +44,11 @@ impl Foo { } impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { - unsafe fn methodUsingBar_(self, my_bar: Bar) + unsafe fn methodUsingBar_(&self, my_bar: Bar) where ::Target: objc::Message + Sized, { - msg_send!(self, methodUsingBar: my_bar) + msg_send!(*self, methodUsingBar: my_bar) } unsafe fn methodReturningBar() -> Bar where diff --git a/tests/expectations/tests/objc_property_fnptr.rs b/tests/expectations/tests/objc_property_fnptr.rs index b9bcf306d8..85f18e9c18 100644 --- a/tests/expectations/tests/objc_property_fnptr.rs +++ b/tests/expectations/tests/objc_property_fnptr.rs @@ -11,7 +11,7 @@ extern crate objc; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object; @@ -28,7 +28,7 @@ impl Foo { impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { unsafe fn func( - self, + &self, ) -> ::std::option::Option< unsafe extern "C" fn( arg1: ::std::os::raw::c_char, @@ -39,10 +39,10 @@ pub trait IFoo: Sized + std::ops::Deref { where ::Target: objc::Message + Sized, { - msg_send!(self, func) + msg_send!(*self, func) } unsafe fn setFunc_( - self, + &self, func: ::std::option::Option< unsafe extern "C" fn( arg1: ::std::os::raw::c_char, @@ -53,6 +53,6 @@ pub trait IFoo: Sized + std::ops::Deref { ) where ::Target: objc::Message + Sized, { - msg_send!(self, setFunc: func) + msg_send!(*self, setFunc: func) } } diff --git a/tests/expectations/tests/objc_protocol.rs b/tests/expectations/tests/objc_protocol.rs index 5a659b2cbb..e68ddcc1d2 100644 --- a/tests/expectations/tests/objc_protocol.rs +++ b/tests/expectations/tests/objc_protocol.rs @@ -12,7 +12,7 @@ extern crate objc; pub type id = *mut objc::runtime::Object; pub trait PFoo: Sized + std::ops::Deref {} #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct Foo(pub id); impl std::ops::Deref for Foo { type Target = objc::runtime::Object;