Skip to content

Commit 4f84eab

Browse files
committed
Implement Encode and RefEncode for UnsafeCell
1 parent dac2bc1 commit 4f84eab

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

crates/objc2/src/encode/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
//! method argument, but is a very common return type, and hence implements
6060
//! [`Encode`].
6161
62+
use core::cell::UnsafeCell;
6263
use core::ffi::c_void;
6364
use core::mem::{self, ManuallyDrop, MaybeUninit};
6465
use core::num::{
@@ -484,11 +485,12 @@ encode_impls_transparent! {
484485
// TODO: With specialization: `impl Encode for ManuallyDrop<Box<T>>`
485486
ManuallyDrop<T: ?Sized>,
486487

488+
// SAFETY: Guaranteed to have the same in-memory representation `T`.
489+
//
487490
// The fact that this has `repr(no_niche)` has no effect on us, since we
488491
// don't unconditionally implement `Encode` generically over `Option`.
489492
// (e.g. an `Option<UnsafeCell<&u8>>` impl is not available).
490-
// The inner field is not public, so may not be stable.
491-
// TODO: UnsafeCell<T>,
493+
UnsafeCell<T: ?Sized>,
492494

493495
// The inner field is not public, so may not be safe.
494496
// TODO: Pin<T>,
@@ -702,13 +704,10 @@ mod tests {
702704
assert_eq!(<ManuallyDrop<Option<&u8>>>::ENCODING, u8::ENCODING_REF);
703705
assert_eq!(<&ManuallyDrop<Option<&u8>>>::ENCODING, <&&u8>::ENCODING);
704706

705-
// assert_eq!(<UnsafeCell<u8>>::ENCODING, u8::ENCODING);
707+
assert_eq!(<UnsafeCell<u8>>::ENCODING, u8::ENCODING);
706708
// assert_eq!(<Pin<u8>>::ENCODING, u8::ENCODING);
707709
assert_eq!(<MaybeUninit<u8>>::ENCODING, u8::ENCODING);
708710
assert_eq!(<Wrapping<u8>>::ENCODING, u8::ENCODING);
709-
710-
// Shouldn't compile
711-
// assert_eq!(<Option<UnsafeCell<&u8>>>::ENCODING, <&u8>::ENCODING);
712711
}
713712

714713
#[test]

crates/test-ui/ui/not_encode.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! Verify that certain things we don't want to be encode aren't.
2+
use core::cell::UnsafeCell;
23
use core::ffi::c_void;
34

45
use objc2::encode::Encode;
@@ -22,4 +23,9 @@ fn main() {
2223
is_encode::<fn(i32, ())>();
2324

2425
is_encode::<&Sel>();
26+
27+
// This should compile
28+
is_encode::<UnsafeCell<&u8>>();
29+
// But this mustn't
30+
is_encode::<Option<UnsafeCell<&u8>>>();
2531
}

crates/test-ui/ui/not_encode.stderr

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,29 @@ note: required by a bound in `is_encode`
224224
| ^^^^^^ required by this bound in `is_encode`
225225
help: consider removing the leading `&`-reference
226226
|
227-
24 - is_encode::<&Sel>();
228-
24 + is_encode::<Sel>();
227+
25 - is_encode::<&Sel>();
228+
25 + is_encode::<Sel>();
229229
|
230+
231+
error[E0277]: the trait bound `UnsafeCell<&u8>: OptionEncode` is not satisfied
232+
--> ui/not_encode.rs
233+
|
234+
| is_encode::<Option<UnsafeCell<&u8>>>();
235+
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `OptionEncode` is not implemented for `UnsafeCell<&u8>`
236+
|
237+
= help: the following other types implement trait `OptionEncode`:
238+
&'a T
239+
&'a mut T
240+
NonNull<T>
241+
NonNull<c_void>
242+
NonZeroI16
243+
NonZeroI32
244+
NonZeroI64
245+
NonZeroI8
246+
and $N others
247+
= note: required for `Option<UnsafeCell<&u8>>` to implement `Encode`
248+
note: required by a bound in `is_encode`
249+
--> ui/not_encode.rs
250+
|
251+
| fn is_encode<T: Encode>() {}
252+
| ^^^^^^ required by this bound in `is_encode`

0 commit comments

Comments
 (0)