Skip to content
Permalink
Browse files

libsyntax: Remove `~self` and `mut ~self` from the language.

This eliminates the last vestige of the `~` syntax.

Instead of `~self`, write `self: Box<TypeOfSelf>`; instead of `mut
~self`, write `mut self: Box<TypeOfSelf>`, replacing `TypeOfSelf` with
the self-type parameter as specified in the implementation.

Closes rust-lang#13885.

[breaking-change]
  • Loading branch information...
pcwalton committed Jul 23, 2014
1 parent 826b835 commit 07f3f13805b78bac8a565ec54fc94ec5040a0619
@@ -3864,13 +3864,13 @@ Function parameters are immutable unless declared with `mut`. The
and `fn f(mut x: Box<int>, y: Box<int>)` declare one mutable variable `x` and
one immutable variable `y`).

Methods that take either `self` or `~self` can optionally place them in a
Methods that take either `self` or `Box<Self>` can optionally place them in a
mutable slot by prefixing them with `mut` (similar to regular arguments):

~~~
trait Changer {
fn change(mut self) -> Self;
fn modify(mut ~self) -> Box<Self>;
fn modify(mut self: Box<Self>) -> Box<Self>;
}
~~~

@@ -1971,7 +1971,7 @@ like any other function, except for the name `self`.

The type of `self` is the type on which the method is implemented,
or a pointer thereof. As an argument it is written either `self`,
`&self`, or `~self`.
`&self`, or `self: TYPE`.
A caller must in turn have a compatible pointer type to call the method.

