Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support T: ?Sized #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/futures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use futures_core::Stream;

use crate::SendWrapper;

impl<F: Future> Future for SendWrapper<F> {
impl<F: ?Sized + Future> Future for SendWrapper<F> {
type Output = F::Output;

/// Polls this [`SendWrapper`] [`Future`].
Expand All @@ -28,7 +28,7 @@ impl<F: Future> Future for SendWrapper<F> {
}
}

impl<S: Stream> Stream for SendWrapper<S> {
impl<S: ?Sized + Stream> Stream for SendWrapper<S> {
type Item = S::Item;

/// Polls this [`SendWrapper`] [`Stream`].
Expand Down
30 changes: 16 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ use std::thread::{self, ThreadId};

/// A wrapper which allows you to move around non-[`Send`]-types between threads, as long as you access the contained
/// value only from within the original thread and make sure that it is dropped from within the original thread.
pub struct SendWrapper<T> {
data: ManuallyDrop<T>,
pub struct SendWrapper<T: ?Sized> {
thread_id: ThreadId,
data: ManuallyDrop<T>,
}

impl<T> SendWrapper<T> {
Expand All @@ -118,11 +118,6 @@ impl<T> SendWrapper<T> {
}
}

/// Returns `true` if the value can be safely accessed from within the current thread.
pub fn valid(&self) -> bool {
self.thread_id == thread::current().id()
}

/// Takes the value out of the `SendWrapper<T>`.
///
/// # Panics
Expand All @@ -141,6 +136,13 @@ impl<T> SendWrapper<T> {
// - We only move out from `self.data` here and in drop, so `self.data` is present
unsafe { ManuallyDrop::take(&mut this.data) }
}
}

impl<T: ?Sized> SendWrapper<T> {
/// Returns `true` if the value can be safely accessed from within the current thread.
pub fn valid(&self) -> bool {
self.thread_id == thread::current().id()
}

#[track_caller]
fn assert_valid_for_deref(&self) {
Expand All @@ -157,10 +159,10 @@ impl<T> SendWrapper<T> {
}
}

unsafe impl<T> Send for SendWrapper<T> {}
unsafe impl<T> Sync for SendWrapper<T> {}
unsafe impl<T: ?Sized> Send for SendWrapper<T> {}
unsafe impl<T: ?Sized> Sync for SendWrapper<T> {}

impl<T> Deref for SendWrapper<T> {
impl<T: ?Sized> Deref for SendWrapper<T> {
type Target = T;

/// Returns a reference to the contained value.
Expand All @@ -180,7 +182,7 @@ impl<T> Deref for SendWrapper<T> {
}
}

impl<T> DerefMut for SendWrapper<T> {
impl<T: ?Sized> DerefMut for SendWrapper<T> {
/// Returns a mutable reference to the contained value.
///
/// # Panics
Expand All @@ -198,7 +200,7 @@ impl<T> DerefMut for SendWrapper<T> {
}
}

impl<T> Drop for SendWrapper<T> {
impl<T: ?Sized> Drop for SendWrapper<T> {
/// Drops the contained value.
///
/// # Panics
Expand Down Expand Up @@ -232,7 +234,7 @@ impl<T> Drop for SendWrapper<T> {
}
}

impl<T: fmt::Debug> fmt::Debug for SendWrapper<T> {
impl<T: ?Sized + fmt::Debug> fmt::Debug for SendWrapper<T> {
/// Formats the value using the given formatter.
///
/// # Panics
Expand All @@ -242,7 +244,7 @@ impl<T: fmt::Debug> fmt::Debug for SendWrapper<T> {
#[track_caller]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SendWrapper")
.field("data", self.deref())
.field("data", &self.deref())
.field("thread_id", &self.thread_id)
.finish()
}
Expand Down