Skip to content

Commit 3e95dae

Browse files
committed
Relax Sized bound on Id to better allow extern types
1 parent 121e34c commit 3e95dae

File tree

7 files changed

+67
-55
lines changed

7 files changed

+67
-55
lines changed

objc2/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
3636
- `Class::instance_variables`
3737
- `Protocol::protocols`
3838
- `Protocol::adopted_protocols`
39+
* Relaxed `Sized` bound on `rc::Id` and `rc::WeakId` to prepare for
40+
`extern type` support.
41+
* **BREAKING**: Relaxed `Sized` bound on `rc::SliceId` and `rc::DefaultId`.
3942

4043
### Removed
4144
* **BREAKING**: Removed the raw FFI functions from the `runtime` module. These

objc2/src/message/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub(crate) mod private {
7979
impl<'a, T: Message + ?Sized> Sealed for &'a T {}
8080
impl<'a, T: Message + ?Sized> Sealed for &'a mut T {}
8181
impl<T: Message + ?Sized> Sealed for NonNull<T> {}
82-
impl<T: Message, O: Ownership> Sealed for Id<T, O> {}
82+
impl<T: Message + ?Sized, O: Ownership> Sealed for Id<T, O> {}
8383

8484
impl<T: MessageReceiver + ?Sized> Sealed for ManuallyDrop<T> {}
8585
}
@@ -248,7 +248,7 @@ unsafe impl<T: Message + ?Sized> MessageReceiver for NonNull<T> {
248248
}
249249
}
250250

