Skip to content

Commit b9657d3

Browse files
committed
Merge msg_send! and msg_send_id!
Merge all message sending functionality into one shared implementation, to make it easier for newcomers to use (instead of having to remember the difference between `#[method(...)]` and `#[method_id(...)]`). This also deprecates `msg_send_id!` and `#[method_id(...)]`, which is a bit step of #617. Fixes #457.
1 parent aa6e383 commit b9657d3

File tree

136 files changed

+3004
-2998
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+3004
-2998
lines changed

crates/header-translator/src/method.rs

+13-24
Original file line numberDiff line numberDiff line change
@@ -767,32 +767,21 @@ impl fmt::Display for Method {
767767
writeln!(f, " #[optional]")?;
768768
}
769769

770-
let method_kind = if self.memory_management == MemoryManagement::Normal {
771-
"method"
772-
} else {
773-
"method_id"
774-
};
775770
let error_trailing = if self.is_error { "_" } else { "" };
776-
writeln!(
777-
f,
778-
" #[{}({}{})]",
779-
method_kind, self.selector, error_trailing
780-
)?;
781-
782-
let id_mm_name = match &self.memory_management {
783-
// MemoryManagement::IdAlloc => Some("alloc"), // Unsupported
784-
MemoryManagement::IdCopy => Some("copy"),
785-
MemoryManagement::IdMutableCopy => Some("mutableCopy"),
786-
MemoryManagement::IdNew => Some("new"),
787-
MemoryManagement::IdInit => Some("init"),
788-
MemoryManagement::IdOther => Some("none"),
789-
MemoryManagement::Normal => None,
790-
};
791-
if let Some(id_mm_name) = id_mm_name {
792-
// TODO: Be explicit about when we emit this for better
793-
// compile-times, and when we do it for soundness.
794-
writeln!(f, " #[unsafe(method_family = {id_mm_name})]")?;
771+
writeln!(f, " #[method({}{})]", self.selector, error_trailing)?;
772+
773+
let method_family = match &self.memory_management {
774+
// MemoryManagement::IdAlloc => "alloc", // Unsupported
775+
MemoryManagement::IdCopy => "copy",
776+
MemoryManagement::IdMutableCopy => "mutableCopy",
777+
MemoryManagement::IdNew => "new",
778+
MemoryManagement::IdInit => "init",
779+
MemoryManagement::IdOther => "none",
780+
MemoryManagement::Normal => "none",
795781
};
782+
// TODO: Be explicit about when we emit this for better
783+
// compile-times, and when we do it for soundness.
784+
writeln!(f, " #[unsafe(method_family = {method_family})]")?;
796785

797786
//
798787
// Signature

crates/header-translator/src/rust_type.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2404,7 +2404,7 @@ impl Ty {
24042404

24052405
// As in `parse_property_return`, the nullability is not guaranteed by
24062406
// the method, and can also fail in OOM situations, but that is
2407-
// handled by `#[method_id(...)]`
2407+
// handled by `#[method(...)]`
24082408
if default_nonnull {
24092409
match &mut ty {
24102410
Self::Pointer { nullability, .. } => {
@@ -2512,8 +2512,8 @@ impl Ty {
25122512
// can also fail in OOM situations, so we must still perform an unwrap
25132513
// to be sure (Swift also uses forced unwrapping here).
25142514
//
2515-
// This unwrap is done by `#[method_id(...)]` when we specify the
2516-
// return type as `Retained`.
2515+
// This unwrap is done by `#[method(...)]` when we specify the return
2516+
// type as `Retained`.
25172517
if is_copy {
25182518
match &mut ty {
25192519
Self::Pointer { nullability, .. } => {

crates/objc2/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
172172
`AnyObject::downcast_ref` method instead.
173173
* Deprecated `Retained::cast`, this has been renamed to `Retained::cast_unchecked`.
174174
* Renamed `DeclaredClass` to `DefinedClass`.
175+
* Merged `msg_send!` and `msg_send_id!`. The latter is now deprecated.
176+
* Merged `#[method(...)]` and `#[method_id(...)]` in `extern_methods!` and
177+
`extern_protocol!`. The latter is now deprecated.
175178

176179
### Removed
177180
* **BREAKING**: Removed the `ffi::SEL` and `ffi::objc_selector` types. Use

crates/objc2/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ objc2-core-foundation = { path = "../../framework-crates/objc2-core-foundation",
132132
objc2-foundation = { path = "../../framework-crates/objc2-foundation", default-features = false, features = [
133133
"std",
134134
"NSArray",
135+
"NSBundle",
135136
"NSDate",
136137
"NSDictionary",
137138
"NSEnumerator",
@@ -141,6 +142,8 @@ objc2-foundation = { path = "../../framework-crates/objc2-foundation", default-f
141142
"NSObject",
142143
"NSRunLoop",
143144
"NSString",
145+
"NSURL",
146+
"NSValue",
144147
] }
145148
libc = "0.2.158"
146149

crates/objc2/examples/class_with_lifetime.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ use std::cell::Cell;
55
use std::marker::PhantomData;
66
use std::sync::Once;
77

8-
use objc2::msg_send_id;
98
use objc2::rc::Retained;
109
use objc2::runtime::{AnyClass, AnyObject, ClassBuilder, NSObject};
11-
use objc2::{ClassType, Encoding, Message, RefEncode};
10+
use objc2::{msg_send, ClassType, Encoding, Message, RefEncode};
1211

1312
/// The type of the instance variable that we want to store
1413
type Ivar<'a> = &'a Cell<u8>;
@@ -49,7 +48,7 @@ impl<'a> MyObject<'a> {
4948

5049
fn new(number: &'a mut u8) -> Retained<Self> {
5150
// SAFETY: The instance variable is initialized below.
52-
let this: Retained<Self> = unsafe { msg_send_id![Self::class(), new] };
51+
let this: Retained<Self> = unsafe { msg_send![Self::class(), new] };
5352

5453
// It is generally very hard to use `mut` in Objective-C, so let's use
5554
// interior mutability instead.

crates/objc2/src/__macro_helpers/common_selectors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ mod tests {
8282
use crate::rc::Retained;
8383
use crate::runtime::ClassBuilder;
8484
use crate::runtime::NSObject;
85-
use crate::{msg_send_id, ClassType};
85+
use crate::{msg_send, ClassType};
8686

8787
use super::*;
8888

@@ -103,7 +103,7 @@ mod tests {
103103

104104
let cls = builder.register();
105105

106-
let obj: Retained<NSObject> = unsafe { msg_send_id![cls, new] };
106+
let obj: Retained<NSObject> = unsafe { msg_send![cls, new] };
107107
drop(obj);
108108
let has_run_destruct = HAS_RUN.load(Ordering::Relaxed);
109109

crates/objc2/src/__macro_helpers/define_class.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::runtime::{AnyProtocol, MethodDescription};
1616
use crate::{AllocAnyThread, ClassType, DefinedClass, Message, ProtocolType};
1717

1818
use super::defined_ivars::{register_with_ivars, setup_dealloc};
19-
use super::{CopyFamily, InitFamily, MaybeUnwrap, MutableCopyFamily, NewFamily, NoneFamily};
19+
use super::{CopyFamily, InitFamily, MutableCopyFamily, NewFamily, NoneFamily};
2020

2121
/// Helper for determining auto traits of defined classes.
2222
///
@@ -97,7 +97,7 @@ where
9797
impl<Ret, T> MessageReceiveRetained<Allocated<T>, Ret> for InitFamily
9898
where
9999
T: Message,
100-
Ret: MaybeOptionRetained<Input = Option<Retained<T>>>,
100+
Ret: MaybeOptionRetained<Inner = T>,
101101
{
102102
#[inline]
103103
fn into_return(obj: Ret) -> RetainedReturnValue {
@@ -144,12 +144,16 @@ where
144144
/// Helper trait for specifying an `Retained<T>` or an `Option<Retained<T>>`.
145145
///
146146
/// (Both of those are valid return types from define_class! `#[method_id]`).
147-
pub trait MaybeOptionRetained: MaybeUnwrap {
147+
pub trait MaybeOptionRetained {
148+
type Inner;
149+
148150
fn consumed_return(self) -> RetainedReturnValue;
149151
fn autorelease_return(self) -> RetainedReturnValue;
150152
}
151153

152154
impl<T: Message> MaybeOptionRetained for Retained<T> {
155+
type Inner = T;
156+
153157
#[inline]
154158
fn consumed_return(self) -> RetainedReturnValue {
155159
let ptr: *mut T = Retained::into_raw(self);
@@ -164,6 +168,8 @@ impl<T: Message> MaybeOptionRetained for Retained<T> {
164168
}
165169

166170
impl<T: Message> MaybeOptionRetained for Option<Retained<T>> {
171+
type Inner = T;
172+
167173
#[inline]
168174
fn consumed_return(self) -> RetainedReturnValue {
169175
let ptr: *mut T = Retained::consume_as_ptr_option(self);

crates/objc2/src/__macro_helpers/defined_ivars.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ mod tests {
435435
use super::*;
436436
use crate::rc::{Allocated, PartialInit, RcTestObject, Retained, ThreadTestData};
437437
use crate::runtime::NSObject;
438-
use crate::{define_class, msg_send, msg_send_id, AllocAnyThread, Message};
438+
use crate::{define_class, msg_send, AllocAnyThread, Message};
439439

440440
/// Initialize superclasses, but not own class.
441441
unsafe fn init_only_superclasses<T: DefinedClass>(obj: Allocated<T>) -> Retained<T>
@@ -445,7 +445,8 @@ mod tests {
445445
unsafe { Retained::from_raw(msg_send![super(Allocated::into_ptr(obj)), init]) }.unwrap()
446446
}
447447

448-
/// Initialize, but fail to finalize (which is only done by `msg_send_id!`).
448+
/// Initialize, but fail to finalize (which is done internally by
449+
/// `msg_send!` when returning `Retained`).
449450
unsafe fn init_no_finalize<T: DefinedClass>(obj: Allocated<T>) -> Retained<T>
450451
where
451452
T::Super: ClassType,
@@ -457,7 +458,7 @@ mod tests {
457458

458459
/// Initialize properly.
459460
unsafe fn init<T: DefinedClass>(obj: Allocated<T>) -> Retained<T> {
460-
unsafe { msg_send_id![obj, init] }
461+
unsafe { msg_send![obj, init] }
461462
}
462463

463464
#[test]
@@ -505,7 +506,7 @@ mod tests {
505506
unsafe impl ImplsDrop {
506507
#[method_id(init)]
507508
fn init(this: Allocated<Self>) -> Option<Retained<Self>> {
508-
unsafe { msg_send_id![super(this.set_ivars(())), init] }
509+
unsafe { msg_send![super(this.set_ivars(())), init] }
509510
}
510511
}
511512
);
@@ -539,7 +540,7 @@ mod tests {
539540
unsafe impl IvarsImplDrop {
540541
#[method_id(init)]
541542
fn init(this: Allocated<Self>) -> Option<Retained<Self>> {
542-
unsafe { msg_send_id![super(this.set_ivars(IvarThatImplsDrop)), init] }
543+
unsafe { msg_send![super(this.set_ivars(IvarThatImplsDrop)), init] }
543544
}
544545
}
545546
);
@@ -567,7 +568,7 @@ mod tests {
567568
unsafe impl BothIvarsAndTypeImplsDrop {
568569
#[method_id(init)]
569570
fn init(this: Allocated<Self>) -> Option<Retained<Self>> {
570-
unsafe { msg_send_id![super(this.set_ivars(IvarThatImplsDrop)), init] }
571+
unsafe { msg_send![super(this.set_ivars(IvarThatImplsDrop)), init] }
571572
}
572573
}
573574
);
@@ -637,7 +638,7 @@ mod tests {
637638
unsafe impl IvarZst {
638639
#[method_id(init)]
639640
fn init(this: Allocated<Self>) -> Option<Retained<Self>> {
640-
unsafe { msg_send_id![super(this.set_ivars(Cell::new(Ivar))), init] }
641+
unsafe { msg_send![super(this.set_ivars(Cell::new(Ivar))), init] }
641642
}
642643
}
643644
);
@@ -701,7 +702,7 @@ mod tests {
701702
#[method_id(init)]
702703
fn init(this: Allocated<Self>) -> Option<Retained<Self>> {
703704
let this = this.set_ivars(Cell::new(Some(RcTestObject::new())));
704-
unsafe { msg_send_id![super(this), init] }
705+
unsafe { msg_send![super(this), init] }
705706
}
706707
}
707708
);
@@ -764,7 +765,7 @@ mod tests {
764765
int: Cell::new(42),
765766
obj: Cell::new(RcTestObject::new()),
766767
});
767-
unsafe { msg_send_id![super(this), init] }
768+
unsafe { msg_send![super(this), init] }
768769
}
769770
}
770771
);
@@ -846,7 +847,7 @@ mod tests {
846847
}
847848

848849
let obj = DropPanics::alloc().set_ivars(());
849-
let obj: Retained<DropPanics> = unsafe { msg_send_id![super(obj), init] };
850+
let obj: Retained<DropPanics> = unsafe { msg_send![super(obj), init] };
850851
drop(obj);
851852
}
852853

@@ -870,7 +871,7 @@ mod tests {
870871
);
871872

872873
let obj = IvarDropPanics::alloc().set_ivars(DropPanics);
873-
let obj: Retained<IvarDropPanics> = unsafe { msg_send_id![super(obj), init] };
874+
let obj: Retained<IvarDropPanics> = unsafe { msg_send![super(obj), init] };
874875
drop(obj);
875876
}
876877

@@ -907,7 +908,7 @@ mod tests {
907908
}
908909

909910
let obj = DropRetainsAndLeaksSelf::alloc().set_ivars(());
910-
let obj: Retained<DropRetainsAndLeaksSelf> = unsafe { msg_send_id![super(obj), init] };
911+
let obj: Retained<DropRetainsAndLeaksSelf> = unsafe { msg_send![super(obj), init] };
911912
drop(obj);
912913

913914
// Suddenly, the object is alive again!

crates/objc2/src/__macro_helpers/method_family.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/// The slight difference here is:
77
/// - The method may be annotated with the `objc_method_family` attribute,
88
/// which would cause it to be in a different family. That this is not the
9-
/// case is part of the `unsafe` contract of `msg_send_id!`.
9+
/// case is part of the `unsafe` contract of `msg_send!`.
1010
/// - The method may not obey the added restrictions of the method family.
1111
/// The added restrictions are:
1212
/// - `new`, `alloc`, `copy` and `mutableCopy`: The method must return a
@@ -39,6 +39,18 @@ pub type NoneFamily = MethodFamily<6>;
3939
/// Used for a fast-path optimization using `objc_alloc`.
4040
pub type AllocSelector = MethodFamily<7>;
4141

42+
// These are used to avoid trying to do retain-semantics for these special
43+
// selectors that would otherwise fall under `NoneFamily`.
44+
45+
/// The `retain` selector itself.
46+
pub type RetainSelector = MethodFamily<8>;
47+
/// The `release` selector itself.
48+
pub type ReleaseSelector = MethodFamily<9>;
49+
/// The `autorelease` selector itself.
50+
pub type AutoreleaseSelector = MethodFamily<10>;
51+
/// The `dealloc` selector itself.
52+
pub type DeallocSelector = MethodFamily<11>;
53+
4254
/// Helper module where `#[unsafe(method_family = $family:ident)]` will import
4355
/// its value from.
4456
#[allow(non_camel_case_types)]

crates/objc2/src/__macro_helpers/mod.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ pub(crate) mod defined_ivars;
2323
mod image_info;
2424
mod method_family;
2525
mod module_info;
26-
mod msg_send;
2726
mod msg_send_retained;
2827
mod null_error;
2928
mod os_version;
29+
mod retain_semantics;
3030
mod sync_unsafe_cell;
3131
mod writeback;
3232

@@ -41,13 +41,16 @@ pub use self::define_class::{
4141
pub use self::defined_ivars::DefinedIvarsHelper;
4242
pub use self::image_info::ImageInfo;
4343
pub use self::method_family::{
44-
method_family, method_family_import, AllocFamily, AllocSelector, CopyFamily, InitFamily,
45-
MethodFamily, MutableCopyFamily, NewFamily, NoneFamily,
44+
method_family, method_family_import, AllocFamily, AllocSelector, AutoreleaseSelector,
45+
CopyFamily, DeallocSelector, InitFamily, MethodFamily, MutableCopyFamily, NewFamily,
46+
NoneFamily, ReleaseSelector, RetainSelector,
4647
};
4748
pub use self::module_info::ModuleInfo;
48-
pub use self::msg_send::MsgSend;
49-
pub use self::msg_send_retained::{MaybeUnwrap, MsgSendRetained, MsgSendSuperRetained};
49+
pub use self::msg_send_retained::{MsgSend, MsgSendError, MsgSendSuper, MsgSendSuperError};
5050
pub use self::os_version::{is_available, AvailableVersion, OSVersion};
51+
pub use self::retain_semantics::{
52+
KindDefined, KindSendMessage, KindSendMessageSuper, RetainSemantics,
53+
};
5154
pub use self::sync_unsafe_cell::SyncUnsafeCell;
5255

5356
/// Disallow using this passed in value in const and statics for forwards

0 commit comments

Comments
 (0)