~~~
@@ -1984,7 +1984,7 @@ A caller must in turn have a compatible pointer type to call the method.
# }
impl Shape {
fn draw_reference(&self) { /* ... */ }
fn draw_owned(~self) { /* ... */ }
fn draw_owned(self: Box<Shape>) { /* ... */ }
fn draw_value(self) { /* ... */ }
}
@@ -2009,7 +2009,7 @@ to a reference.
# }
# impl Shape {
# fn draw_reference(&self) { /* ... */ }
# fn draw_owned(~self) { /* ... */ }
# fn draw_owned(self: Box<Shape>) { /* ... */ }
# fn draw_value(self) { /* ... */ }
# }
# let s = Circle(Point { x: 1.0, y: 2.0 }, 3.0);
@@ -180,7 +180,7 @@ impl Scheduler {

// Take a main task to run, and a scheduler to run it in. Create a
// scheduler task and bootstrap into it.
pub fn bootstrap(mut ~self) {
pub fn bootstrap(mut self: Box<Scheduler>) {

// Build an Idle callback.
let cb = box SchedRunner as Box<Callback + Send>;
@@ -224,7 +224,8 @@ impl Scheduler {

// This does not return a scheduler, as the scheduler is placed
// inside the task.
pub fn run(mut ~self, stask: Box<GreenTask>) -> Box<GreenTask> {
pub fn run(mut self: Box<Scheduler>, stask: Box<GreenTask>)
-> Box<GreenTask> {

// This is unsafe because we need to place the scheduler, with
// the event_loop inside, inside our task. But we still need a
@@ -271,7 +272,7 @@ impl Scheduler {
// If we try really hard to do some work, but no work is available to be
// done, then we fall back to epoll() to block this thread waiting for more
// work (instead of busy waiting).
fn run_sched_once(mut ~self, stask: Box<GreenTask>) {
fn run_sched_once(mut self: Box<Scheduler>, stask: Box<GreenTask>) {
// Make sure that we're not lying in that the `stask` argument is indeed
// the scheduler task for this scheduler.
assert!(self.sched_task.is_none());
@@ -349,11 +350,10 @@ impl Scheduler {
// returns the still-available scheduler. At this point all
// message-handling will count as a turn of work, and as a result
// return None.
fn interpret_message_queue(mut ~self, stask: Box<GreenTask>,
fn interpret_message_queue(mut self: Box<Scheduler>,
stask: Box<GreenTask>,
effort: EffortLevel)
-> (Box<Scheduler>, Box<GreenTask>, bool)
{

-> (Box<Scheduler>, Box<GreenTask>, bool) {
let msg = if effort == DontTryTooHard {
self.message_queue.casual_pop()
} else {
@@ -432,7 +432,7 @@ impl Scheduler {
}
}

fn do_work(mut ~self, stask: Box<GreenTask>)
fn do_work(mut self: Box<Scheduler>, stask: Box<GreenTask>)
-> (Box<Scheduler>, Box<GreenTask>, bool) {
rtdebug!("scheduler calling do work");
match self.find_work() {
@@ -517,7 +517,7 @@ impl Scheduler {
// * Task Routing Functions - Make sure tasks send up in the right
// place.

fn process_task(mut ~self,
fn process_task(mut self: Box<Scheduler>,
cur: Box<GreenTask>,
mut next: Box<GreenTask>,
schedule_fn: SchedulingFn)
@@ -610,7 +610,7 @@ impl Scheduler {
// cleanup function f, which takes the scheduler and the
// old task as inputs.

pub fn change_task_context(mut ~self,
pub fn change_task_context(mut self: Box<Scheduler>,
mut current_task: Box<GreenTask>,
mut next_task: Box<GreenTask>,
f: |&mut Scheduler, Box<GreenTask>|)
@@ -693,7 +693,7 @@ impl Scheduler {

// * Context Swapping Helpers - Here be ugliness!

pub fn resume_task_immediately(~self,
pub fn resume_task_immediately(self: Box<Scheduler>,
cur: Box<GreenTask>,
next: Box<GreenTask>)
-> (Box<Scheduler>, Box<GreenTask>) {
@@ -733,7 +733,7 @@ impl Scheduler {
/// This situation is currently prevented, or in other words it is
/// guaranteed that this function will not return before the given closure
/// has returned.
pub fn deschedule_running_task_and_then(mut ~self,
pub fn deschedule_running_task_and_then(mut self: Box<Scheduler>,
cur: Box<GreenTask>,
f: |&mut Scheduler, BlockedTask|) {
// Trickier - we need to get the scheduler task out of self
@@ -743,7 +743,7 @@ impl Scheduler {
self.switch_running_tasks_and_then(cur, stask, f)
}

pub fn switch_running_tasks_and_then(~self,
pub fn switch_running_tasks_and_then(self: Box<Scheduler>,
cur: Box<GreenTask>,
next: Box<GreenTask>,
f: |&mut Scheduler, BlockedTask|) {
@@ -795,7 +795,9 @@ impl Scheduler {

/// Called by a running task to end execution, after which it will
/// be recycled by the scheduler for reuse in a new task.
pub fn terminate_current_task(mut ~self, cur: Box<GreenTask>) -> ! {
pub fn terminate_current_task(mut self: Box<Scheduler>,
cur: Box<GreenTask>)
-> ! {
// Similar to deschedule running task and then, but cannot go through
// the task-blocking path. The task is already dying.
let stask = self.sched_task.take_unwrap();
@@ -807,7 +809,9 @@ impl Scheduler {
fail!("should never return!");
}

pub fn run_task(~self, cur: Box<GreenTask>, next: Box<GreenTask>) {
pub fn run_task(self: Box<Scheduler>,
cur: Box<GreenTask>,
next: Box<GreenTask>) {
let (sched, task) =
self.process_task(cur, next, Scheduler::switch_task);
task.put_with_sched(sched);
@@ -823,7 +827,7 @@ impl Scheduler {
/// to introduce some amount of randomness to the scheduler. Currently the
/// randomness is a result of performing a round of work stealing (which
/// may end up stealing from the current scheduler).
pub fn yield_now(mut ~self, cur: Box<GreenTask>) {
pub fn yield_now(mut self: Box<Scheduler>, cur: Box<GreenTask>) {
// Async handles trigger the scheduler by calling yield_now on the local
// task, which eventually gets us to here. See comments in SchedRunner
// for more info on this.
@@ -842,7 +846,7 @@ impl Scheduler {
}
}

pub fn maybe_yield(mut ~self, cur: Box<GreenTask>) {
pub fn maybe_yield(mut self: Box<Scheduler>, cur: Box<GreenTask>) {
// It's possible for sched tasks to possibly call this function, and it
// just means that they're likely sending on channels (which
// occasionally call this function). Sched tasks follow different paths
@@ -27,7 +27,9 @@ struct SimpleTask {
impl Runtime for SimpleTask {
// Implement the simple tasks of descheduling and rescheduling, but only in
// a simple number of cases.
fn deschedule(mut ~self, times: uint, mut cur_task: Box<Task>,
fn deschedule(mut self: Box<SimpleTask>,
times: uint,
mut cur_task: Box<Task>,
f: |BlockedTask| -> Result<(), BlockedTask>) {
assert!(times == 1);

@@ -54,7 +56,7 @@ impl Runtime for SimpleTask {
}
Local::put(cur_task);
}
fn reawaken(mut ~self, mut to_wake: Box<Task>) {
fn reawaken(mut self: Box<SimpleTask>, mut to_wake: Box<Task>) {
let me = &mut *self as *mut SimpleTask;
to_wake.put_runtime(self);
unsafe {
@@ -69,9 +71,9 @@ impl Runtime for SimpleTask {
// purpose. A "simple task" is just that, a very simple task that can't
// really do a whole lot. The only purpose of the task is to get us off our
// feet and running.
fn yield_now(~self, _cur_task: Box<Task>) { fail!() }
fn maybe_yield(~self, _cur_task: Box<Task>) { fail!() }
fn spawn_sibling(~self,
fn yield_now(self: Box<SimpleTask>, _cur_task: Box<Task>) { fail!() }
fn maybe_yield(self: Box<SimpleTask>, _cur_task: Box<Task>) { fail!() }
fn spawn_sibling(self: Box<SimpleTask>,
_cur_task: Box<Task>,
_opts: TaskOpts,
_f: proc():Send) {
@@ -80,7 +82,7 @@ impl Runtime for SimpleTask {
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
fn stack_bounds(&self) -> (uint, uint) { fail!() }
fn can_block(&self) -> bool { true }
fn wrap(~self) -> Box<Any> { fail!() }
fn wrap(self: Box<SimpleTask>) -> Box<Any> { fail!() }
}

pub fn task() -> Box<Task> {
@@ -265,7 +265,7 @@ impl GreenTask {

// Runtime glue functions and helpers

pub fn put_with_sched(mut ~self, sched: Box<Scheduler>) {
pub fn put_with_sched(mut self: Box<GreenTask>, sched: Box<Scheduler>) {
assert!(self.sched.is_none());
self.sched = Some(sched);
self.put();
@@ -276,18 +276,18 @@ impl GreenTask {
self.task = Some(task);
}

pub fn swap(mut ~self) -> Box<Task> {
pub fn swap(mut self: Box<GreenTask>) -> Box<Task> {
let mut task = self.task.take_unwrap();
task.put_runtime(self);
return task;
}

pub fn put(~self) {
pub fn put(self: Box<GreenTask>) {
assert!(self.sched.is_some());
Local::put(self.swap());
}

fn terminate(mut ~self) -> ! {
fn terminate(mut self: Box<GreenTask>) -> ! {
let sched = self.sched.take_unwrap();
sched.terminate_current_task(self)
}
@@ -311,7 +311,7 @@ impl GreenTask {
// *not* a cheap operation to clone a handle. Until the day comes that we
// need to optimize this, a lock should do just fine (it's completely
// uncontended except for when the task is rescheduled).
fn reawaken_remotely(mut ~self) {
fn reawaken_remotely(mut self: Box<GreenTask>) {
unsafe {
let mtx = &mut self.nasty_deschedule_lock as *mut NativeMutex;
let handle = self.handle.get_mut_ref() as *mut SchedHandle;
@@ -322,19 +322,21 @@ impl GreenTask {
}

impl Runtime for GreenTask {
fn yield_now(mut ~self, cur_task: Box<Task>) {
fn yield_now(mut self: Box<GreenTask>, cur_task: Box<Task>) {
self.put_task(cur_task);
let sched = self.sched.take_unwrap();
sched.yield_now(self);
}

fn maybe_yield(mut ~self, cur_task: Box<Task>) {
fn maybe_yield(mut self: Box<GreenTask>, cur_task: Box<Task>) {
self.put_task(cur_task);
let sched = self.sched.take_unwrap();
sched.maybe_yield(self);
}

fn deschedule(mut ~self, times: uint, cur_task: Box<Task>,
fn deschedule(mut self: Box<GreenTask>,
times: uint,
cur_task: Box<Task>,
f: |BlockedTask| -> Result<(), BlockedTask>) {
self.put_task(cur_task);
let mut sched = self.sched.take_unwrap();
@@ -383,7 +385,7 @@ impl Runtime for GreenTask {
}
}

fn reawaken(mut ~self, to_wake: Box<Task>) {
fn reawaken(mut self: Box<GreenTask>, to_wake: Box<Task>) {
self.put_task(to_wake);
assert!(self.sched.is_none());

@@ -434,7 +436,7 @@ impl Runtime for GreenTask {
}
}

fn spawn_sibling(mut ~self,
fn spawn_sibling(mut self: Box<GreenTask>,
cur_task: Box<Task>,
opts: TaskOpts,
f: proc():Send) {
@@ -471,7 +473,7 @@ impl Runtime for GreenTask {

fn can_block(&self) -> bool { false }

fn wrap(~self) -> Box<Any> { self as Box<Any> }
fn wrap(self: Box<GreenTask>) -> Box<Any> { self as Box<Any> }
}

#[cfg(test)]
@@ -484,7 +484,8 @@ impl TcpListener {
}

impl rtio::RtioTcpListener for TcpListener {
fn listen(~self) -> IoResult<Box<rtio::RtioTcpAcceptor + Send>> {
fn listen(self: Box<TcpListener>)
-> IoResult<Box<rtio::RtioTcpAcceptor + Send>> {
self.native_listen(128).map(|a| {
box a as Box<rtio::RtioTcpAcceptor + Send>
})
@@ -229,7 +229,8 @@ impl UnixListener {
}

impl rtio::RtioUnixListener for UnixListener {
fn listen(~self) -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
fn listen(self: Box<UnixListener>)
-> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
self.native_listen(128).map(|a| {
box a as Box<rtio::RtioUnixAcceptor + Send>
})
@@ -588,7 +588,8 @@ impl Drop for UnixListener {
}

impl rtio::RtioUnixListener for UnixListener {
fn listen(~self) -> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
fn listen(self: Box<UnixListener>)
-> IoResult<Box<rtio::RtioUnixAcceptor + Send>> {
self.native_listen().map(|a| {
box a as Box<rtio::RtioUnixAcceptor + Send>
})
@@ -131,21 +131,21 @@ struct Ops {
}

impl rt::Runtime for Ops {
fn yield_now(~self, mut cur_task: Box<Task>) {
fn yield_now(self: Box<Ops>, mut cur_task: Box<Task>) {
// put the task back in TLS and then invoke the OS thread yield
cur_task.put_runtime(self);
Local::put(cur_task);
Thread::yield_now();
}

fn maybe_yield(~self, mut cur_task: Box<Task>) {
fn maybe_yield(self: Box<Ops>, mut cur_task: Box<Task>) {
// just put the task back in TLS, on OS threads we never need to
// opportunistically yield b/c the OS will do that for us (preemption)
cur_task.put_runtime(self);
Local::put(cur_task);
}

fn wrap(~self) -> Box<Any> {
fn wrap(self: Box<Ops>) -> Box<Any> {
self as Box<Any>
}

@@ -192,7 +192,9 @@ impl rt::Runtime for Ops {
// `awoken` field which indicates whether we were actually woken up via some
// invocation of `reawaken`. This flag is only ever accessed inside the
// lock, so there's no need to make it atomic.
fn deschedule(mut ~self, times: uint, mut cur_task: Box<Task>,
fn deschedule(mut self: Box<Ops>,
times: uint,
mut cur_task: Box<Task>,
f: |BlockedTask| -> Result<(), BlockedTask>) {
let me = &mut *self as *mut Ops;
cur_task.put_runtime(self);
@@ -250,7 +252,7 @@ impl rt::Runtime for Ops {

// See the comments on `deschedule` for why the task is forgotten here, and
// why it's valid to do so.
fn reawaken(mut ~self, mut to_wake: Box<Task>) {
fn reawaken(mut self: Box<Ops>, mut to_wake: Box<Task>) {
unsafe {
let me = &mut *self as *mut Ops;
to_wake.put_runtime(self);
@@ -261,7 +263,7 @@ impl rt::Runtime for Ops {
}
}

fn spawn_sibling(~self,
fn spawn_sibling(self: Box<Ops>,
mut cur_task: Box<Task>,
opts: TaskOpts,
f: proc():Send) {

1 comment on commit 07f3f13

@alexcrichton

This comment has been minimized.

Copy link

commented on 07f3f13 Jul 23, 2014

r+

Please sign in to comment.
You can’t perform that action at this time.