From f436f9ca2963e33cc41802370bb9c551c833970e Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 22 Dec 2014 00:49:42 +0100 Subject: [PATCH] Make Send and Sync traits unsafe --- src/liballoc/arc.rs | 4 ++-- src/libcore/cell.rs | 4 ++-- src/libcore/kinds.rs | 4 ++-- src/libcore/ptr.rs | 4 ++-- src/librustc_trans/back/write.rs | 2 +- src/librustc_trans/trans/mod.rs | 4 ++-- src/libstd/c_str.rs | 4 ++-- src/libstd/comm/blocking.rs | 5 ++++- src/libstd/comm/mod.rs | 4 ++-- src/libstd/comm/mpsc_queue.rs | 4 ++-- src/libstd/comm/spsc_queue.rs | 4 ++-- src/libstd/comm/sync.rs | 9 +++++---- src/libstd/rt/exclusive.rs | 4 ++-- src/libstd/sync/mutex.rs | 9 +++++---- src/libstd/sync/once.rs | 4 +++- src/libstd/sys/common/helper_thread.rs | 4 ++-- src/libstd/sys/common/mutex.rs | 4 +++- src/libstd/sys/unix/c.rs | 4 ++-- src/libstd/sys/unix/mutex.rs | 4 +++- src/libstd/sys/unix/pipe.rs | 6 ++++-- src/libstd/sys/unix/tcp.rs | 6 ++++-- src/libstd/thread.rs | 7 +++++-- src/libstd/thread_local/mod.rs | 4 ++-- src/libstd/thread_local/scoped.rs | 4 ++-- src/libtest/lib.rs | 2 +- src/test/run-pass/const-block.rs | 2 +- src/test/run-pass/const-cast-ptr-int.rs | 2 +- src/test/run-pass/const-cast.rs | 2 +- src/test/run-pass/issue-13837.rs | 2 +- src/test/run-pass/issue-17718-static-unsafe-interior.rs | 2 +- src/test/run-pass/issue-2718.rs | 2 +- src/test/run-pass/typeck_type_placeholder_1.rs | 2 +- 32 files changed, 73 insertions(+), 55 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index e060ecad974..4810e15d68b 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -129,9 +129,9 @@ pub struct Weak { _ptr: *mut ArcInner, } -impl Send for Arc { } +unsafe impl Send for Arc { } -impl Sync for Arc { } +unsafe impl Sync for Arc { } struct ArcInner { strong: atomic::AtomicUint, diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 89118a6a8e4..6fc6c2a569d 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -577,6 +577,6 @@ pub unsafe fn into_inner(self) -> T { } } -impl Send for RacyCell { } +unsafe impl Send for RacyCell { } -impl Sync for RacyCell { } // Oh dear +unsafe impl Sync for RacyCell { } // Oh dear diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs index b0f46e3d68c..fb030ea45f3 100644 --- a/src/libcore/kinds.rs +++ b/src/libcore/kinds.rs @@ -19,7 +19,7 @@ /// Types able to be transferred across task boundaries. #[lang="send"] -pub trait Send for Sized? : 'static { +pub unsafe trait Send for Sized? : 'static { // empty. } @@ -81,7 +81,7 @@ pub trait Copy for Sized? { /// reference; not doing this is undefined behaviour (for example, /// `transmute`-ing from `&T` to `&mut T` is illegal). #[lang="sync"] -pub trait Sync for Sized? { +pub unsafe trait Sync for Sized? { // Empty } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 6bde1015d29..402e85b4d8b 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -515,13 +515,13 @@ fn ge(&self, other: &*mut T) -> bool { *self >= *other } /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `UniquePtr` must enforce it. -impl Send for UniquePtr { } +unsafe impl Send for UniquePtr { } /// `UniquePtr` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `UniquePtr` must enforce it. -impl Sync for UniquePtr { } +unsafe impl Sync for UniquePtr { } impl UniquePtr { /// Returns a null UniquePtr. diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 6348ce89608..513b955da3f 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -281,7 +281,7 @@ struct ModuleConfig { time_passes: bool, } -impl Send for ModuleConfig { } +unsafe impl Send for ModuleConfig { } impl ModuleConfig { fn new(tm: TargetMachineRef, passes: Vec) -> ModuleConfig { diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs index c8cfdd3e4e4..7e4517c209b 100644 --- a/src/librustc_trans/trans/mod.rs +++ b/src/librustc_trans/trans/mod.rs @@ -60,8 +60,8 @@ pub struct ModuleTranslation { pub llmod: ModuleRef, } -impl Send for ModuleTranslation { } -impl Sync for ModuleTranslation { } +unsafe impl Send for ModuleTranslation { } +unsafe impl Sync for ModuleTranslation { } pub struct CrateTranslation { pub modules: Vec, diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index 27b63be6cd0..846b542d81a 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -89,8 +89,8 @@ pub struct CString { owns_buffer_: bool, } -impl Send for CString { } -impl Sync for CString { } +unsafe impl Send for CString { } +unsafe impl Sync for CString { } impl Clone for CString { /// Clone this CString into a new, uniquely owned CString. For safety diff --git a/src/libstd/comm/blocking.rs b/src/libstd/comm/blocking.rs index a154224824c..412b7161305 100644 --- a/src/libstd/comm/blocking.rs +++ b/src/libstd/comm/blocking.rs @@ -13,16 +13,19 @@ use thread::Thread; use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Ordering}; use sync::Arc; +use kinds::{Sync, Send}; use kinds::marker::{NoSend, NoSync}; use mem; use clone::Clone; -#[deriving(Send, Sync)] struct Inner { thread: Thread, woken: AtomicBool, } +unsafe impl Send for Inner {} +unsafe impl Sync for Inner {} + #[deriving(Clone)] pub struct SignalToken { inner: Arc, diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 18b50c621e9..618a5eebf0f 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -363,7 +363,7 @@ pub struct Receiver { // The receiver port can be sent from place to place, so long as it // is not used to receive non-sendable things. -impl Send for Receiver { } +unsafe impl Send for Receiver { } /// An iterator over messages on a receiver, this iterator will block /// whenever `next` is called, waiting for a new message, and `None` will be @@ -382,7 +382,7 @@ pub struct Sender { // The send port can be sent from place to place, so long as it // is not used to send non-sendable things. -impl Send for Sender { } +unsafe impl Send for Sender { } /// The sending-half of Rust's synchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. diff --git a/src/libstd/comm/mpsc_queue.rs b/src/libstd/comm/mpsc_queue.rs index 6298896a18b..cddef236664 100644 --- a/src/libstd/comm/mpsc_queue.rs +++ b/src/libstd/comm/mpsc_queue.rs @@ -76,8 +76,8 @@ pub struct Queue { tail: UnsafeCell<*mut Node>, } -impl Send for Queue { } -impl Sync for Queue { } +unsafe impl Send for Queue { } +unsafe impl Sync for Queue { } impl Node { unsafe fn new(v: Option) -> *mut Node { diff --git a/src/libstd/comm/spsc_queue.rs b/src/libstd/comm/spsc_queue.rs index dbf1f255997..becb78063ae 100644 --- a/src/libstd/comm/spsc_queue.rs +++ b/src/libstd/comm/spsc_queue.rs @@ -73,9 +73,9 @@ pub struct Queue { cache_subtractions: AtomicUint, } -impl Send for Queue { } +unsafe impl Send for Queue { } -impl Sync for Queue { } +unsafe impl Sync for Queue { } impl Node { fn new() -> *mut Node { diff --git a/src/libstd/comm/sync.rs b/src/libstd/comm/sync.rs index f4f4c7472e2..88338849965 100644 --- a/src/libstd/comm/sync.rs +++ b/src/libstd/comm/sync.rs @@ -53,11 +53,10 @@ pub struct Packet { lock: Mutex>, } -impl Send for Packet { } +unsafe impl Send for Packet { } -impl Sync for Packet { } +unsafe impl Sync for Packet { } -#[deriving(Send)] struct State { disconnected: bool, // Is the channel disconnected yet? queue: Queue, // queue of senders waiting to send data @@ -74,6 +73,8 @@ struct State { canceled: Option<&'static mut bool>, } +unsafe impl Send for State {} + /// Possible flavors of threads who can be blocked on this channel. enum Blocker { BlockedSender(SignalToken), @@ -93,7 +94,7 @@ struct Node { next: *mut Node, } -impl Send for Node {} +unsafe impl Send for Node {} /// A simple ring-buffer struct Buffer { diff --git a/src/libstd/rt/exclusive.rs b/src/libstd/rt/exclusive.rs index a878066ad16..88bdb29caec 100644 --- a/src/libstd/rt/exclusive.rs +++ b/src/libstd/rt/exclusive.rs @@ -26,9 +26,9 @@ pub struct Exclusive { data: UnsafeCell, } -impl Send for Exclusive { } +unsafe impl Send for Exclusive { } -impl Sync for Exclusive { } +unsafe impl Sync for Exclusive { } /// An RAII guard returned via `lock` pub struct ExclusiveGuard<'a, T:'a> { diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 2849813c510..d2dafac281a 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -11,7 +11,7 @@ use prelude::*; use cell::{UnsafeCell, RacyCell}; -use kinds::marker; +use kinds::{marker, Sync}; use sync::{poison, AsMutexGuard}; use sys_common::mutex as sys; @@ -73,9 +73,9 @@ pub struct Mutex { data: RacyCell, } -impl Send for Mutex { } +unsafe impl Send for Mutex { } -impl Sync for Mutex { } +unsafe impl Sync for Mutex { } /// The static mutex type is provided to allow for static allocation of mutexes. /// @@ -98,12 +98,13 @@ impl Sync for Mutex { } /// } /// // lock is unlocked here. /// ``` -#[deriving(Sync)] pub struct StaticMutex { lock: sys::Mutex, poison: RacyCell, } +unsafe impl Sync for StaticMutex {} + /// An RAII implementation of a "scoped lock" of a mutex. When this structure is /// dropped (falls out of scope), the lock will be unlocked. /// diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 4b940b0420a..4d9fbb59908 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -14,6 +14,7 @@ //! example use case would be for initializing an FFI library. use int; +use kinds::Sync; use mem::drop; use ops::FnOnce; use sync::atomic; @@ -35,13 +36,14 @@ /// // run initialization here /// }); /// ``` -#[deriving(Sync)] pub struct Once { mutex: StaticMutex, cnt: atomic::AtomicInt, lock_cnt: atomic::AtomicInt, } +unsafe impl Sync for Once {} + /// Initialization value for static `Once` values. pub const ONCE_INIT: Once = Once { mutex: MUTEX_INIT, diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 9df69d8e0d6..b0137bdad06 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -59,9 +59,9 @@ pub struct Helper { pub shutdown: UnsafeCell, } -impl Send for Helper { } +unsafe impl Send for Helper { } -impl Sync for Helper { } +unsafe impl Sync for Helper { } impl Helper { /// Lazily boots a helper thread, becoming a no-op if the helper has already diff --git a/src/libstd/sys/common/mutex.rs b/src/libstd/sys/common/mutex.rs index 5869c280517..567c26956ef 100644 --- a/src/libstd/sys/common/mutex.rs +++ b/src/libstd/sys/common/mutex.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use kinds::Sync; use sys::mutex as imp; /// An OS-based mutual exclusion lock. @@ -15,9 +16,10 @@ /// This is the thinnest cross-platform wrapper around OS mutexes. All usage of /// this mutex is unsafe and it is recommended to instead use the safe wrapper /// at the top level of the crate instead of this type. -#[deriving(Sync)] pub struct Mutex(imp::Mutex); +unsafe impl Sync for Mutex {} + /// Constant initializer for statically allocated mutexes. pub const MUTEX_INIT: Mutex = Mutex(imp::MUTEX_INIT); diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs index a5796f8dd01..a4ebcbd25d0 100644 --- a/src/libstd/sys/unix/c.rs +++ b/src/libstd/sys/unix/c.rs @@ -162,8 +162,8 @@ pub struct sigaction { sa_restorer: *mut libc::c_void, } - impl ::kinds::Send for sigaction { } - impl ::kinds::Sync for sigaction { } + unsafe impl ::kinds::Send for sigaction { } + unsafe impl ::kinds::Sync for sigaction { } #[repr(C)] #[cfg(target_word_size = "32")] diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index 52ed0649694..986f50bc8de 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use kinds::Sync; use cell::{UnsafeCell, RacyCell}; use sys::sync as ffi; use sys_common::mutex; -#[deriving(Sync)] pub struct Mutex { inner: RacyCell } #[inline] @@ -24,6 +24,8 @@ pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t { inner: RacyCell(UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER }), }; +unsafe impl Sync for Mutex {} + impl Mutex { #[inline] pub unsafe fn new() -> Mutex { diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 8d1010937bc..c4aec82894f 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -210,12 +210,13 @@ fn clone(&self) -> UnixStream { // Unix Listener //////////////////////////////////////////////////////////////////////////////// -#[deriving(Sync)] pub struct UnixListener { inner: Inner, path: CString, } +unsafe impl Sync for UnixListener {} + impl UnixListener { pub fn bind(addr: &CString) -> IoResult { bind(addr, libc::SOCK_STREAM).map(|fd| { @@ -253,7 +254,6 @@ pub struct UnixAcceptor { deadline: u64, } -#[deriving(Sync)] struct AcceptorInner { listener: UnixListener, reader: FileDesc, @@ -261,6 +261,8 @@ struct AcceptorInner { closed: atomic::AtomicBool, } +unsafe impl Sync for AcceptorInner {} + impl UnixAcceptor { pub fn fd(&self) -> fd_t { self.inner.listener.fd() } diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index 60ca76171b1..e2a78947e16 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -29,11 +29,12 @@ // TCP listeners //////////////////////////////////////////////////////////////////////////////// -#[deriving(Sync)] pub struct TcpListener { pub inner: FileDesc, } +unsafe impl Sync for TcpListener {} + impl TcpListener { pub fn bind(addr: ip::SocketAddr) -> IoResult { let fd = try!(net::socket(addr, libc::SOCK_STREAM)); @@ -90,7 +91,6 @@ pub struct TcpAcceptor { deadline: u64, } -#[deriving(Sync)] struct AcceptorInner { listener: TcpListener, reader: FileDesc, @@ -98,6 +98,8 @@ struct AcceptorInner { closed: atomic::AtomicBool, } +unsafe impl Sync for AcceptorInner {} + impl TcpAcceptor { pub fn fd(&self) -> sock_t { self.inner.listener.fd() } diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index e3b97afb31d..92aa5201ec3 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -283,19 +283,22 @@ fn spawn_inner(self, f: Thunk<(), T>) -> JoinGuard { } } -#[deriving(Sync)] struct Inner { name: Option, lock: Mutex, // true when there is a buffered unpark cvar: Condvar, } -#[deriving(Clone, Sync)] +unsafe impl Sync for Inner {} + +#[deriving(Clone)] /// A handle to a thread. pub struct Thread { inner: Arc, } +unsafe impl Sync for Thread {} + impl Thread { // Used only internally to construct a thread object without spawning fn new(name: Option) -> Thread { diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index 55fb3151133..242dceb4256 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -280,7 +280,7 @@ pub struct Key { pub dtor_running: UnsafeCell, // should be Cell } - impl ::kinds::Sync for Key { } + unsafe impl ::kinds::Sync for Key { } #[doc(hidden)] impl Key { @@ -412,7 +412,7 @@ pub struct Key { pub os: OsStaticKey, } - impl ::kinds::Sync for Key { } + unsafe impl ::kinds::Sync for Key { } struct Value { key: &'static Key, diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs index 83e61373dd1..d7ea163cc80 100644 --- a/src/libstd/thread_local/scoped.rs +++ b/src/libstd/thread_local/scoped.rs @@ -202,7 +202,7 @@ mod imp { #[doc(hidden)] pub struct KeyInner { pub inner: UnsafeCell<*mut T> } - #[cfg(not(stage0))] impl ::kinds::Sync for KeyInner { } + unsafe impl ::kinds::Sync for KeyInner { } #[doc(hidden)] impl KeyInner { @@ -224,7 +224,7 @@ pub struct KeyInner { pub marker: marker::InvariantType, } - #[cfg(not(stage0))] impl ::kinds::Sync for KeyInner { } + unsafe impl ::kinds::Sync for KeyInner { } #[doc(hidden)] impl KeyInner { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index dc30f973ff7..88dd6fce88f 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -976,7 +976,7 @@ enum TestEvent { pub type MonitorMsg = (TestDesc, TestResult, Vec ); -impl Send for MonitorMsg {} +unsafe impl Send for MonitorMsg {} fn run_tests(opts: &TestOpts, tests: Vec , diff --git a/src/test/run-pass/const-block.rs b/src/test/run-pass/const-block.rs index 81943b9f13a..35783ea5899 100644 --- a/src/test/run-pass/const-block.rs +++ b/src/test/run-pass/const-block.rs @@ -18,7 +18,7 @@ struct Foo { b: *const () } -impl Sync for Foo {} +unsafe impl Sync for Foo {} fn foo(a: T) -> T { a diff --git a/src/test/run-pass/const-cast-ptr-int.rs b/src/test/run-pass/const-cast-ptr-int.rs index e581a3a65d1..50e460bd179 100644 --- a/src/test/run-pass/const-cast-ptr-int.rs +++ b/src/test/run-pass/const-cast-ptr-int.rs @@ -14,7 +14,7 @@ struct TestStruct { x: *const u8 } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} static a: TestStruct = TestStruct{x: 0 as *const u8}; diff --git a/src/test/run-pass/const-cast.rs b/src/test/run-pass/const-cast.rs index 29c119f742f..b7e9c0338dd 100644 --- a/src/test/run-pass/const-cast.rs +++ b/src/test/run-pass/const-cast.rs @@ -14,7 +14,7 @@ struct TestStruct { x: *const libc::c_void } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} extern fn foo() {} const x: extern "C" fn() = foo; diff --git a/src/test/run-pass/issue-13837.rs b/src/test/run-pass/issue-13837.rs index 3a3d236b69d..c6847ce55de 100644 --- a/src/test/run-pass/issue-13837.rs +++ b/src/test/run-pass/issue-13837.rs @@ -12,7 +12,7 @@ struct TestStruct { x: *const [int; 2] } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} static TEST_VALUE : TestStruct = TestStruct{x: 0x1234 as *const [int; 2]}; diff --git a/src/test/run-pass/issue-17718-static-unsafe-interior.rs b/src/test/run-pass/issue-17718-static-unsafe-interior.rs index 9ca1245f067..17dd6d69fd4 100644 --- a/src/test/run-pass/issue-17718-static-unsafe-interior.rs +++ b/src/test/run-pass/issue-17718-static-unsafe-interior.rs @@ -36,7 +36,7 @@ struct Wrap { value: T } -impl Sync for Wrap {} +unsafe impl Sync for Wrap {} static UNSAFE: RacyCell = RacyCell(UnsafeCell{value: 1}); static WRAPPED_UNSAFE: Wrap<&'static RacyCell> = Wrap { value: &UNSAFE }; diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 73cda4ba8fb..d949cab97c2 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -46,7 +46,7 @@ pub struct packet { payload: Option } - impl Send for packet {} + unsafe impl Send for packet {} pub fn packet() -> *const packet { unsafe { diff --git a/src/test/run-pass/typeck_type_placeholder_1.rs b/src/test/run-pass/typeck_type_placeholder_1.rs index 5e9d778e5ba..a8ae3f40f0e 100644 --- a/src/test/run-pass/typeck_type_placeholder_1.rs +++ b/src/test/run-pass/typeck_type_placeholder_1.rs @@ -15,7 +15,7 @@ struct TestStruct { x: *const int } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} static CONSTEXPR: TestStruct = TestStruct{x: &413 as *const _}; -- GitLab