Skip to content

Commit aa67e05

Browse files
authored
Merge pull request #535 from madsmtm/c-void-encoding
Remove `c_void` encoding hack
2 parents 4e64c1a + 8c4b479 commit aa67e05

13 files changed

+60
-144
lines changed

crates/objc2/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
201201
let ivar = cls.instance_variable("number").unwrap();
202202
let number = unsafe { *ivar.load::<u32>(&obj) };
203203
```
204+
* Implement `RefEncode` normally for `c_void`. This makes `AtomicPtr<c_void>`
205+
implement `Encode`.
204206

205207
### Removed
206208
* **BREAKING**: Removed `ProtocolType` implementation for `NSObject`.

crates/objc2/src/encode.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -704,28 +704,9 @@ unsafe impl<T: RefEncode> RefEncode for atomic::AtomicPtr<T> {
704704
const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
705705
}
706706

707-
/// [`Encode`] is implemented manually for `*const c_void`, `*mut c_void` and
708-
/// `NonNull<c_void>`, instead of implementing [`RefEncode`], to discourage
709-
/// creating `&c_void`/`&mut c_void`.
710-
unsafe impl Encode for *const c_void {
711-
const ENCODING: Encoding = Encoding::Pointer(&Encoding::Void);
707+
unsafe impl RefEncode for c_void {
708+
const ENCODING_REF: Encoding = Encoding::Pointer(&Encoding::Void);
712709
}
713-
unsafe impl RefEncode for *const c_void {
714-
const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
715-
}
716-
unsafe impl Encode for *mut c_void {
717-
const ENCODING: Encoding = Encoding::Pointer(&Encoding::Void);
718-
}
719-
unsafe impl RefEncode for *mut c_void {
720-
const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
721-
}
722-
unsafe impl Encode for NonNull<c_void> {
723-
const ENCODING: Encoding = Encoding::Pointer(&Encoding::Void);
724-
}
725-
unsafe impl RefEncode for NonNull<c_void> {
726-
const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
727-
}
728-
unsafe impl OptionEncode for NonNull<c_void> {}
729710

730711
unsafe impl<T: Encode, const LENGTH: usize> Encode for [T; LENGTH] {
731712
const ENCODING: Encoding = Encoding::Array(LENGTH as u64, &T::ENCODING);
@@ -959,10 +940,15 @@ mod tests {
959940
<*const c_void>::ENCODING,
960941
Encoding::Pointer(&Encoding::Void)
961942
);
943+
assert_eq!(<&c_void>::ENCODING, Encoding::Pointer(&Encoding::Void));
962944
assert_eq!(
963945
<&*const c_void>::ENCODING,
964946
Encoding::Pointer(&Encoding::Pointer(&Encoding::Void))
965947
);
948+
assert_eq!(
949+
<AtomicPtr<c_void>>::ENCODING,
950+
Encoding::Atomic(&Encoding::Pointer(&Encoding::Void))
951+
);
966952
}
967953

968954
#[test]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//! Test underspecified msg_send_id! errors.
2+
use icrate::Foundation::NSString;
3+
use objc2::msg_send_id;
4+
use objc2::rc::Id;
5+
6+
fn main() {
7+
let obj: &NSString;
8+
let _: Result<Id<NSString>, _> = unsafe { msg_send_id![obj, error: _] };
9+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error[E0282]: type annotations needed
2+
--> ui/msg_send_id_underspecified_error1.rs
3+
|
4+
| let _: Result<Id<NSString>, _> = unsafe { msg_send_id![obj, error: _] };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
//! Test underspecified msg_send! errors.
1+
//! Test underspecified msg_send_id! errors.
22
use icrate::Foundation::{NSError, NSString};
33
use objc2::msg_send_id;
44
use objc2::rc::Id;
55

66
fn main() {
77
let obj: &NSString;
8-
let _: Result<Id<_>, Id<NSError>> = unsafe { msg_send_id![obj, a: _] };
8+
let _: Result<_, Id<NSError>> = unsafe { msg_send_id![obj, error: _] };
99
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error[E0282]: type annotations needed
2+
--> ui/msg_send_id_underspecified_error2.rs
3+
|
4+
| let _: Result<_, Id<NSError>> = unsafe { msg_send_id![obj, error: _] };
5+
| ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//! Test underspecified msg_send_id! errors.
2+
use icrate::Foundation::NSString;
3+
use objc2::msg_send_id;
4+
5+
fn main() {
6+
let obj: &NSString;
7+
let _: Result<_, _> = unsafe { msg_send_id![obj, error: _] };
8+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error[E0282]: type annotations needed
2+
--> ui/msg_send_id_underspecified_error3.rs
3+
|
4+
| let _: Result<_, _> = unsafe { msg_send_id![obj, error: _] };
5+
| ^^^^^^^^^^^^ cannot infer type
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
//! Test underspecified msg_send! errors.
22
use icrate::Foundation::NSString;
3-
use objc2::rc::Id;
4-
use objc2::{msg_send, msg_send_id};
3+
use objc2::msg_send;
54

65
fn main() {
76
let obj: &NSString;
8-
let _: Result<(), _> = unsafe { msg_send![obj, a: _] };
9-
10-
let _: Result<_, _> = unsafe { msg_send_id![obj, b: _] };
11-
let _: Result<Id<NSString>, _> = unsafe { msg_send_id![obj, c: _] };
12-
let _: Result<Id<NSString>, Id<_>> = unsafe { msg_send_id![obj, d: _] };
7+
let _: Result<(), _> = unsafe { msg_send![obj, error: _] };
138
}
Lines changed: 2 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,5 @@
11
error[E0282]: type annotations needed
22
--> ui/msg_send_underspecified_error.rs
33
|
4-
| let _: Result<Id<NSString>, Id<_>> = unsafe { msg_send_id![obj, d: _] };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
6-
7-
error[E0283]: type annotations needed
8-
--> ui/msg_send_underspecified_error.rs
9-
|
10-
| let _: Result<(), _> = unsafe { msg_send![obj, a: _] };
11-
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type for raw pointer `*mut _`
12-
|
13-
= note: multiple `impl`s satisfying `*mut _: RefEncode` found in the `objc2` crate:
14-
- impl RefEncode for *mut c_void;
15-
- impl<T> RefEncode for *mut T
16-
where T: RefEncode, T: ?Sized;
17-
= note: required for `*mut *mut _` to implement `Encode`
18-
note: required by a bound in `send_message_error`
19-
--> $WORKSPACE/crates/objc2/src/__macro_helpers/msg_send.rs
20-
|
21-
| unsafe fn send_message_error<A, E>(self, sel: Sel, args: A) -> Result<(), Id<E>>
22-
| ------------------ required by a bound in this associated function
23-
| where
24-
| *mut *mut E: Encode,
25-
| ^^^^^^ required by this bound in `MsgSend::send_message_error`
26-
= note: this error originates in the macro `$crate::__msg_send_helper` which comes from the expansion of the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
27-
28-
error[E0283]: type annotations needed
29-
--> ui/msg_send_underspecified_error.rs
30-
|
31-
| let _: Result<_, _> = unsafe { msg_send_id![obj, b: _] };
32-
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for raw pointer `*mut _`
33-
|
34-
= note: multiple `impl`s satisfying `*mut _: RefEncode` found in the `objc2` crate:
35-
- impl RefEncode for *mut c_void;
36-
- impl<T> RefEncode for *mut T
37-
where T: RefEncode, T: ?Sized;
38-
= note: required for `*mut *mut _` to implement `Encode`
39-
note: required by a bound in `send_message_id_error`
40-
--> $WORKSPACE/crates/objc2/src/__macro_helpers/msg_send_id.rs
41-
|
42-
| unsafe fn send_message_id_error<A, E, R>(obj: T, sel: Sel, args: A) -> Result<R, Id<E>>
43-
| --------------------- required by a bound in this associated function
44-
| where
45-
| *mut *mut E: Encode,
46-
| ^^^^^^ required by this bound in `MsgSendId::send_message_id_error`
47-
= note: this error originates in the macro `$crate::__msg_send_id_helper` which comes from the expansion of the macro `msg_send_id` (in Nightly builds, run with -Z macro-backtrace for more info)
48-
49-
error[E0283]: type annotations needed
50-
--> ui/msg_send_underspecified_error.rs
51-
|
52-
| let _: Result<Id<NSString>, _> = unsafe { msg_send_id![obj, c: _] };
53-
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for raw pointer `*mut _`
54-
|
55-
= note: multiple `impl`s satisfying `*mut _: RefEncode` found in the `objc2` crate:
56-
- impl RefEncode for *mut c_void;
57-
- impl<T> RefEncode for *mut T
58-
where T: RefEncode, T: ?Sized;
59-
= note: required for `*mut *mut _` to implement `Encode`
60-
note: required by a bound in `send_message_id_error`
61-
--> $WORKSPACE/crates/objc2/src/__macro_helpers/msg_send_id.rs
62-
|
63-
| unsafe fn send_message_id_error<A, E, R>(obj: T, sel: Sel, args: A) -> Result<R, Id<E>>
64-
| --------------------- required by a bound in this associated function
65-
| where
66-
| *mut *mut E: Encode,
67-
| ^^^^^^ required by this bound in `MsgSendId::send_message_id_error`
68-
= note: this error originates in the macro `$crate::__msg_send_id_helper` which comes from the expansion of the macro `msg_send_id` (in Nightly builds, run with -Z macro-backtrace for more info)
69-
70-
error[E0283]: type annotations needed
71-
--> ui/msg_send_underspecified_error.rs
72-
|
73-
| let _: Result<Id<NSString>, Id<_>> = unsafe { msg_send_id![obj, d: _] };
74-
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for raw pointer `*mut _`
75-
|
76-
= note: multiple `impl`s satisfying `*mut _: RefEncode` found in the `objc2` crate:
77-
- impl RefEncode for *mut c_void;
78-
- impl<T> RefEncode for *mut T
79-
where T: RefEncode, T: ?Sized;
80-
= note: required for `*mut *mut _` to implement `Encode`
81-
note: required by a bound in `send_message_id_error`
82-
--> $WORKSPACE/crates/objc2/src/__macro_helpers/msg_send_id.rs
83-
|
84-
| unsafe fn send_message_id_error<A, E, R>(obj: T, sel: Sel, args: A) -> Result<R, Id<E>>
85-
| --------------------- required by a bound in this associated function
86-
| where
87-
| *mut *mut E: Encode,
88-
| ^^^^^^ required by this bound in `MsgSendId::send_message_id_error`
89-
= note: this error originates in the macro `$crate::__msg_send_id_helper` which comes from the expansion of the macro `msg_send_id` (in Nightly builds, run with -Z macro-backtrace for more info)
4+
| let _: Result<(), _> = unsafe { msg_send![obj, error: _] };
5+
| ^^^^^^^^^^^^^ cannot infer type

crates/test-ui/ui/msg_send_underspecified_error2.stderr

Lines changed: 0 additions & 5 deletions
This file was deleted.

crates/test-ui/ui/not_encode.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ fn main() {
1515
is_encode::<&()>();
1616
is_encode::<*const ()>();
1717
is_encode::<c_void>();
18-
is_encode::<&c_void>();
1918
is_encode::<&Block<((), i32), ()>>();
2019

2120
is_encode::<fn() -> &'static ()>();

crates/test-ui/ui/not_encode.stderr

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -95,24 +95,15 @@ error[E0277]: the trait bound `c_void: Encode` is not satisfied
9595
| ^^^^^^ the trait `Encode` is not implemented for `c_void`
9696
|
9797
= help: the following other types implement trait `Encode`:
98-
*const c_void
99-
*mut c_void
100-
note: required by a bound in `is_encode`
101-
--> ui/not_encode.rs
102-
|
103-
| fn is_encode<T: Encode>() {}
104-
| ^^^^^^ required by this bound in `is_encode`
105-
106-
error[E0277]: the trait bound `c_void: RefEncode` is not satisfied
107-
--> ui/not_encode.rs
108-
|
109-
| is_encode::<&c_void>();
110-
| ^^^^^^^ the trait `RefEncode` is not implemented for `c_void`
111-
|
112-
= help: the following other types implement trait `RefEncode`:
113-
*const c_void
114-
*mut c_void
115-
= note: required for `&c_void` to implement `Encode`
98+
isize
99+
i8
100+
i16
101+
i32
102+
i64
103+
usize
104+
u8
105+
u16
106+
and $N others
116107
note: required by a bound in `is_encode`
117108
--> ui/not_encode.rs
118109
|
@@ -225,8 +216,8 @@ note: required by a bound in `is_encode`
225216
| ^^^^^^ required by this bound in `is_encode`
226217
help: consider removing the leading `&`-reference
227218
|
228-
25 - is_encode::<&Sel>();
229-
25 + is_encode::<Sel>();
219+
24 - is_encode::<&Sel>();
220+
24 + is_encode::<Sel>();
230221
|
231222

232223
error[E0277]: the trait bound `UnsafeCell<&u8>: OptionEncode` is not satisfied
@@ -236,14 +227,14 @@ error[E0277]: the trait bound `UnsafeCell<&u8>: OptionEncode` is not satisfied
236227
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `OptionEncode` is not implemented for `UnsafeCell<&u8>`
237228
|
238229
= help: the following other types implement trait `OptionEncode`:
239-
NonNull<c_void>
240230
NonNull<T>
241231
objc2::runtime::Sel
242232
NonZeroU8
243233
NonZeroU16
244234
NonZeroU32
245235
NonZeroU64
246236
NonZeroUsize
237+
NonZeroI8
247238
and $N others
248239
= note: required for `Option<UnsafeCell<&u8>>` to implement `Encode`
249240
note: required by a bound in `is_encode`
@@ -259,14 +250,14 @@ error[E0277]: the trait bound `Cell<&u8>: OptionEncode` is not satisfied
259250
| ^^^^^^^^^^^^^^^^^ the trait `OptionEncode` is not implemented for `Cell<&u8>`
260251
|
261252
= help: the following other types implement trait `OptionEncode`:
262-
NonNull<c_void>
263253
NonNull<T>
264254
objc2::runtime::Sel
265255
NonZeroU8
266256
NonZeroU16
267257
NonZeroU32
268258
NonZeroU64
269259
NonZeroUsize
260+
NonZeroI8
270261
and $N others
271262
= note: required for `Option<Cell<&u8>>` to implement `Encode`
272263
note: required by a bound in `is_encode`

0 commit comments

Comments
 (0)