diff --git a/crates/objc2/CHANGELOG.md b/crates/objc2/CHANGELOG.md index 9b5eec77e..710f53db8 100644 --- a/crates/objc2/CHANGELOG.md +++ b/crates/objc2/CHANGELOG.md @@ -42,6 +42,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). In particular automatic conversion of `bool` is not supported in `MessageReceiver`. +* Relaxed the requirements for receivers in `MethodImplementation`; now, + anything that implements `MessageReceiver` can be used as the receiver of + a method. ### Deprecated * Soft deprecated using `msg_send!` without a comma between arguments (i.e. diff --git a/crates/objc2/src/macros/declare_class.rs b/crates/objc2/src/macros/declare_class.rs index c93306645..44aa7b3c6 100644 --- a/crates/objc2/src/macros/declare_class.rs +++ b/crates/objc2/src/macros/declare_class.rs @@ -82,10 +82,9 @@ /// /// On instance methods, you can freely choose between different types of /// receivers, e.g. `&self`, `this: *const Self`, `&mut self`, and so on. Note -/// though that using raw pointers requires the function to be `unsafe`, and -/// using `&mut self` requires the class' mutability to be +/// though that using `&mut self` requires the class' mutability to be /// [`IsAllowedMutable`]. -/// If you require mutation of your class' instance variables, consider using +/// If you need mutation of your class' instance variables, consider using /// [`Cell`] or similar instead. /// /// The desired selector can be specified using the `#[method(my:selector:)]` diff --git a/crates/objc2/src/runtime/method_implementation.rs b/crates/objc2/src/runtime/method_implementation.rs index 602a9e656..73e2dd1b6 100644 --- a/crates/objc2/src/runtime/method_implementation.rs +++ b/crates/objc2/src/runtime/method_implementation.rs @@ -2,9 +2,8 @@ use core::mem; use crate::__macro_helpers::IdReturnValue; use crate::encode::{EncodeArgument, EncodeArguments, EncodeReturn, RefEncode}; -use crate::mutability::IsAllowedMutable; use crate::rc::Allocated; -use crate::runtime::{AnyClass, Imp, Sel}; +use crate::runtime::{Imp, MessageReceiver, Sel}; use crate::Message; mod private { @@ -19,7 +18,7 @@ mod private { // Note: `Sized` is intentionally added to make the trait not object safe. pub trait MethodImplementation: private::Sealed + Sized { /// The callee type of the method. - type Callee: RefEncode + ?Sized; + type Callee: ?Sized + RefEncode; /// The return type of the method. type Ret: EncodeReturn; /// The argument types of the method. @@ -29,67 +28,39 @@ pub trait MethodImplementation: private::Sealed + Sized { fn __imp(self) -> Imp; } -macro_rules! method_impl_generic { - (<$($l:lifetime),*> T: $t_bound:ident $(+ $t_bound2:ident)?, $r:ident, $f:ty, $($t:ident),*) => { - impl<$($l,)* T, $r, $($t),*> private::Sealed for $f +macro_rules! method_impl_inner { + ($(($unsafe:ident))? $abi:literal; $($t:ident),*) => { + impl private::Sealed for $($unsafe)? extern $abi fn(T, Sel $(, $t)*) -> R where - T: ?Sized + $t_bound $(+ $t_bound2)?, - $r: EncodeReturn, + T: ?Sized + MessageReceiver, + R: EncodeReturn, $($t: EncodeArgument,)* {} - impl<$($l,)* T, $r, $($t),*> MethodImplementation for $f + impl MethodImplementation for $($unsafe)? extern $abi fn(T, Sel $(, $t)*) -> R where - T: ?Sized + $t_bound $(+ $t_bound2)?, - $r: EncodeReturn, + T: ?Sized + MessageReceiver, + R: EncodeReturn, $($t: EncodeArgument,)* { - type Callee = T; - type Ret = $r; - type Args = ($($t,)*); - - fn __imp(self) -> Imp { - unsafe { mem::transmute(self) } - } - } - }; -} - -macro_rules! method_impl_concrete { - (<$($l:lifetime),*> $callee:ident, $r:ident, $f:ty, $($t:ident),*) => { - impl<$($l,)* $r, $($t),*> private::Sealed for $f - where - $r: EncodeReturn, - $($t: EncodeArgument,)* - {} - - impl<$($l,)* $r, $($t),*> MethodImplementation for $f - where - $r: EncodeReturn, - $($t: EncodeArgument,)* - { - type Callee = $callee; - type Ret = $r; + type Callee = T::__Inner; + type Ret = R; type Args = ($($t,)*); fn __imp(self) -> Imp { + // SAFETY: Transmuting to an `unsafe` function pointer unsafe { mem::transmute(self) } } } - }; -} -macro_rules! method_impl_allocated { - (<> Allocated, $f:ty, $($t:ident),*) => { - #[doc(hidden)] - impl private::Sealed for $f + impl private::Sealed for $($unsafe)? extern $abi fn(Allocated, Sel $(, $t)*) -> IdReturnValue where T: ?Sized + Message, $($t: EncodeArgument,)* {} #[doc(hidden)] - impl MethodImplementation for $f + impl MethodImplementation for $($unsafe)? extern $abi fn(Allocated, Sel $(, $t)*) -> IdReturnValue where T: ?Sized + Message, $($t: EncodeArgument,)* @@ -113,29 +84,14 @@ macro_rules! method_impl_allocated { }; } -macro_rules! method_impl_abi { - ($abi:literal; $($t:ident),*) => { - method_impl_generic!(<'a> T: Message, R, extern $abi fn(&'a T, Sel $(, $t)*) -> R, $($t),*); - method_impl_generic!(<'a> T: Message + IsAllowedMutable, R, extern $abi fn(&'a mut T, Sel $(, $t)*) -> R, $($t),*); - method_impl_generic!(<> T: Message, R, unsafe extern $abi fn(*const T, Sel $(, $t)*) -> R, $($t),*); - method_impl_generic!(<> T: Message, R, unsafe extern $abi fn(*mut T, Sel $(, $t)*) -> R, $($t),*); - method_impl_generic!(<'a> T: Message, R, unsafe extern $abi fn(&'a T, Sel $(, $t)*) -> R, $($t),*); - method_impl_generic!(<'a> T: Message + IsAllowedMutable, R, unsafe extern $abi fn(&'a mut T, Sel $(, $t)*) -> R, $($t),*); - - method_impl_concrete!(<'a> AnyClass, R, extern $abi fn(&'a AnyClass, Sel $(, $t)*) -> R, $($t),*); - method_impl_concrete!(<> AnyClass, R, unsafe extern $abi fn(*const AnyClass, Sel $(, $t)*) -> R, $($t),*); - method_impl_concrete!(<'a> AnyClass, R, unsafe extern $abi fn(&'a AnyClass, Sel $(, $t)*) -> R, $($t),*); - - method_impl_allocated!(<> Allocated, extern $abi fn(Allocated, Sel $(, $t)*) -> IdReturnValue, $($t),*); - method_impl_allocated!(<> Allocated, unsafe extern $abi fn(Allocated, Sel $(, $t)*) -> IdReturnValue, $($t),*); - }; -} - macro_rules! method_impl { ($($t:ident),*) => { - method_impl_abi!("C"; $($t),*); + method_impl_inner!((unsafe) "C"; $($t),*); + method_impl_inner!("C"; $($t),*); + #[cfg(feature = "unstable-c-unwind")] + method_impl_inner!((unsafe) "C-unwind"; $($t),*); #[cfg(feature = "unstable-c-unwind")] - method_impl_abi!("C-unwind"; $($t),*); + method_impl_inner!("C-unwind"; $($t),*); }; } diff --git a/crates/objc2/tests/declare_class.rs b/crates/objc2/tests/declare_class.rs index 3136bee99..329a500f6 100644 --- a/crates/objc2/tests/declare_class.rs +++ b/crates/objc2/tests/declare_class.rs @@ -1,5 +1,5 @@ #![deny(deprecated, unreachable_code)] -use core::ptr; +use core::ptr::{self, NonNull}; use objc2::declare::IvarEncode; use objc2::mutability::{Immutable, Mutable}; @@ -538,3 +538,30 @@ fn out_param3() { fn out_param4() { OutParam::unsupported4(None); } + +#[test] +fn test_pointer_receiver_allowed() { + declare_class!( + #[derive(Debug)] + struct PointerReceiver; + + unsafe impl ClassType for PointerReceiver { + type Super = NSObject; + type Mutability = Immutable; + const NAME: &'static str = "PointerReceiver"; + } + + unsafe impl PointerReceiver { + #[method(constPtr)] + fn const_ptr(_this: *const Self) {} + + #[method(mutPtr)] + fn mut_ptr(_this: *mut Self) {} + + #[method(nonnullPtr)] + fn nonnull_ptr(_this: NonNull) {} + } + ); + + let _ = PointerReceiver::class(); +} diff --git a/crates/test-ui/ui/declare_class_invalid_receiver.stderr b/crates/test-ui/ui/declare_class_invalid_receiver.stderr index c9d056b91..42dcf27a6 100644 --- a/crates/test-ui/ui/declare_class_invalid_receiver.stderr +++ b/crates/test-ui/ui/declare_class_invalid_receiver.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `extern "C" fn(Box, objc2::runtime::Sel): MethodImplementation` is not satisfied +error[E0277]: the trait bound `Box: MessageReceiver` is not satisfied --> ui/declare_class_invalid_receiver.rs | | / declare_class!( @@ -10,19 +10,18 @@ error[E0277]: the trait bound `extern "C" fn(Box, objc2::runtime:: | | ); | | ^ | | | - | |_the trait `MethodImplementation` is not implemented for `extern "C" fn(Box, objc2::runtime::Sel)` + | |_the trait `MessageReceiver` is not implemented for `Box` | required by a bound introduced by this call | - = help: the following other types implement trait `MethodImplementation`: - unsafe extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - and $N others + = help: the following other types implement trait `MessageReceiver`: + NonNull + *const AnyClass + *const T + *mut T + &'a T + &'a mut T + &'a AnyClass + = note: required for `extern "C" fn(Box, objc2::runtime::Sel)` to implement `MethodImplementation` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -33,7 +32,7 @@ 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 `extern "C" fn(Id, objc2::runtime::Sel): MethodImplementation` is not satisfied +error[E0277]: the trait bound `Id: MessageReceiver` is not satisfied --> ui/declare_class_invalid_receiver.rs | | / declare_class!( @@ -45,19 +44,18 @@ error[E0277]: the trait bound `extern "C" fn(Id, objc2::runtime::S | | ); | | ^ | | | - | |_the trait `MethodImplementation` is not implemented for `extern "C" fn(Id, objc2::runtime::Sel)` + | |_the trait `MessageReceiver` is not implemented for `Id` | required by a bound introduced by this call | - = help: the following other types implement trait `MethodImplementation`: - unsafe extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - and $N others + = help: the following other types implement trait `MessageReceiver`: + NonNull + *const AnyClass + *const T + *mut T + &'a T + &'a mut T + &'a AnyClass + = note: required for `extern "C" fn(Id, objc2::runtime::Sel)` to implement `MethodImplementation` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -68,7 +66,7 @@ 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 `extern "C" fn(CustomObject, objc2::runtime::Sel): MethodImplementation` is not satisfied +error[E0277]: the trait bound `CustomObject: MessageReceiver` is not satisfied --> ui/declare_class_invalid_receiver.rs | | / declare_class!( @@ -80,19 +78,18 @@ error[E0277]: the trait bound `extern "C" fn(CustomObject, objc2::runtime::Sel): | | ); | | ^ | | | - | |_the trait `MethodImplementation` is not implemented for `extern "C" fn(CustomObject, objc2::runtime::Sel)` + | |_the trait `MessageReceiver` is not implemented for `CustomObject` | required by a bound introduced by this call | - = help: the following other types implement trait `MethodImplementation`: - unsafe extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - and $N others + = help: the following other types implement trait `MessageReceiver`: + NonNull + *const AnyClass + *const T + *mut T + &'a T + &'a mut T + &'a AnyClass + = note: required for `extern "C" fn(CustomObject, objc2::runtime::Sel)` to implement `MethodImplementation` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -133,7 +130,7 @@ 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::__rewrite_self_param_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 +error[E0277]: the trait bound `Box: MessageReceiver` is not satisfied --> ui/declare_class_invalid_receiver.rs | | / declare_class!( @@ -145,19 +142,18 @@ error[E0277]: the trait bound `extern "C" fn(Box, objc2::runtime:: | | ); | | ^ | | | - | |_the trait `MethodImplementation` is not implemented for `extern "C" fn(Box, objc2::runtime::Sel) -> IdReturnValue` + | |_the trait `MessageReceiver` is not implemented for `Box` | required by a bound introduced by this call | - = help: the following other types implement trait `MethodImplementation`: - unsafe extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - and $N others + = help: the following other types implement trait `MessageReceiver`: + NonNull + *const AnyClass + *const T + *mut T + &'a T + &'a mut T + &'a AnyClass + = note: required for `extern "C" fn(Box, objc2::runtime::Sel) -> IdReturnValue` to implement `MethodImplementation` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -168,7 +164,7 @@ 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 `extern "C" fn(Id, objc2::runtime::Sel) -> IdReturnValue: MethodImplementation` is not satisfied +error[E0277]: the trait bound `Id: MessageReceiver` is not satisfied --> ui/declare_class_invalid_receiver.rs | | / declare_class!( @@ -180,19 +176,18 @@ error[E0277]: the trait bound `extern "C" fn(Id, objc2::runtime::S | | ); | | ^ | | | - | |_the trait `MethodImplementation` is not implemented for `extern "C" fn(Id, objc2::runtime::Sel) -> IdReturnValue` + | |_the trait `MessageReceiver` is not implemented for `Id` | required by a bound introduced by this call | - = help: the following other types implement trait `MethodImplementation`: - unsafe extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - and $N others + = help: the following other types implement trait `MessageReceiver`: + NonNull + *const AnyClass + *const T + *mut T + &'a T + &'a mut T + &'a AnyClass + = note: required for `extern "C" fn(Id, objc2::runtime::Sel) -> IdReturnValue` to implement `MethodImplementation` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -203,7 +198,7 @@ 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 `extern "C" fn(CustomObject, objc2::runtime::Sel) -> IdReturnValue: MethodImplementation` is not satisfied +error[E0277]: the trait bound `CustomObject: MessageReceiver` is not satisfied --> ui/declare_class_invalid_receiver.rs | | / declare_class!( @@ -215,19 +210,18 @@ error[E0277]: the trait bound `extern "C" fn(CustomObject, objc2::runtime::Sel) | | ); | | ^ | | | - | |_the trait `MethodImplementation` is not implemented for `extern "C" fn(CustomObject, objc2::runtime::Sel) -> IdReturnValue` + | |_the trait `MessageReceiver` is not implemented for `CustomObject` | required by a bound introduced by this call | - = help: the following other types implement trait `MethodImplementation`: - unsafe extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - and $N others + = help: the following other types implement trait `MessageReceiver`: + NonNull + *const AnyClass + *const T + *mut T + &'a T + &'a mut T + &'a AnyClass + = note: required for `extern "C" fn(CustomObject, objc2::runtime::Sel) -> IdReturnValue` to implement `MethodImplementation` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | diff --git a/crates/test-ui/ui/declare_class_mut_self_not_mutable.stderr b/crates/test-ui/ui/declare_class_mut_self_not_mutable.stderr index 6f6cea254..7cb287282 100644 --- a/crates/test-ui/ui/declare_class_mut_self_not_mutable.stderr +++ b/crates/test-ui/ui/declare_class_mut_self_not_mutable.stderr @@ -19,7 +19,7 @@ error[E0277]: the trait bound `InteriorMutable: mutability::MutabilityIsAllowedM ImmutableWithMutableSubclass MutableWithImmutableSuperclass = note: required for `CustomObject` to implement `IsAllowedMutable` - = note: required for `extern "C" fn(&mut CustomObject, objc2::runtime::Sel) -> &mut CustomObject` to implement `MethodImplementation` + = note: required for `&mut CustomObject` to implement `MessageReceiver` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -27,7 +27,7 @@ note: required by a bound in `ClassBuilder::add_method` | ---------- required by a bound in this associated function ... | F: MethodImplementation, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this 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 `InteriorMutable: mutability::MutabilityIsAllowedMutable` is not satisfied @@ -51,7 +51,7 @@ error[E0277]: the trait bound `InteriorMutable: mutability::MutabilityIsAllowedM ImmutableWithMutableSubclass MutableWithImmutableSuperclass = note: required for `CustomObject` to implement `IsAllowedMutable` - = note: required for `extern "C" fn(&mut CustomObject, objc2::runtime::Sel)` to implement `MethodImplementation` + = note: required for `&mut CustomObject` to implement `MessageReceiver` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -59,7 +59,7 @@ note: required by a bound in `ClassBuilder::add_method` | ---------- required by a bound in this associated function ... | F: MethodImplementation, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this 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 `InteriorMutable: mutability::MutabilityIsAllowedMutable` is not satisfied @@ -83,7 +83,7 @@ error[E0277]: the trait bound `InteriorMutable: mutability::MutabilityIsAllowedM ImmutableWithMutableSubclass MutableWithImmutableSuperclass = note: required for `CustomObject` to implement `IsAllowedMutable` - = note: required for `extern "C" fn(&mut CustomObject, objc2::runtime::Sel) -> IdReturnValue` to implement `MethodImplementation` + = note: required for `&mut CustomObject` to implement `MessageReceiver` note: required by a bound in `ClassBuilder::add_method` --> $WORKSPACE/crates/objc2/src/declare/mod.rs | @@ -91,7 +91,7 @@ note: required by a bound in `ClassBuilder::add_method` | ---------- required by a bound in this associated function ... | F: MethodImplementation, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this 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 `InteriorMutable: mutability::MutabilityIsAllowedMutable` is not satisfied diff --git a/crates/test-ui/ui/fn_ptr_reference_encode.rs b/crates/test-ui/ui/fn_ptr_reference_encode.rs index 47c8e62a6..49ab6363b 100644 --- a/crates/test-ui/ui/fn_ptr_reference_encode.rs +++ b/crates/test-ui/ui/fn_ptr_reference_encode.rs @@ -1,7 +1,7 @@ //! Test that `Encode` is not implemented for function pointers that are //! higher-ranked over lifetimes. //! -//! Ideally, they should be, but they can't be right now. +//! Ideally, it should be, but it can't right now. use objc2::encode::Encode; extern "C" fn my_fn(_x: &i32) {} diff --git a/crates/test-ui/ui/fn_ptr_reference_method.rs b/crates/test-ui/ui/fn_ptr_reference_method.rs index f1c594b32..f5d8cba9f 100644 --- a/crates/test-ui/ui/fn_ptr_reference_method.rs +++ b/crates/test-ui/ui/fn_ptr_reference_method.rs @@ -1,7 +1,7 @@ //! Test how `MethodImplementation` is implemented regarding lifetimes in //! function pointers and whether they're higher-ranked over them. //! -//! Ideally it should work for all of these, but it can't be right now. +//! Ideally it should work for all of these, but it can't right now. //! //! (`_` can be used to work around this, by letting the compiler choose an //! appropriate lifetime '0 that the trait is implemented for). @@ -18,10 +18,8 @@ fn main() { builder.add_method(sel!(none:), my_fn as extern "C" fn(_, _, _)); // Fails - builder.add_method(sel!(third:), my_fn as extern "C" fn(_, _, &NSObject)); - - // Also fails, properly tested in `fn_ptr_reference_method2` builder.add_method(sel!(first:), my_fn as extern "C" fn(&NSObject, _, _)); + builder.add_method(sel!(third:), my_fn as extern "C" fn(_, _, &NSObject)); builder.add_method(sel!(both:), my_fn as extern "C" fn(&NSObject, _, &NSObject)); } } diff --git a/crates/test-ui/ui/fn_ptr_reference_method.stderr b/crates/test-ui/ui/fn_ptr_reference_method.stderr index 4183bab61..d4766c95e 100644 --- a/crates/test-ui/ui/fn_ptr_reference_method.stderr +++ b/crates/test-ui/ui/fn_ptr_reference_method.stderr @@ -1,26 +1,35 @@ -error[E0277]: the trait bound `for<'a> extern "C" fn(_, _, &'a NSObject): MethodImplementation` is not satisfied +error: implementation of `MethodImplementation` is not general enough + --> ui/fn_ptr_reference_method.rs + | + | builder.add_method(sel!(first:), my_fn as extern "C" fn(&NSObject, _, _)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MethodImplementation` is not general enough + | + = note: `MethodImplementation` would have to be implemented for the type `for<'a> extern "C" fn(&'a NSObject, objc2::runtime::Sel, &NSObject)` + = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&'0 NSObject, objc2::runtime::Sel, &NSObject)`, for some specific lifetime `'0` + +error: implementation of `MethodImplementation` is not general enough --> ui/fn_ptr_reference_method.rs | | builder.add_method(sel!(third:), my_fn as extern "C" fn(_, _, &NSObject)); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MethodImplementation` is not implemented for `for<'a> extern "C" fn(_, _, &'a NSObject)` - | | - | required by a bound introduced by this call - | - = help: the following other types implement trait `MethodImplementation`: - unsafe extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B) -> IdReturnValue - unsafe extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - extern "C" fn(Allocated, objc2::runtime::Sel, A, B, C) -> IdReturnValue - and $N others -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 -... - | F: MethodImplementation, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ClassBuilder::add_method` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MethodImplementation` is not general enough + | + = note: `MethodImplementation` would have to be implemented for the type `for<'a> extern "C" fn(&NSObject, objc2::runtime::Sel, &'a NSObject)` + = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&NSObject, objc2::runtime::Sel, &'0 NSObject)`, for some specific lifetime `'0` + +error: implementation of `MethodImplementation` is not general enough + --> ui/fn_ptr_reference_method.rs + | + | builder.add_method(sel!(both:), my_fn as extern "C" fn(&NSObject, _, &NSObject)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MethodImplementation` is not general enough + | + = note: `MethodImplementation` would have to be implemented for the type `for<'a, 'b> extern "C" fn(&'a NSObject, objc2::runtime::Sel, &'b NSObject)` + = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&'0 NSObject, objc2::runtime::Sel, &NSObject)`, for some specific lifetime `'0` + +error: implementation of `MethodImplementation` is not general enough + --> ui/fn_ptr_reference_method.rs + | + | builder.add_method(sel!(both:), my_fn as extern "C" fn(&NSObject, _, &NSObject)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MethodImplementation` is not general enough + | + = note: `MethodImplementation` would have to be implemented for the type `for<'a, 'b> extern "C" fn(&'a NSObject, objc2::runtime::Sel, &'b NSObject)` + = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&NSObject, objc2::runtime::Sel, &'0 NSObject)`, for some specific lifetime `'0` diff --git a/crates/test-ui/ui/fn_ptr_reference_method2.rs b/crates/test-ui/ui/fn_ptr_reference_method2.rs deleted file mode 100644 index d221cc571..000000000 --- a/crates/test-ui/ui/fn_ptr_reference_method2.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! Extra test for `fn_ptr_reference_method` -//! (They fail at different compilation passes). -use objc2::declare::ClassBuilder; -use objc2::runtime::{NSObject, Sel}; -use objc2::{class, sel}; - -extern "C" fn my_fn(_this: &NSObject, _cmd: Sel, _x: &NSObject) {} - -fn main() { - let mut builder = ClassBuilder::new("SomeTestClass", class!(NSObject)).unwrap(); - unsafe { - builder.add_method(sel!(first:), my_fn as extern "C" fn(&NSObject, _, _)); - builder.add_method(sel!(both:), my_fn as extern "C" fn(&NSObject, Sel, &NSObject)); - } -} diff --git a/crates/test-ui/ui/fn_ptr_reference_method2.stderr b/crates/test-ui/ui/fn_ptr_reference_method2.stderr deleted file mode 100644 index 8e3313262..000000000 --- a/crates/test-ui/ui/fn_ptr_reference_method2.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: implementation of `MethodImplementation` is not general enough - --> ui/fn_ptr_reference_method2.rs - | - | builder.add_method(sel!(first:), my_fn as extern "C" fn(&NSObject, _, _)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MethodImplementation` is not general enough - | - = note: `MethodImplementation` would have to be implemented for the type `for<'a> extern "C" fn(&'a NSObject, objc2::runtime::Sel, &NSObject)` - = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&'0 NSObject, objc2::runtime::Sel, &NSObject)`, for some specific lifetime `'0` - -error: implementation of `MethodImplementation` is not general enough - --> ui/fn_ptr_reference_method2.rs - | - | builder.add_method(sel!(both:), my_fn as extern "C" fn(&NSObject, Sel, &NSObject)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MethodImplementation` is not general enough - | - = note: `MethodImplementation` would have to be implemented for the type `for<'a, 'b> extern "C" fn(&'a NSObject, objc2::runtime::Sel, &'b NSObject)` - = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&'0 NSObject, objc2::runtime::Sel, &NSObject)`, for some specific lifetime `'0` - -error: implementation of `MethodImplementation` is not general enough - --> ui/fn_ptr_reference_method2.rs - | - | builder.add_method(sel!(both:), my_fn as extern "C" fn(&NSObject, Sel, &NSObject)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MethodImplementation` is not general enough - | - = note: `MethodImplementation` would have to be implemented for the type `for<'a, 'b> extern "C" fn(&'a NSObject, objc2::runtime::Sel, &'b NSObject)` - = note: ...but `MethodImplementation` is actually implemented for the type `extern "C" fn(&NSObject, objc2::runtime::Sel, &'0 NSObject)`, for some specific lifetime `'0`