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

Fix call of proc_macro::Span::clone on the wrong thread #1466

Merged
merged 1 commit into from
Jun 5, 2023
Merged
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
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ impl Clone for Error {
impl Clone for ErrorMessage {
fn clone(&self) -> Self {
ErrorMessage {
span: self.span.clone(),
span: self.span,
message: self.message.clone(),
}
}
Expand Down
20 changes: 15 additions & 5 deletions src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ pub(crate) struct ThreadBound<T> {
unsafe impl<T> Sync for ThreadBound<T> {}

// Send bound requires Copy, as otherwise Drop could run in the wrong place.
//
// Today Copy and Drop are mutually exclusive so `T: Copy` implies `T: !Drop`.
// This impl needs to be revisited if that restriction is relaxed in the future.
unsafe impl<T: Copy> Send for ThreadBound<T> {}

impl<T> ThreadBound<T> {
Expand Down Expand Up @@ -40,11 +43,18 @@ impl<T: Debug> Debug for ThreadBound<T> {
}
}

impl<T: Clone> Clone for ThreadBound<T> {
// Copy the bytes of T, even if the currently running thread is the "wrong"
// thread. This is fine as long as the original thread is not simultaneously
// mutating this value via interior mutability, which would be a data race.
//
// Currently `T: Copy` is sufficient to guarantee that T contains no interior
// mutability, because _all_ interior mutability in Rust is built on
// std::cell::UnsafeCell, which has no Copy impl. This impl needs to be
// revisited if that restriction is relaxed in the future.
impl<T: Copy> Copy for ThreadBound<T> {}

impl<T: Copy> Clone for ThreadBound<T> {
fn clone(&self) -> Self {
ThreadBound {
value: self.value.clone(),
thread_id: self.thread_id,
}
*self
}
}