Skip to content

Commit 13dafa0

Browse files
committed
auto merge of #13050 : alexcrichton/rust/no-send-default, r=huonw
See #10296 for the rationale, and commits for the implementation.
2 parents 8eaada5 + 8d0be73 commit 13dafa0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+405
-392
lines changed

Diff for: src/doc/tutorial.md

+17-15
Original file line numberDiff line numberDiff line change
@@ -2103,7 +2103,7 @@ a `&T` pointer. `MutexArc` is an example of a *sharable* type with internal muta
21032103
These are types that do not contain any data whose lifetime is bound to
21042104
a particular stack frame. These are types that do not contain any
21052105
references, or types where the only contained references
2106-
have the `'static` lifetime. (For more on named lifetimes and their uses,
2106+
have the `'static` lifetime. (For more on named lifetimes and their uses,
21072107
see the [references and lifetimes guide][lifetimes].)
21082108
21092109
> ***Note:*** These two traits were referred to as 'kinds' in earlier
@@ -2430,23 +2430,25 @@ select the method to call at runtime.
24302430
24312431
This usage of traits is similar to Java interfaces.
24322432
2433-
By default, each of the three storage classes for traits enforce a
2434-
particular set of built-in kinds that their contents must fulfill in
2435-
order to be packaged up in a trait object of that storage class.
2433+
There are some built-in bounds, such as `Send` and `Share`, which are properties
2434+
of the components of types. By design, trait objects don't know the exact type
2435+
of their contents and so the compiler cannot reason about those properties.
24362436
2437-
* The contents of owned traits (`~Trait`) must fulfill the `Send` bound.
2438-
* The contents of reference traits (`&Trait`) are not constrained by any bound.
2437+
You can instruct the compiler, however, that the contents of a trait object must
2438+
acribe to a particular bound with a trailing colon (`:`). These are examples of
2439+
valid types:
24392440
2440-
Consequently, the trait objects themselves automatically fulfill their
2441-
respective kind bounds. However, this default behavior can be overridden by
2442-
specifying a list of bounds on the trait type, for example, by writing `~Trait:`
2443-
(which indicates that the contents of the owned trait need not fulfill any
2444-
bounds), or by writing `~Trait:Send+Share`, which indicates that in addition
2445-
to fulfilling `Send`, contents must also fulfill `Share`, and as a consequence,
2446-
the trait itself fulfills `Share`.
2441+
~~~rust
2442+
trait Foo {}
2443+
trait Bar<T> {}
24472444
2448-
* `~Trait:Send` is equivalent to `~Trait`.
2449-
* `&Trait:` is equivalent to `&Trait`.
2445+
fn sendable_foo(f: ~Foo:Send) { /* ... */ }
2446+
fn shareable_bar<T: Share>(b: &Bar<T>: Share) { /* ... */ }
2447+
~~~
2448+
2449+
When no colon is specified (such as the type `~Foo`), it is inferred that the
2450+
value ascribes to no bounds. They must be added manually if any bounds are
2451+
necessary for usage.
24502452

24512453
Builtin kind bounds can also be specified on closure types in the same way (for
24522454
example, by writing `fn:Send()`), and the default behaviours are the same as

Diff for: src/libgreen/basic.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ use std::rt::rtio::{EventLoop, IoFactory, RemoteCallback, PausableIdleCallback,
2222
use std::unstable::sync::Exclusive;
2323

2424
/// This is the only exported function from this module.
25-
pub fn event_loop() -> ~EventLoop {
26-
~BasicLoop::new() as ~EventLoop
25+
pub fn event_loop() -> ~EventLoop:Send {
26+
~BasicLoop::new() as ~EventLoop:Send
2727
}
2828

2929
struct BasicLoop {
30-
work: ~[proc()], // pending work
30+
work: ~[proc:Send()], // pending work
3131
idle: Option<*mut BasicPausable>, // only one is allowed
32-
remotes: ~[(uint, ~Callback)],
32+
remotes: ~[(uint, ~Callback:Send)],
3333
next_remote: uint,
3434
messages: Exclusive<~[Message]>,
3535
}
@@ -135,26 +135,28 @@ impl EventLoop for BasicLoop {
135135
}
136136
}
137137

138-
fn callback(&mut self, f: proc()) {
138+
fn callback(&mut self, f: proc:Send()) {
139139
self.work.push(f);
140140
}
141141

142142
// FIXME: Seems like a really weird requirement to have an event loop provide.
143-
fn pausable_idle_callback(&mut self, cb: ~Callback) -> ~PausableIdleCallback {
143+
fn pausable_idle_callback(&mut self, cb: ~Callback:Send)
144+
-> ~PausableIdleCallback:Send
145+
{
144146
let callback = ~BasicPausable::new(self, cb);
145147
rtassert!(self.idle.is_none());
146148
unsafe {
147149
let cb_ptr: &*mut BasicPausable = cast::transmute(&callback);
148150
self.idle = Some(*cb_ptr);
149151
}
150-
return callback as ~PausableIdleCallback;
152+
callback as ~PausableIdleCallback:Send
151153
}
152154

153-
fn remote_callback(&mut self, f: ~Callback) -> ~RemoteCallback {
155+
fn remote_callback(&mut self, f: ~Callback:Send) -> ~RemoteCallback:Send {
154156
let id = self.next_remote;
155157
self.next_remote += 1;
156158
self.remotes.push((id, f));
157-
~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback
159+
~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback:Send
158160
}
159161

160162
fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> { None }
@@ -195,12 +197,12 @@ impl Drop for BasicRemote {
195197

196198
struct BasicPausable {
197199
eloop: *mut BasicLoop,
198-
work: ~Callback,
200+
work: ~Callback:Send,
199201
active: bool,
200202
}
201203

202204
impl BasicPausable {
203-
fn new(eloop: &mut BasicLoop, cb: ~Callback) -> BasicPausable {
205+
fn new(eloop: &mut BasicLoop, cb: ~Callback:Send) -> BasicPausable {
204206
BasicPausable {
205207
active: false,
206208
work: cb,

Diff for: src/libgreen/lib.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ pub mod task;
247247
/// The return value is used as the process return code. 0 on success, 101 on
248248
/// error.
249249
pub fn start(argc: int, argv: **u8,
250-
event_loop_factory: fn() -> ~rtio::EventLoop,
250+
event_loop_factory: fn() -> ~rtio::EventLoop:Send,
251251
main: proc()) -> int {
252252
rt::init(argc, argv);
253253
let mut main = Some(main);
@@ -268,7 +268,8 @@ pub fn start(argc: int, argv: **u8,
268268
///
269269
/// This function will not return until all schedulers in the associated pool
270270
/// have returned.
271-
pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop, main: proc()) -> int {
271+
pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop:Send,
272+
main: proc()) -> int {
272273
// Create a scheduler pool and spawn the main task into this pool. We will
273274
// get notified over a channel when the main task exits.
274275
let mut cfg = PoolConfig::new();
@@ -298,7 +299,7 @@ pub struct PoolConfig {
298299
threads: uint,
299300
/// A factory function used to create new event loops. If this is not
300301
/// specified then the default event loop factory is used.
301-
event_loop_factory: fn() -> ~rtio::EventLoop,
302+
event_loop_factory: fn() -> ~rtio::EventLoop:Send,
302303
}
303304

304305
impl PoolConfig {
@@ -323,7 +324,7 @@ pub struct SchedPool {
323324
priv stack_pool: StackPool,
324325
priv deque_pool: deque::BufferPool<~task::GreenTask>,
325326
priv sleepers: SleeperList,
326-
priv factory: fn() -> ~rtio::EventLoop,
327+
priv factory: fn() -> ~rtio::EventLoop:Send,
327328
priv task_state: TaskState,
328329
priv tasks_done: Receiver<()>,
329330
}

Diff for: src/libgreen/sched.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub struct Scheduler {
7979
/// A fast XorShift rng for scheduler use
8080
rng: XorShiftRng,
8181
/// A togglable idle callback
82-
idle_callback: Option<~PausableIdleCallback>,
82+
idle_callback: Option<~PausableIdleCallback:Send>,
8383
/// A countdown that starts at a random value and is decremented
8484
/// every time a yield check is performed. When it hits 0 a task
8585
/// will yield.
@@ -99,7 +99,7 @@ pub struct Scheduler {
9999
// destroyed before it's actually destroyed.
100100

101101
/// The event loop used to drive the scheduler and perform I/O
102-
event_loop: ~EventLoop,
102+
event_loop: ~EventLoop:Send,
103103
}
104104

105105
/// An indication of how hard to work on a given operation, the difference
@@ -122,7 +122,7 @@ impl Scheduler {
122122
// * Initialization Functions
123123

124124
pub fn new(pool_id: uint,
125-
event_loop: ~EventLoop,
125+
event_loop: ~EventLoop:Send,
126126
work_queue: deque::Worker<~GreenTask>,
127127
work_queues: ~[deque::Stealer<~GreenTask>],
128128
sleeper_list: SleeperList,
@@ -135,7 +135,7 @@ impl Scheduler {
135135
}
136136

137137
pub fn new_special(pool_id: uint,
138-
event_loop: ~EventLoop,
138+
event_loop: ~EventLoop:Send,
139139
work_queue: deque::Worker<~GreenTask>,
140140
work_queues: ~[deque::Stealer<~GreenTask>],
141141
sleeper_list: SleeperList,
@@ -182,7 +182,7 @@ impl Scheduler {
182182
pub fn bootstrap(mut ~self) {
183183

184184
// Build an Idle callback.
185-
let cb = ~SchedRunner as ~Callback;
185+
let cb = ~SchedRunner as ~Callback:Send;
186186
self.idle_callback = Some(self.event_loop.pausable_idle_callback(cb));
187187

188188
// Create a task for the scheduler with an empty context.
@@ -230,7 +230,7 @@ impl Scheduler {
230230
// mutable reference to the event_loop to give it the "run"
231231
// command.
232232
unsafe {
233-
let event_loop: *mut ~EventLoop = &mut self.event_loop;
233+
let event_loop: *mut ~EventLoop:Send = &mut self.event_loop;
234234
// Our scheduler must be in the task before the event loop
235235
// is started.
236236
stask.put_with_sched(self);
@@ -868,7 +868,7 @@ impl Scheduler {
868868
}
869869

870870
pub fn make_handle(&mut self) -> SchedHandle {
871-
let remote = self.event_loop.remote_callback(~SchedRunner as ~Callback);
871+
let remote = self.event_loop.remote_callback(~SchedRunner);
872872

873873
return SchedHandle {
874874
remote: remote,
@@ -893,7 +893,7 @@ pub enum SchedMessage {
893893
}
894894

895895
pub struct SchedHandle {
896-
priv remote: ~RemoteCallback,
896+
priv remote: ~RemoteCallback:Send,
897897
priv queue: msgq::Producer<SchedMessage>,
898898
sched_id: uint
899899
}
@@ -1007,7 +1007,6 @@ mod test {
10071007

10081008
use std::comm;
10091009
use std::task::TaskOpts;
1010-
use std::rt::Runtime;
10111010
use std::rt::task::Task;
10121011
use std::rt::local::Local;
10131012

@@ -1034,7 +1033,7 @@ mod test {
10341033
match task.get().maybe_take_runtime::<GreenTask>() {
10351034
Some(green) => {
10361035
let ret = green.sched.get_ref().sched_id();
1037-
task.get().put_runtime(green as ~Runtime);
1036+
task.get().put_runtime(green);
10381037
return ret;
10391038
}
10401039
None => fail!()

Diff for: src/libgreen/simple.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl Runtime for SimpleTask {
3434

3535
let me = &mut *self as *mut SimpleTask;
3636
let cur_dupe = &*cur_task as *Task;
37-
cur_task.put_runtime(self as ~Runtime);
37+
cur_task.put_runtime(self);
3838
let task = BlockedTask::block(cur_task);
3939

4040
// See libnative/task.rs for what's going on here with the `awoken`
@@ -57,7 +57,7 @@ impl Runtime for SimpleTask {
5757
}
5858
fn reawaken(mut ~self, mut to_wake: ~Task) {
5959
let me = &mut *self as *mut SimpleTask;
60-
to_wake.put_runtime(self as ~Runtime);
60+
to_wake.put_runtime(self);
6161
unsafe {
6262
cast::forget(to_wake);
6363
let guard = (*me).lock.lock();
@@ -86,6 +86,6 @@ pub fn task() -> ~Task {
8686
task.put_runtime(~SimpleTask {
8787
lock: unsafe {NativeMutex::new()},
8888
awoken: false,
89-
} as ~Runtime);
89+
});
9090
return task;
9191
}

Diff for: src/libgreen/task.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ impl GreenTask {
287287

288288
pub fn swap(mut ~self) -> ~Task {
289289
let mut task = self.task.take_unwrap();
290-
task.put_runtime(self as ~Runtime);
290+
task.put_runtime(self);
291291
return task;
292292
}
293293

@@ -482,7 +482,6 @@ impl Runtime for GreenTask {
482482

483483
#[cfg(test)]
484484
mod tests {
485-
use std::rt::Runtime;
486485
use std::rt::local::Local;
487486
use std::rt::task::Task;
488487
use std::task;
@@ -576,7 +575,7 @@ mod tests {
576575
let mut task: ~Task = Local::take();
577576
match task.maybe_take_runtime::<GreenTask>() {
578577
Some(ops) => {
579-
task.put_runtime(ops as ~Runtime);
578+
task.put_runtime(ops);
580579
}
581580
None => fail!(),
582581
}

Diff for: src/liblog/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub static WARN: u32 = 2;
156156
/// Error log level
157157
pub static ERROR: u32 = 1;
158158

159-
local_data_key!(local_logger: ~Logger)
159+
local_data_key!(local_logger: ~Logger:Send)
160160

161161
/// A trait used to represent an interface to a task-local logger. Each task
162162
/// can have its own custom logger which can respond to logging messages
@@ -203,7 +203,7 @@ pub fn log(level: u32, args: &fmt::Arguments) {
203203
// frob the slot while we're doing the logging. This will destroy any logger
204204
// set during logging.
205205
let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
206-
~DefaultLogger { handle: io::stderr() } as ~Logger
206+
~DefaultLogger { handle: io::stderr() } as ~Logger:Send
207207
});
208208
logger.log(level, args);
209209
local_data::set(local_logger, logger);
@@ -217,7 +217,7 @@ pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
217217

218218
/// Replaces the task-local logger with the specified logger, returning the old
219219
/// logger.
220-
pub fn set_logger(logger: ~Logger) -> Option<~Logger> {
220+
pub fn set_logger(logger: ~Logger:Send) -> Option<~Logger:Send> {
221221
let prev = local_data::pop(local_logger);
222222
local_data::set(local_logger, logger);
223223
return prev;

Diff for: src/libnative/io/file_unix.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ impl rtio::RtioPipe for FileDesc {
176176
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
177177
self.inner_write(buf)
178178
}
179-
fn clone(&self) -> ~rtio::RtioPipe {
180-
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe
179+
fn clone(&self) -> ~rtio::RtioPipe:Send {
180+
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe:Send
181181
}
182182
}
183183

Diff for: src/libnative/io/file_win32.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ impl rtio::RtioPipe for FileDesc {
206206
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
207207
self.inner_write(buf)
208208
}
209-
fn clone(&self) -> ~rtio::RtioPipe {
210-
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe
209+
fn clone(&self) -> ~rtio::RtioPipe:Send {
210+
~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe:Send
211211
}
212212
}
213213

0 commit comments

Comments
 (0)