251-
unsafe impl<T: Message, O: Ownership> MessageReceiver for Id<T, O> {
251+
unsafe impl<T: Message + ?Sized, O: Ownership> MessageReceiver for Id<T, O> {
252252
#[inline]
253253
fn as_raw_receiver(&self) -> *mut Object {
254254
// TODO: Maybe don't dereference here, just to be safe?

objc2/src/rc/autorelease.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl AutoreleasePool {
101101
/// the lifetime is bound to the pool instead of being unbounded.
102102
#[inline]
103103
#[allow(clippy::needless_lifetimes)]
104-
pub unsafe fn ptr_as_ref<'p, T>(&'p self, ptr: *const T) -> &'p T {
104+
pub unsafe fn ptr_as_ref<'p, T: ?Sized>(&'p self, ptr: *const T) -> &'p T {
105105
self.__verify_is_inner();
106106
// SAFETY: Checked by the caller
107107
unsafe { &*ptr }
@@ -122,7 +122,7 @@ impl AutoreleasePool {
122122
#[inline]
123123
#[allow(clippy::needless_lifetimes)]
124124
#[allow(clippy::mut_from_ref)]
125-
pub unsafe fn ptr_as_mut<'p, T>(&'p self, ptr: *mut T) -> &'p mut T {
125+
pub unsafe fn ptr_as_mut<'p, T: ?Sized>(&'p self, ptr: *mut T) -> &'p mut T {
126126
self.__verify_is_inner();
127127
// SAFETY: Checked by the caller
128128
unsafe { &mut *ptr }

objc2/src/rc/id.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ use crate::Message;
5353
/// do so. If you need to run some code when the object is destroyed,
5454
/// implement the `dealloc` method instead.
5555
///
56+
/// This allows `?Sized` types `T`, but the intention is to only support when
57+
/// `T` is an `extern type` (yet unstable).
58+
///
5659
/// # Examples
5760
///
5861
/// ```no_run
@@ -95,9 +98,9 @@ use crate::Message;
9598
/// ```
9699
#[repr(transparent)]
97100
// TODO: Figure out if `Message` bound on `T` would be better here?
98-
// TODO: Add `?Sized + ptr::Thin` bound on `T` to allow for extern types
101+
// TODO: Add `ptr::Thin` bound on `T` to allow for only extern types
99102
// TODO: Consider changing the name of Id -> Retain
100-
pub struct Id<T, O: Ownership> {
103+
pub struct Id<T: ?Sized, O: Ownership> {
101104
/// A pointer to the contained object. The pointer is always retained.
102105
///
103106
/// It is important that this is `NonNull`, since we want to dereference
@@ -116,8 +119,7 @@ pub struct Id<T, O: Ownership> {
116119
own: PhantomData<O>,
117120
}
118121

119-
// TODO: Maybe make most of these functions "associated" functions instead?
120-
impl<T: Message, O: Ownership> Id<T, O> {
122+
impl<T: Message + ?Sized, O: Ownership> Id<T, O> {
121123
/// Constructs an [`Id`] to an object that already has +1 retain count.
122124
///
123125
/// This is useful when you have a retain count that has been handed off
@@ -171,7 +173,10 @@ impl<T: Message, O: Ownership> Id<T, O> {
171173
own: PhantomData,
172174
}
173175
}
176+
}
174177

178+
// TODO: Add ?Sized bound
179+
impl<T: Message, O: Ownership> Id<T, O> {
175180
/// Retains the given object pointer.
176181
///
177182
/// This is useful when you have been given a pointer to an object from
@@ -254,6 +259,7 @@ impl<T: Message, O: Ownership> Id<T, O> {
254259
// }
255260
// }
256261

262+
// TODO: Add ?Sized bound
257263
impl<T: Message> Id<T, Owned> {
258264
/// Autoreleases the owned [`Id`], returning a mutable reference bound to
259265
/// the pool.
@@ -291,6 +297,7 @@ impl<T: Message> Id<T, Owned> {
291297
}
292298
}
293299

300+
// TODO: Add ?Sized bound
294301
impl<T: Message> Id<T, Shared> {
295302
/// Autoreleases the shared [`Id`], returning an aliased reference bound
296303
/// to the pool.
@@ -308,7 +315,7 @@ impl<T: Message> Id<T, Shared> {
308315
}
309316
}
310317

311-
impl<T: Message> From<Id<T, Owned>> for Id<T, Shared> {
318+
impl<T: Message + ?Sized> From<Id<T, Owned>> for Id<T, Shared> {
312319
/// Downgrade from an owned to a shared [`Id`], allowing it to be cloned.
313320
#[inline]
314321
fn from(obj: Id<T, Owned>) -> Self {
@@ -318,6 +325,7 @@ impl<T: Message> From<Id<T, Owned>> for Id<T, Shared> {
318325
}
319326
}
320327

328+
// TODO: Add ?Sized bound
321329
impl<T: Message> Clone for Id<T, Shared> {
322330
/// Makes a clone of the shared object.
323331
///
@@ -338,7 +346,7 @@ impl<T: Message> Clone for Id<T, Shared> {
338346
/// borrowed data.
339347
///
340348
/// [dropck_eyepatch]: https://doc.rust-lang.org/nightly/nomicon/dropck.html#an-escape-hatch
341-
impl<T, O: Ownership> Drop for Id<T, O> {
349+
impl<T: ?Sized, O: Ownership> Drop for Id<T, O> {
342350
/// Releases the retained object.
343351
///
344352
/// The contained object's destructor (if it has one) is never run!
@@ -363,25 +371,25 @@ impl<T, O: Ownership> Drop for Id<T, O> {
363371
/// clone a `Id<T, Shared>`, send it to another thread, and drop the clone
364372
/// last, making `dealloc` get called on the other thread, and violate
365373
/// `T: !Send`.
366-
unsafe impl<T: Sync + Send> Send for Id<T, Shared> {}
374+
unsafe impl<T: Sync + Send + ?Sized> Send for Id<T, Shared> {}
367375

368376
/// The `Sync` implementation requires `T: Sync` because `&Id<T, Shared>` give
369377
/// access to `&T`.
370378
///
371379
/// Additiontally, it requires `T: Send`, because if `T: !Send`, you could
372380
/// clone a `&Id<T, Shared>` from another thread, and drop the clone last,
373381
/// making `dealloc` get called on the other thread, and violate `T: !Send`.
374-
unsafe impl<T: Sync + Send> Sync for Id<T, Shared> {}
382+
unsafe impl<T: Sync + Send + ?Sized> Sync for Id<T, Shared> {}
375383

376384
/// `Id<T, Owned>` are `Send` if `T` is `Send` because they give the same
377385
/// access as having a T directly.
378-
unsafe impl<T: Send> Send for Id<T, Owned> {}
386+
unsafe impl<T: Send + ?Sized> Send for Id<T, Owned> {}
379387

380388
/// `Id<T, Owned>` are `Sync` if `T` is `Sync` because they give the same
381389
/// access as having a `T` directly.
382-
unsafe impl<T: Sync> Sync for Id<T, Owned> {}
390+
unsafe impl<T: Sync + ?Sized> Sync for Id<T, Owned> {}
383391

384-
impl<T, O: Ownership> Deref for Id<T, O> {
392+
impl<T: ?Sized, O: Ownership> Deref for Id<T, O> {
385393
type Target = T;
386394

387395
/// Obtain an immutable reference to the object.
@@ -393,7 +401,7 @@ impl<T, O: Ownership> Deref for Id<T, O> {
393401
}
394402
}
395403

396-
impl<T> DerefMut for Id<T, Owned> {
404+
impl<T: ?Sized> DerefMut for Id<T, Owned> {
397405
/// Obtain a mutable reference to the object.
398406
#[inline]
399407
fn deref_mut(&mut self) -> &mut T {
@@ -404,7 +412,7 @@ impl<T> DerefMut for Id<T, Owned> {
404412
}
405413
}
406414

407-
impl<T, O: Ownership> fmt::Pointer for Id<T, O> {
415+
impl<T: ?Sized, O: Ownership> fmt::Pointer for Id<T, O> {
408416
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
409417
fmt::Pointer::fmt(&self.ptr.as_ptr(), f)
410418
}
@@ -414,15 +422,15 @@ impl<T, O: Ownership> fmt::Pointer for Id<T, O> {
414422
//
415423
// See https://doc.rust-lang.org/1.54.0/src/alloc/boxed.rs.html#1652-1675
416424
// and the `Arc` implementation.
417-
impl<T, O: Ownership> Unpin for Id<T, O> {}
425+
impl<T: ?Sized, O: Ownership> Unpin for Id<T, O> {}
418426

419-
impl<T: RefUnwindSafe, O: Ownership> RefUnwindSafe for Id<T, O> {}
427+
impl<T: RefUnwindSafe + ?Sized, O: Ownership> RefUnwindSafe for Id<T, O> {}
420428

421429
// Same as `Arc<T>`.
422-
impl<T: RefUnwindSafe> UnwindSafe for Id<T, Shared> {}
430+
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Id<T, Shared> {}
423431

424432
// Same as `Box<T>`.
425-
impl<T: UnwindSafe> UnwindSafe for Id<T, Owned> {}
433+
impl<T: UnwindSafe + ?Sized> UnwindSafe for Id<T, Owned> {}
426434

427435
#[cfg(test)]
428436
mod tests {

objc2/src/rc/id_forwarding_impls.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::io;
2121

2222
use super::{Id, Owned, Ownership};
2323

24-
impl<T: PartialEq, O: Ownership> PartialEq for Id<T, O> {
24+
impl<T: PartialEq + ?Sized, O: Ownership> PartialEq for Id<T, O> {
2525
#[inline]
2626
fn eq(&self, other: &Self) -> bool {
2727
(**self).eq(&**other)
@@ -34,9 +34,9 @@ impl<T: PartialEq, O: Ownership> PartialEq for Id<T, O> {
3434
}
3535
}
3636

37-
impl<T: Eq, O: Ownership> Eq for Id<T, O> {}
37+
impl<T: Eq + ?Sized, O: Ownership> Eq for Id<T, O> {}
3838

39-
impl<T: PartialOrd, O: Ownership> PartialOrd for Id<T, O> {
39+
impl<T: PartialOrd + ?Sized, O: Ownership> PartialOrd for Id<T, O> {
4040
#[inline]
4141
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
4242
(**self).partial_cmp(&**other)
@@ -59,20 +59,20 @@ impl<T: PartialOrd, O: Ownership> PartialOrd for Id<T, O> {
5959
}
6060
}
6161

62-
impl<T: Ord, O: Ownership> Ord for Id<T, O> {
62+
impl<T: Ord + ?Sized, O: Ownership> Ord for Id<T, O> {
6363
#[inline]
6464
fn cmp(&self, other: &Self) -> Ordering {
6565
(**self).cmp(&**other)
6666
}
6767
}
6868

69-
impl<T: hash::Hash, O: Ownership> hash::Hash for Id<T, O> {
69+
impl<T: hash::Hash + ?Sized, O: Ownership> hash::Hash for Id<T, O> {
7070
fn hash<H: hash::Hasher>(&self, state: &mut H) {
7171
(**self).hash(state)
7272
}
7373
}
7474

75-
impl<T: hash::Hasher> hash::Hasher for Id<T, Owned> {
75+
impl<T: hash::Hasher + ?Sized> hash::Hasher for Id<T, Owned> {
7676
fn finish(&self) -> u64 {
7777
(**self).finish()
7878
}
@@ -117,19 +117,19 @@ impl<T: hash::Hasher> hash::Hasher for Id<T, Owned> {
117117
}
118118
}
119119

120-
impl<T: fmt::Display, O: Ownership> fmt::Display for Id<T, O> {
120+
impl<T: fmt::Display + ?Sized, O: Ownership> fmt::Display for Id<T, O> {
121121
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122122
(**self).fmt(f)
123123
}
124124
}
125125

126-
impl<T: fmt::Debug, O: Ownership> fmt::Debug for Id<T, O> {
126+
impl<T: fmt::Debug + ?Sized, O: Ownership> fmt::Debug for Id<T, O> {
127127
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128128
(**self).fmt(f)
129129
}
130130
}
131131

132-
impl<I: Iterator> Iterator for Id<I, Owned> {
132+
impl<I: Iterator + ?Sized> Iterator for Id<I, Owned> {
133133
type Item = I::Item;
134134
fn next(&mut self) -> Option<I::Item> {
135135
(**self).next()
@@ -142,7 +142,7 @@ impl<I: Iterator> Iterator for Id<I, Owned> {
142142
}
143143
}
144144

145-
impl<I: DoubleEndedIterator> DoubleEndedIterator for Id<I, Owned> {
145+
impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Id<I, Owned> {
146146
fn next_back(&mut self) -> Option<I::Item> {
147147
(**self).next_back()
148148
}
@@ -151,13 +151,13 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for Id<I, Owned> {
151151
}
152152
}
153153

154-
impl<I: ExactSizeIterator> ExactSizeIterator for Id<I, Owned> {
154+
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Id<I, Owned> {
155155
fn len(&self) -> usize {
156156
(**self).len()
157157
}
158158
}
159159

160-
impl<I: FusedIterator> FusedIterator for Id<I, Owned> {}
160+
impl<I: FusedIterator + ?Sized> FusedIterator for Id<I, Owned> {}
161161

162162
impl<T, O: Ownership> borrow::Borrow<T> for Id<T, O> {
163163
fn borrow(&self) -> &T {
@@ -171,25 +171,25 @@ impl<T> borrow::BorrowMut<T> for Id<T, Owned> {
171171
}
172172
}
173173

174-
impl<T, O: Ownership> AsRef<T> for Id<T, O> {
174+
impl<T: ?Sized, O: Ownership> AsRef<T> for Id<T, O> {
175175
fn as_ref(&self) -> &T {
176176
&**self
177177
}
178178
}
179179

180-
impl<T> AsMut<T> for Id<T, Owned> {
180+
impl<T: ?Sized> AsMut<T> for Id<T, Owned> {
181181
fn as_mut(&mut self) -> &mut T {
182182
&mut **self
183183
}
184184
}
185185

186-
impl<T: Error, O: Ownership> Error for Id<T, O> {
186+
impl<T: Error + ?Sized, O: Ownership> Error for Id<T, O> {
187187
fn source(&self) -> Option<&(dyn Error + 'static)> {
188188
(**self).source()
189189
}
190190
}
191191

192-
impl<T: io::Read> io::Read for Id<T, Owned> {
192+
impl<T: io::Read + ?Sized> io::Read for Id<T, Owned> {
193193
#[inline]
194194
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
195195
(**self).read(buf)
@@ -216,7 +216,7 @@ impl<T: io::Read> io::Read for Id<T, Owned> {
216216
}
217217
}
218218

219-
impl<T: io::Write> io::Write for Id<T, Owned> {
219+
impl<T: io::Write + ?Sized> io::Write for Id<T, Owned> {
220220
#[inline]
221221
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
222222
(**self).write(buf)
@@ -243,7 +243,7 @@ impl<T: io::Write> io::Write for Id<T, Owned> {
243243
}
244244
}
245245

246-
impl<T: io::Seek> io::Seek for Id<T, Owned> {
246+
impl<T: io::Seek + ?Sized> io::Seek for Id<T, Owned> {
247247
#[inline]
248248
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
249249
(**self).seek(pos)
@@ -255,7 +255,7 @@ impl<T: io::Seek> io::Seek for Id<T, Owned> {
255255
}
256256
}
257257

258-
impl<T: io::BufRead> io::BufRead for Id<T, Owned> {
258+
impl<T: io::BufRead + ?Sized> io::BufRead for Id<T, Owned> {
259259
#[inline]
260260
fn fill_buf(&mut self) -> io::Result<&[u8]> {
261261
(**self).fill_buf()
@@ -277,7 +277,7 @@ impl<T: io::BufRead> io::BufRead for Id<T, Owned> {
277277
}
278278
}
279279

280-
impl<T: Future + Unpin> Future for Id<T, Owned> {
280+
impl<T: Future + Unpin + ?Sized> Future for Id<T, Owned> {
281281
type Output = T::Output;
282282

283283
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

0 commit comments

Comments
 (0)