From b5dbed0b3859fda1fb717d9f832f44eeb00e69e8 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 23 Jun 2023 18:02:59 +0300 Subject: [PATCH 1/6] Add a few more invalid `declare_class!` macro invocation tests --- .../ui/declare_class_invalid_syntax.rs | 70 +++++- .../ui/declare_class_invalid_syntax.stderr | 228 +++++++++++++++--- 2 files changed, 256 insertions(+), 42 deletions(-) diff --git a/crates/test-ui/ui/declare_class_invalid_syntax.rs b/crates/test-ui/ui/declare_class_invalid_syntax.rs index dc18511e6..d7e38b188 100644 --- a/crates/test-ui/ui/declare_class_invalid_syntax.rs +++ b/crates/test-ui/ui/declare_class_invalid_syntax.rs @@ -6,26 +6,34 @@ use objc2::runtime::NSObject; use objc2::{declare_class, mutability, ClassType}; declare_class!( - struct CustomObject; + struct InvalidMethodDeclarations; - unsafe impl ClassType for CustomObject { + unsafe impl ClassType for InvalidMethodDeclarations { type Super = NSObject; type Mutability = mutability::InteriorMutable; - const NAME: &'static str = "CustomObject"; + const NAME: &'static str = "InvalidMethodDeclarations"; } - unsafe impl CustomObject { + unsafe impl InvalidMethodDeclarations { fn test_no_attribute() { unimplemented!() } + #[method(duplicateAttribute)] + #[method(duplicateAttribute)] + fn test_duplicate_attribute() {} + + #[method_id(duplicateAttributeDifferent)] + #[method(duplicateAttributeDifferent)] + fn test_duplicate_attribute_different() {} + #[method_id(testMethodId)] fn test_method_id_no_return() { unimplemented!() } - #[method(testInvalid)] - fn test_invalid() { + #[method(testInvalidBody)] + fn test_invalid_body() { a - } @@ -40,17 +48,47 @@ declare_class!( } } - unsafe impl CustomObject { + unsafe impl InvalidMethodDeclarations { #[method(testPub)] pub fn test_pub() {} } - unsafe impl CustomObject { + unsafe impl InvalidMethodDeclarations { + #[method(testConst)] + const fn test_const() {} + } + + unsafe impl InvalidMethodDeclarations { + #[method(testAsync)] + async fn test_async() {} + } + + unsafe impl InvalidMethodDeclarations { + #[method(testExtern)] + extern "C" fn test_extern() {} + } + + unsafe impl InvalidMethodDeclarations { + #[method(testFnFn)] + fn fn test_fn_fn() {} + } + + unsafe impl InvalidMethodDeclarations { + #[method(testGeneric)] + fn test_generic() {} + } + + unsafe impl InvalidMethodDeclarations { #[method(testNoBody)] fn test_no_body(&self); } - unsafe impl CustomObject { + unsafe impl InvalidMethodDeclarations { + #[method(testUnfinished)] + fn test_unfinished() + } + + unsafe impl InvalidMethodDeclarations { #[method_id(alloc)] fn test_method_id_bad_selector1() -> Id { unimplemented!() @@ -77,10 +115,22 @@ declare_class!( } } - unsafe impl CustomObject { + unsafe impl InvalidMethodDeclarations { #[method(dealloc)] fn deallocMethod(&mut self) {} } + + unsafe impl InvalidMethodDeclarations { + #![doc = "inner_attribute"] + } + + unsafe impl InvalidMethodDeclarations { + type TypeAlias = Self; + } + + unsafe impl InvalidMethodDeclarations { + const CONSTANT: () = (); + } ); declare_class!( diff --git a/crates/test-ui/ui/declare_class_invalid_syntax.stderr b/crates/test-ui/ui/declare_class_invalid_syntax.stderr index 748af0ab7..dc28ec3ca 100644 --- a/crates/test-ui/ui/declare_class_invalid_syntax.stderr +++ b/crates/test-ui/ui/declare_class_invalid_syntax.stderr @@ -2,9 +2,37 @@ error: must specify the desired selector using `#[method(...)]` or `#[method_id( --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { +... | + | | } + | | ); + | |_^ + | + = note: this error originates in the macro `$crate::__extract_custom_attributes_inner` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot specify the `method`/`method_id` attribute twice + --> ui/declare_class_invalid_syntax.rs + | + | / declare_class!( + | | struct InvalidMethodDeclarations; + | | + | | unsafe impl ClassType for InvalidMethodDeclarations { +... | + | | } + | | ); + | |_^ + | + = note: this error originates in the macro `$crate::__extract_custom_attributes_inner` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot specify the `method`/`method_id` attribute twice + --> ui/declare_class_invalid_syntax.rs + | + | / declare_class!( + | | struct InvalidMethodDeclarations; + | | + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -50,6 +78,66 @@ note: while trying to match `unsafe` | unsafe fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block | ^^^^^^ +error: no rules expected the token `const` + --> ui/declare_class_invalid_syntax.rs + | + | const fn test_const() {} + | ^^^^^ no rules expected this token in macro call + | +note: while trying to match `unsafe` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | unsafe fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block + | ^^^^^^ + +error: no rules expected the token `async` + --> ui/declare_class_invalid_syntax.rs + | + | async fn test_async() {} + | ^^^^^ no rules expected this token in macro call + | +note: while trying to match `unsafe` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | unsafe fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block + | ^^^^^^ + +error: no rules expected the token `extern` + --> ui/declare_class_invalid_syntax.rs + | + | extern "C" fn test_extern() {} + | ^^^^^^ no rules expected this token in macro call + | +note: while trying to match `unsafe` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | unsafe fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block + | ^^^^^^ + +error: no rules expected the token `test_fn_fn` + --> ui/declare_class_invalid_syntax.rs + | + | fn fn test_fn_fn() {} + | ^^^^^^^^^^ no rules expected this token in macro call + | +note: while trying to match `(` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block + | ^ + +error: no rules expected the token `<` + --> ui/declare_class_invalid_syntax.rs + | + | fn test_generic() {} + | ^ no rules expected this token in macro call + | +note: while trying to match `(` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block + | ^ + error: no rules expected the token `;` --> ui/declare_class_invalid_syntax.rs | @@ -62,13 +150,25 @@ note: while trying to match meta-variable `$body:block` | fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block | ^^^^^^^^^^^ +error: unexpected end of macro invocation + --> ui/declare_class_invalid_syntax.rs + | + | fn test_unfinished() + | ^ missing tokens in macro arguments + | +note: while trying to match meta-variable `$body:block` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | fn $name:ident($($args:tt)*) $(-> $ret:ty)? $body:block + | ^^^^^^^^^^^ + error: `#[method_id(alloc)]` is not supported. Use `#[method(alloc)]` and do the memory management yourself --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -80,9 +180,9 @@ error: `#[method_id(retain)]` is not supported. Use `#[method(retain)]` and do t --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -94,9 +194,9 @@ error: `#[method_id(release)]` is not supported. Use `#[method(release)]` and do --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -108,9 +208,9 @@ error: `#[method_id(autorelease)]` is not supported. Use `#[method(autorelease)] --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -122,9 +222,9 @@ error: `#[method_id(dealloc)]` is not supported. Add an instance variable with a --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -136,9 +236,9 @@ error: `#[method(dealloc)]` is not supported. Implement `Drop` for the type inst --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -146,13 +246,77 @@ error: `#[method(dealloc)]` is not supported. Implement `Drop` for the type inst | = note: this error originates in the macro `$crate::__declare_class_register_out` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) +error: no rules expected the token `!` + --> ui/declare_class_invalid_syntax.rs + | + | #![doc = "inner_attribute"] + | ^ no rules expected this token in macro call + | +note: while trying to match `[` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | $(#[$($m:tt)*])* + | ^ + +error: no rules expected the token `type` + --> ui/declare_class_invalid_syntax.rs + | + | type TypeAlias = Self; + | ^^^^ no rules expected this token in macro call + | +note: while trying to match `)` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | ($($macro_arg:tt)*) + | ^ + +error: no rules expected the token `const` + --> ui/declare_class_invalid_syntax.rs + | + | const CONSTANT: () = (); + | ^^^^^ no rules expected this token in macro call + | +note: while trying to match `)` + --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs + | + | ($($macro_arg:tt)*) + | ^ + error: must specify the desired selector using `#[method(...)]` or `#[method_id(...)]` --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; + | | + | | unsafe impl ClassType for InvalidMethodDeclarations { +... | + | | } + | | ); + | |_^ + | + = note: this error originates in the macro `$crate::__extract_custom_attributes_inner` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot specify the `method`/`method_id` attribute twice + --> ui/declare_class_invalid_syntax.rs + | + | / declare_class!( + | | struct InvalidMethodDeclarations; + | | + | | unsafe impl ClassType for InvalidMethodDeclarations { +... | + | | } + | | ); + | |_^ + | + = note: this error originates in the macro `$crate::__extract_custom_attributes_inner` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot specify the `method`/`method_id` attribute twice + --> ui/declare_class_invalid_syntax.rs + | + | / declare_class!( + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -164,9 +328,9 @@ error: `#[method_id(...)]` must have a return type --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -190,9 +354,9 @@ error: no rules expected the token `)` --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); @@ -283,47 +447,47 @@ note: while trying to match `type` | type Mutability = $mutability:ty; | ^^^^ -error[E0599]: no function or associated item named `test_pattern` found for struct `CustomObject` in the current scope +error[E0599]: no function or associated item named `test_pattern` found for struct `InvalidMethodDeclarations` in the current scope --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | fn test_pattern((a, b): (u32, i32)) { - | | ^^^^^^^^^^^^ function or associated item not found in `CustomObject` + | | ^^^^^^^^^^^^ function or associated item not found in `InvalidMethodDeclarations` ... | | | } | | ); | |_- function or associated item `test_pattern` not found for this struct -error[E0599]: no function or associated item named `test_self` found for struct `CustomObject` in the current scope +error[E0599]: no function or associated item named `test_self` found for struct `InvalidMethodDeclarations` in the current scope --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | fn test_self(self) { - | | ^^^^^^^^^ function or associated item not found in `CustomObject` + | | ^^^^^^^^^ function or associated item not found in `InvalidMethodDeclarations` ... | | | } | | ); | |_- function or associated item `test_self` not found for this struct -error[E0277]: the trait bound `RetainSemantics<2>: MessageRecieveId<&AnyClass, Id>` is not satisfied +error[E0277]: the trait bound `RetainSemantics<2>: MessageRecieveId<&AnyClass, Id>` is not satisfied --> ui/declare_class_invalid_syntax.rs | | / declare_class!( - | | struct CustomObject; + | | struct InvalidMethodDeclarations; | | - | | unsafe impl ClassType for CustomObject { + | | unsafe impl ClassType for InvalidMethodDeclarations { ... | | | } | | ); - | |_^ the trait `MessageRecieveId<&AnyClass, Id>` is not implemented for `RetainSemantics<2>` + | |_^ the trait `MessageRecieveId<&AnyClass, Id>` is not implemented for `RetainSemantics<2>` | = help: the following other types implement trait `MessageRecieveId`: as MessageRecieveId> From 503aeceb686503d92fa188613bcbaa14a7f4297a Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 31 Jul 2023 12:47:31 +0200 Subject: [PATCH 2/6] Small cleanup and test improvements --- .../src/__macro_helpers/declare_class.rs | 9 +---- crates/objc2/src/encode/__unstable.rs | 11 ++++-- crates/objc2/src/message/mod.rs | 2 +- crates/objc2/src/rc/id.rs | 13 ++++++- crates/objc2/tests/declare_class_self.rs | 29 ++++++++++---- crates/objc2/tests/no_prelude.rs | 2 + crates/objc2/tests/use_macros.rs | 5 +-- .../ui/declare_class_invalid_receiver.rs | 39 +++++++++++-------- .../ui/declare_class_invalid_receiver.stderr | 30 ++++++++++++++ 9 files changed, 100 insertions(+), 40 deletions(-) diff --git a/crates/objc2/src/__macro_helpers/declare_class.rs b/crates/objc2/src/__macro_helpers/declare_class.rs index 274fc981b..40b7ceaf0 100644 --- a/crates/objc2/src/__macro_helpers/declare_class.rs +++ b/crates/objc2/src/__macro_helpers/declare_class.rs @@ -1,6 +1,3 @@ -use core::mem::ManuallyDrop; -use core::ptr; - use crate::declare::__IdReturnValue; use crate::rc::{Allocated, Id}; use crate::{ClassType, Message, MessageReceiver}; @@ -85,7 +82,7 @@ pub trait MaybeOptionId: MaybeUnwrap { impl MaybeOptionId for Id { #[inline] fn consumed_return(self) -> __IdReturnValue { - let ptr: *mut T = Id::consume_as_ptr(ManuallyDrop::new(self)); + let ptr: *mut T = Id::consume_as_ptr(self); __IdReturnValue(ptr.cast()) } @@ -99,9 +96,7 @@ impl MaybeOptionId for Id { impl MaybeOptionId for Option> { #[inline] fn consumed_return(self) -> __IdReturnValue { - let ptr: *mut T = self - .map(|this| Id::consume_as_ptr(ManuallyDrop::new(this))) - .unwrap_or_else(ptr::null_mut); + let ptr: *mut T = Id::consume_as_ptr_option(self); __IdReturnValue(ptr.cast()) } diff --git a/crates/objc2/src/encode/__unstable.rs b/crates/objc2/src/encode/__unstable.rs index 90f89b405..52f0e901c 100644 --- a/crates/objc2/src/encode/__unstable.rs +++ b/crates/objc2/src/encode/__unstable.rs @@ -30,21 +30,26 @@ mod return_private { /// /// We currently don't need a similar `EncodeArgument` trait, but we might in /// the future. +/// +/// +/// # Safety +/// +/// Similar to [`Encode`]. // // Note: While this is not public, it is still a breaking change to change, // since `block2` relies on it. -pub trait EncodeReturn: return_private::Sealed { +pub unsafe trait EncodeReturn: return_private::Sealed { /// The Objective-C type-encoding for this type. const ENCODING_RETURN: Encoding; } impl return_private::Sealed for () {} -impl EncodeReturn for () { +unsafe impl EncodeReturn for () { const ENCODING_RETURN: Encoding = Encoding::Void; } impl return_private::Sealed for T {} -impl EncodeReturn for T { +unsafe impl EncodeReturn for T { const ENCODING_RETURN: Encoding = T::ENCODING; } diff --git a/crates/objc2/src/message/mod.rs b/crates/objc2/src/message/mod.rs index aadcf3673..3db849cff 100644 --- a/crates/objc2/src/message/mod.rs +++ b/crates/objc2/src/message/mod.rs @@ -454,7 +454,7 @@ unsafe impl MessageReceiver for ManuallyDrop> { #[inline] fn __as_raw_receiver(self) -> *mut AnyObject { - Id::consume_as_ptr(self).cast() + Id::consume_as_ptr(ManuallyDrop::into_inner(self)).cast() } } diff --git a/crates/objc2/src/rc/id.rs b/crates/objc2/src/rc/id.rs index 675680252..bb933766d 100644 --- a/crates/objc2/src/rc/id.rs +++ b/crates/objc2/src/rc/id.rs @@ -239,8 +239,17 @@ impl Id { } #[inline] - pub(crate) fn consume_as_ptr(this: ManuallyDrop) -> *mut T { - this.ptr.as_ptr() + pub(crate) fn consume_as_ptr(this: Self) -> *mut T { + ManuallyDrop::new(this).ptr.as_ptr() + } + + #[inline] + pub(crate) fn consume_as_ptr_option(this: Option) -> *mut T + where + T: Sized, + { + this.map(|this| Id::consume_as_ptr(this)) + .unwrap_or_else(ptr::null_mut) } } diff --git a/crates/objc2/tests/declare_class_self.rs b/crates/objc2/tests/declare_class_self.rs index 7f4b39d39..6915e5f0f 100644 --- a/crates/objc2/tests/declare_class_self.rs +++ b/crates/objc2/tests/declare_class_self.rs @@ -1,7 +1,6 @@ //! To remind myself that `Self` needs to work in methods in `declare_class!`, -//! and hence we _must_ implement things by changing the generated method, we -//! can't just create an internal helper function (since we can't name the -//! types of such a function)! +//! and hence whenever we name any of the types involved in this, we need to +//! do it in a context where `Self` works. use objc2::rc::{Allocated, Id}; use objc2::runtime::NSObject; use objc2::{declare_class, mutability, ClassType}; @@ -14,6 +13,14 @@ impl GetSameType for T { type SameType = T; } +trait GetId { + type IdType; +} + +impl GetId for T { + type IdType = Id; +} + macro_rules! get_self { () => { Self @@ -31,7 +38,7 @@ declare_class!( } unsafe impl MyTestObject { - #[method_id(init)] + #[method_id(initWith:)] fn init( _this: Allocated<::SameType>, _param: <*const Self as GetSameType>::SameType, @@ -39,8 +46,8 @@ declare_class!( unimplemented!() } - #[method(compare:)] - fn compare(&self, _other: &Self) -> bool { + #[method(isEqual:)] + fn is_equal(&self, _other: &Self) -> bool { unimplemented!() } @@ -49,7 +56,15 @@ declare_class!( fn test4(_this: &<(Self) as GetSameType>::SameType) -> Id { unimplemented!() } + + #[method_id(test5)] + fn test5(&self) -> ::IdType { + unimplemented!() + } } ); -fn main() {} +#[test] +fn create_class() { + let _ = MyTestObject::class(); +} diff --git a/crates/objc2/tests/no_prelude.rs b/crates/objc2/tests/no_prelude.rs index 16aa6f777..cf79c10f5 100644 --- a/crates/objc2/tests/no_prelude.rs +++ b/crates/objc2/tests/no_prelude.rs @@ -143,11 +143,13 @@ new_objc2::extern_protocol!( unsafe impl ProtocolType for dyn CustomProtocol {} ); +#[test] pub fn test_selector() { let _sel = new_objc2::sel!(abc); let _sel = new_objc2::sel!(abc:def:); } +#[test] pub fn test_class() { let _class = new_objc2::class!(NSObject); } diff --git a/crates/objc2/tests/use_macros.rs b/crates/objc2/tests/use_macros.rs index b3edaceb8..9b6b13f41 100644 --- a/crates/objc2/tests/use_macros.rs +++ b/crates/objc2/tests/use_macros.rs @@ -3,7 +3,7 @@ use objc2::runtime::{AnyClass, NSObject}; use objc2::{class, declare_class, msg_send, sel, ClassType}; declare_class!( - struct MyObject; + pub struct MyObject; unsafe impl ClassType for MyObject { type Super = NSObject; @@ -28,8 +28,7 @@ fn use_sel() { let _sel = sel!(setObject:forKey:); } -#[allow(unused)] -fn test_msg_send_comma_handling(obj: &MyObject, superclass: &AnyClass) { +pub fn test_msg_send_comma_handling(obj: &MyObject, superclass: &AnyClass) { unsafe { let _: () = msg_send![obj, a]; let _: () = msg_send![obj, a,]; diff --git a/crates/test-ui/ui/declare_class_invalid_receiver.rs b/crates/test-ui/ui/declare_class_invalid_receiver.rs index b870458f6..78d6ca5eb 100644 --- a/crates/test-ui/ui/declare_class_invalid_receiver.rs +++ b/crates/test-ui/ui/declare_class_invalid_receiver.rs @@ -1,5 +1,5 @@ use objc2::rc::{Allocated, Id}; -use objc2::runtime::NSObject; +use objc2::runtime::{AnyClass, NSObject}; use objc2::{declare_class, mutability, ClassType}; declare_class!( @@ -12,47 +12,52 @@ declare_class!( } unsafe impl CustomObject { - #[method(test1)] - fn test1(self: Box) { + #[method(testBox)] + fn test_box(self: Box) { unimplemented!() } - #[method(test2)] - fn test2(this: Id) { + #[method(testIdSelf)] + fn test_id_self(this: Id) { unimplemented!() } - #[method(test3)] - fn test3(this: Self) { + #[method(testSelf)] + fn test_self(this: Self) { + unimplemented!() + } + + #[method(testClass)] + fn test_class(this: &AnyClass) { unimplemented!() } } unsafe impl CustomObject { - #[method_id(test4)] - fn test4(self: Box) -> Id { + #[method_id(testBoxId)] + fn test_box_id(self: Box) -> Id { unimplemented!() } - #[method_id(test5)] - fn test5(this: Id) -> Id { + #[method_id(testIdSelfId)] + fn test_id_self_id(this: Id) -> Id { unimplemented!() } - #[method_id(test6)] - fn test6(this: Self) -> Id { + #[method_id(testSelfId)] + fn test_self_id(this: Self) -> Id { unimplemented!() } } unsafe impl CustomObject { - #[method_id(test7)] - fn test7(this: Allocated) -> Id { + #[method_id(testAlloc)] + fn test_alloc(this: Allocated) -> Id { unimplemented!() } - #[method_id(initTest8)] - fn test8(&self) -> Id { + #[method_id(initTestNotAlloc)] + fn test_init_not_alloc(&self) -> Id { unimplemented!() } } diff --git a/crates/test-ui/ui/declare_class_invalid_receiver.stderr b/crates/test-ui/ui/declare_class_invalid_receiver.stderr index 5c093441c..c651ce5dc 100644 --- a/crates/test-ui/ui/declare_class_invalid_receiver.stderr +++ b/crates/test-ui/ui/declare_class_invalid_receiver.stderr @@ -103,6 +103,36 @@ note: required by a bound in `ClassBuilder::add_method` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ClassBuilder::add_method` = note: this error originates in the macro `$crate::__declare_class_register_out` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0277]: the trait bound `AnyClass: Message` is not satisfied + --> ui/declare_class_invalid_receiver.rs + | + | / declare_class!( + | | struct CustomObject; + | | + | | unsafe impl ClassType for CustomObject { +... | + | | } + | | ); + | |_^ the trait `Message` is not implemented for `AnyClass` + | + = help: the following other types implement trait `Message`: + AnyObject + CustomObject + Exception + NSObject + ProtocolObject

+ __NSProxy + __RcTestObject +note: required by a bound in `ClassBuilder::add_method` + --> $WORKSPACE/crates/objc2/src/declare/mod.rs + | + | pub unsafe fn add_method(&mut self, sel: Sel, func: F) + | ---------- required by a bound in this associated function + | where + | T: Message + ?Sized, + | ^^^^^^^ required by this bound in `ClassBuilder::add_method` + = note: this error originates in the macro `$crate::__rewrite_self_arg_inner` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0277]: the trait bound `extern "C" fn(Box, objc2::runtime::Sel) -> __IdReturnValue: MethodImplementation` is not satisfied --> ui/declare_class_invalid_receiver.rs | From 419574b4fdd37c21206cd4d827634f8ca2be38e5 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 31 Jul 2023 12:05:45 +0200 Subject: [PATCH 3/6] Fix incorrect `cfg` attribute in tests --- crates/objc2/src/declare/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/objc2/src/declare/mod.rs b/crates/objc2/src/declare/mod.rs index 9e0df3e45..b38290146 100644 --- a/crates/objc2/src/declare/mod.rs +++ b/crates/objc2/src/declare/mod.rs @@ -832,10 +832,7 @@ mod tests { } #[test] - #[cfg_attr( - debug_assertions, - should_panic = "selector xyz: accepts 1 arguments, but function accepts 0" - )] + #[should_panic = "selector xyz: accepts 1 arguments, but function accepts 0"] fn wrong_arguments() { let cls = test_utils::custom_class(); let mut builder = ClassBuilder::new("TestClassBuilderWrongArguments", cls).unwrap(); From a9b44188b58c3de2ad0f0fdcf4810d742a61f41f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 31 Jul 2023 12:19:30 +0200 Subject: [PATCH 4/6] Make assembly test failures easier to diagnose --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c227572c3..edd09f887 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -254,6 +254,11 @@ jobs: - name: Run all assembly tests if: ${{ env.FULL }} run: ./helper-scripts/run-assembly-tests.sh + env: + TEST_OVERWRITE: 1 + + - name: Check diff + run: git diff --exit-code header-translator: name: Verify header translator output From 413929d81d38ccb8e40c73e187f44629e5d975d2 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 31 Jul 2023 13:55:14 +0200 Subject: [PATCH 5/6] Fix assembly $RUSTC replacing --- .../crates/test_declare_class/expected/apple-aarch64.s | 2 +- .../crates/test_declare_class/expected/apple-armv7.s | 2 +- .../crates/test_declare_class/expected/apple-armv7s.s | 2 +- .../crates/test_declare_class/expected/apple-old-x86.s | 2 +- .../crates/test_declare_class/expected/apple-x86.s | 2 +- crates/test-assembly/src/lib.rs | 10 ++++++++++ 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s b/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s index 9468ee1e3..271e785ac 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s @@ -783,7 +783,7 @@ l_anon.[ID].2: .ascii "called `Option::unwrap()` on a `None` value" l_anon.[ID].3: - .ascii "/Users/madsmarquart/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/sync/once.rs" + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 3, 0x0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s index 3e159664e..c89f6b361 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s @@ -711,7 +711,7 @@ l_anon.[ID].2: .ascii "called `Option::unwrap()` on a `None` value" l_anon.[ID].3: - .ascii "/Users/madsmarquart/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/sync/once.rs" + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s index 32b6c2e3c..9f475c54a 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s @@ -714,7 +714,7 @@ l_anon.[ID].2: .ascii "called `Option::unwrap()` on a `None` value" l_anon.[ID].3: - .ascii "/Users/madsmarquart/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/sync/once.rs" + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s b/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s index 6959cefe8..87a6a5744 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s @@ -736,7 +736,7 @@ l_anon.[ID].2: .ascii "called `Option::unwrap()` on a `None` value" l_anon.[ID].3: - .ascii "/Users/madsmarquart/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/sync/once.rs" + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s b/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s index b4a2d7af0..31b87f358 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s @@ -736,7 +736,7 @@ l_anon.[ID].2: .ascii "called `Option::unwrap()` on a `None` value" l_anon.[ID].3: - .ascii "/Users/madsmarquart/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/sync/once.rs" + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 diff --git a/crates/test-assembly/src/lib.rs b/crates/test-assembly/src/lib.rs index 9208c67d1..5c6fb8e64 100644 --- a/crates/test-assembly/src/lib.rs +++ b/crates/test-assembly/src/lib.rs @@ -64,6 +64,8 @@ pub fn read_assembly>(path: P, package_path: &Path) -> io::Result .as_os_str() .to_str() .unwrap(); + + // Replace paths let s = s.replace(workspace_dir, "$WORKSPACE"); let s = s.replace( package_path @@ -79,6 +81,14 @@ pub fn read_assembly>(path: P, package_path: &Path) -> io::Result let s = regex::Regex::new(r"/rustc/[0-9a-f]*/") .unwrap() .replace_all(&s, |_: ®ex::Captures| "$RUSTC/"); + let s = regex::Regex::new(r"/.*/rustlib/src/rust/") + .unwrap() + .replace_all(&s, |_: ®ex::Captures| "$RUSTC/"); + + // HACK: Make location data the same no matter which platform generated + // the data. + let s = s.replace(".asciz\t\"}", ".asciz\t\"t"); + // HACK: Replace Objective-C image info for simulator targets let s = s.replace( ".asciz\t\"\\000\\000\\000\\000`\\000\\000\"", From e57230904961b86417e907325a39b1a2573ab1af Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 31 Jul 2023 12:24:44 +0200 Subject: [PATCH 6/6] Properly hide __RcTestObject and __ThreadTestData --- crates/objc2/src/rc/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/objc2/src/rc/mod.rs b/crates/objc2/src/rc/mod.rs index 24b310ce7..934c9a21a 100644 --- a/crates/objc2/src/rc/mod.rs +++ b/crates/objc2/src/rc/mod.rs @@ -63,5 +63,6 @@ pub use self::autorelease::{ }; pub use self::id::Id; pub use self::id_traits::{DefaultId, IdFromIterator, IdIntoIterator}; +#[doc(hidden)] pub use self::test_object::{__RcTestObject, __ThreadTestData}; pub use self::weak_id::WeakId;