Skip to content

Commit 6112808

Browse files
committed
Document RefEncode being wrong on BOOL, and suggest Bool instead
1 parent 7866c8d commit 6112808

File tree

6 files changed

+23
-7
lines changed

6 files changed

+23
-7
lines changed

objc2/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ Objective-C objects can be messaged using the `msg_send!` macro:
1414

1515
```rust , no_run
1616
use objc2::{class, msg_send};
17-
use objc2::runtime::{BOOL, Object};
17+
use objc2::runtime::{Bool, Object};
1818

1919
let cls = class!(NSObject);
2020
unsafe {
2121
let obj: *mut Object = msg_send![cls, new];
2222
let hash: usize = msg_send![obj, hash];
23-
let is_kind: BOOL = msg_send![obj, isKindOfClass: cls];
23+
let is_kind: Bool = msg_send![obj, isKindOfClass: cls];
2424
// Even void methods must have their return type annotated
2525
let _: () = msg_send![obj, release];
2626
}

objc2/src/bool.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,21 @@ impl fmt::Debug for Bool {
9999
}
100100
}
101101

102+
// SAFETY: `Bool` is `repr(transparent)`.
102103
unsafe impl Encode for Bool {
103104
const ENCODING: Encoding<'static> = objc2_sys::BOOL::ENCODING;
104105
}
105106

107+
// Note that we shouldn't delegate to `BOOL`'s `ENCODING_REF` since `BOOL` is
108+
// sometimes `i8`/`u8`, and their `ENCODING_REF`s are `Encoding::String`,
109+
// which is incorrect for `BOOL`:
110+
//
111+
// ```objc
112+
// @encode(BOOL); // -> "c", "C" or "B"
113+
// @encode(BOOL*); // -> "^c", "^C" or "^B"
114+
// @encode(char); // -> "c" or "C"
115+
// @encode(char*); // -> "*"
116+
// ```
106117
unsafe impl RefEncode for Bool {
107118
const ENCODING_REF: Encoding<'static> = Encoding::Pointer(&Self::ENCODING);
108119
}

objc2/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ Objective-C objects can be messaged using the [`msg_send!`](macro.msg_send!.html
77
88
``` no_run
99
# use objc2::{class, msg_send};
10-
# use objc2::runtime::{BOOL, Class, Object};
10+
# use objc2::runtime::{Bool, Class, Object};
1111
# unsafe {
1212
let cls = class!(NSObject);
1313
let obj: *mut Object = msg_send![cls, new];
1414
let hash: usize = msg_send![obj, hash];
15-
let is_kind: BOOL = msg_send![obj, isKindOfClass: cls];
15+
let is_kind: Bool = msg_send![obj, isKindOfClass: cls];
1616
// Even void methods must have their return type annotated
1717
let _: () = msg_send![obj, release];
1818
# }

objc2/src/message/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,13 @@ pub unsafe trait MessageReceiver: private::Sealed {
165165
/// # Example
166166
/// ``` no_run
167167
/// # use objc2::{class, msg_send, sel};
168-
/// # use objc2::runtime::{BOOL, Class, Object};
168+
/// # use objc2::runtime::{Bool, Class, Object};
169169
/// # use objc2::MessageReceiver;
170170
/// let obj: &Object;
171171
/// # obj = unsafe { msg_send![class!(NSObject), new] };
172172
/// let sel = sel!(isKindOfClass:);
173173
/// // Verify isKindOfClass: takes one Class and returns a BOOL
174-
/// let result = obj.verify_message::<(&Class,), BOOL>(sel);
174+
/// let result = obj.verify_message::<(&Class,), Bool>(sel);
175175
/// assert!(result.is_ok());
176176
/// ```
177177
fn verify_message<A, R>(&self, sel: Sel) -> Result<(), MessageError>

objc2_encode/src/encode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ unsafe impl Encode for () {
182182
/// Using this directly is heavily discouraged, since the type of BOOL differs
183183
/// across platforms.
184184
///
185-
/// Use `objc2_sys::BOOL::ENCODING` or `objc2::runtime::Bool` instead.
185+
/// Use `objc2::runtime::Bool::ENCODING` instead.
186186
unsafe impl Encode for bool {
187187
const ENCODING: Encoding<'static> = Encoding::Bool;
188188
}

objc2_sys/src/types.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ mod inner {
6565
///
6666
/// The type of this varies across platforms, so to convert an it into a Rust
6767
/// [`bool`], always compare it with [`YES`][`crate::YES`] or [`NO`][`crate::NO`].
68+
///
69+
/// Note that this type implements `objc2_encode::Encode` and
70+
/// `objc2_encode::RefEncode`, but the `RefEncode` implementation is wrong
71+
/// on some platforms! You should only use this on FFI boundaries, otherwise
72+
/// prefer `objc2::runtime::Bool`.
6873
pub type BOOL = inner::BOOL;
6974

7075
/// An immutable pointer to a selector.

0 commit comments

Comments
 (0)