about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-08-17 17:13:11 -0700
committerEric Holk <eholk@mozilla.com>2011-08-17 17:16:23 -0700
commit3ab21e5ee082ff1cc535f23d1be5f153cb80a985 (patch)
tree660373019d8287feb0bebfda5001b37c0152886d
parentf023f8209040554839dc7bc91d9f796a5ff7f247 (diff)
downloadrust-3ab21e5ee082ff1cc535f23d1be5f153cb80a985.tar.gz
rust-3ab21e5ee082ff1cc535f23d1be5f153cb80a985.zip
Better type inference for chans and ports.
-rw-r--r--src/lib/comm.rs31
-rw-r--r--src/lib/task.rs21
-rw-r--r--src/test/compiletest/procsrv.rs42
-rw-r--r--src/test/run-fail/port-type.rs2
-rw-r--r--src/test/run-pass/send-type-inference.rs12
-rw-r--r--src/test/stdtest/comm.rs16
6 files changed, 65 insertions, 59 deletions
diff --git a/src/lib/comm.rs b/src/lib/comm.rs
index 17c766cda1a..615686a49e0 100644
--- a/src/lib/comm.rs
+++ b/src/lib/comm.rs
@@ -6,7 +6,7 @@ import task::task_id;
 
 export _chan;
 export _port;
-
+export chan_handle;
 export mk_port;
 export send;
 export recv;
@@ -32,10 +32,9 @@ native "rust-intrinsic" mod rusti {
 
 type port_id = int;
 
-type chan<~T> = {
-    task : task_id,
-    port : port_id
-};
+type chan_handle<~T> = { task : task_id, port : port_id};
+
+tag chan<~T> { chan_t(chan_handle<T>); }
 type _chan<~T> = chan<T>;
 
 resource port_ptr(po: *rustrt::rust_port) {
@@ -43,11 +42,11 @@ resource port_ptr(po: *rustrt::rust_port) {
     rustrt::del_port(po);
 }
 
-type port<~T> = @port_ptr;
+tag port<~T> { port_t(@port_ptr); }
 
 obj port_obj<~T>(raw_port : port<T>) {
-    fn mk_chan() -> _chan<T> {
-        chan::<T>(raw_port)
+    fn mk_chan() -> chan<T> {
+        chan(raw_port)
     }
 
     fn recv() -> T {
@@ -60,21 +59,21 @@ fn mk_port<~T>() -> _port<T> {
     ret port_obj::<T>(port::<T>());
 }
 
-fn send<~T>(ch : chan<T>, data : -T) {
+fn send<~T>(ch : &chan<T>, data : -T) {
     rustrt::chan_id_send(ch.task, ch.port, data);
 }
 
 fn port<~T>() -> port<T> {
-    @port_ptr(rustrt::new_port(sys::size_of::<T>()))
+    port_t(@port_ptr(rustrt::new_port(sys::size_of::<T>())))
 }
 
-fn recv<~T>(p : port<T>) -> T {
-    ret rusti::recv(**p)
+fn recv<~T>(p : &port<T>) -> T {
+    ret rusti::recv(***p)
 }
 
-fn chan<~T>(p : port<T>) -> chan<T> {
-    {
+fn chan<~T>(p : &port<T>) -> chan<T> {
+    chan_t({
         task: task::get_task_id(),
-        port: rustrt::get_port_id(**p)
-    }
+        port: rustrt::get_port_id(***p)
+    })
 }
diff --git a/src/lib/task.rs b/src/lib/task.rs
index 4ad160df603..9ed8e8ecdf0 100644
--- a/src/lib/task.rs
+++ b/src/lib/task.rs
@@ -1,6 +1,5 @@
 import cast = unsafe::reinterpret_cast;
 import comm;
-import comm::_chan;
 import option::some;
 import option::none;
 import option = option::t;
@@ -33,7 +32,7 @@ native "rust" mod rustrt {
 type rust_task = {
     id : task,
     mutable notify_enabled : u8,
-    mutable notify_chan : _chan<task_notification>,
+    mutable notify_chan : comm::chan_handle<task_notification>,
     ctx : task_context,
     stack_ptr : *u8
 };
@@ -76,14 +75,12 @@ tag task_notification {
 fn join(task_port : (task_id, comm::port<task_notification>))
     -> task_result {
     let (id, port) = task_port;
-    while true {
-        alt comm::recv::<task_notification>(port) {
-          exit(_id, res) {
-            if _id == id { ret res }
-          }
-        }
+    alt comm::recv::<task_notification>(port) {
+      exit(_id, res) {
+        if _id == id { ret res }
+        else { fail #fmt("join received id %d, expected %d", _id, id) }
+      }
     }
-    fail
 }
 
 fn join_id(t : task_id) -> task_result {
@@ -108,7 +105,7 @@ fn spawn(thunk : -fn() -> ()) -> task {
     spawn_inner(thunk, none)
 }
 
-fn spawn_notify(thunk : -fn() -> (), notify : _chan<task_notification>)
+fn spawn_notify(thunk : -fn() -> (), notify : comm::chan<task_notification>)
     -> task {
     spawn_inner(thunk, some(notify))
 }
@@ -121,7 +118,7 @@ fn spawn_joinable(thunk : -fn()) -> (task_id, comm::port<task_notification>) {
 
 // FIXME: make this a fn~ once those are supported.
 fn spawn_inner(thunk : -fn() -> (),
-               notify : option<_chan<task_notification>>)
+               notify : option<comm::chan<task_notification>>)
     -> task_id {
     let id = rustrt::new_task();
 
@@ -144,7 +141,7 @@ fn spawn_inner(thunk : -fn() -> (),
     alt notify {
       some(c) {
         (**task_ptr).notify_enabled = 1u8;
-        (**task_ptr).notify_chan = c;
+        (**task_ptr).notify_chan = *c;
       }
       none {}
     };
diff --git a/src/test/compiletest/procsrv.rs b/src/test/compiletest/procsrv.rs
index 67628fc82dc..68df59be521 100644
--- a/src/test/compiletest/procsrv.rs
+++ b/src/test/compiletest/procsrv.rs
@@ -14,10 +14,10 @@ import std::os;
 import std::run;
 import std::io;
 import std::str;
-import std::comm::_chan;
-import std::comm::mk_port;
-import std::comm::_port;
+import std::comm::chan;
+import std::comm::port;
 import std::comm::send;
+import std::comm::recv;
 
 export handle;
 export mk;
@@ -26,27 +26,27 @@ export run;
 export close;
 export reqchan;
 
-type reqchan = _chan<request>;
+type reqchan = chan<request>;
 
 type handle = {task: option::t<task_id>, chan: reqchan};
 
 tag request {
-    exec([u8], [u8], [[u8]], _chan<response>);
+    exec([u8], [u8], [[u8]], chan<response>);
     stop;
 }
 
 type response = {pid: int, infd: int, outfd: int, errfd: int};
 
 fn mk() -> handle {
-    let setupport = mk_port();
-    let task = task::_spawn(bind fn(setupchan: _chan<_chan<request>>) {
-        let reqport = mk_port();
-        let reqchan = reqport.mk_chan();
+    let setupport = port();
+    let task = task::spawn(bind fn(setupchan: chan<chan<request>>) {
+        let reqport = port();
+        let reqchan = chan(reqport);
         send(setupchan, reqchan);
         worker(reqport);
-    } (setupport.mk_chan()));
+    } (chan(setupport)));
     ret {task: option::some(task),
-         chan: setupport.recv()
+         chan: recv(setupport)
         };
 }
 
@@ -60,13 +60,13 @@ fn close(handle: &handle) {
 fn run(handle: &handle, lib_path: &str,
        prog: &str, args: &[str], input: &option::t<str>) ->
 {status: int, out: str, err: str} {
-    let p = mk_port::<response>();
-    let ch = p.mk_chan();
+    let p = port();
+    let ch = chan(p);
     send(handle.chan, exec(str::bytes(lib_path),
                            str::bytes(prog),
                            clone_ivecstr(args),
                            ch));
-    let resp = p.recv();
+    let resp = recv(p);
 
     writeclose(resp.infd, input);
     let output = readclose(resp.outfd);
@@ -99,18 +99,12 @@ fn readclose(fd: int) -> str {
     ret buf;
 }
 
-fn worker(p: _port<request>) {
+fn worker(p: port<request>) {
 
     // FIXME (787): If we declare this inside of the while loop and then
     // break out of it before it's ever initialized (i.e. we don't run
-    // any tests), then the cleanups will puke, so we're initializing it
-    // here with defaults.
-    let execparms = {
-        lib_path: "",
-        prog: "",
-        args: ~[],
-        respchan: p.mk_chan()
-    };
+    // any tests), then the cleanups will puke.
+    let execparms;
 
     while true {
         // FIXME: Sending strings across channels seems to still
@@ -124,7 +118,7 @@ fn worker(p: _port<request>) {
             // put the entire alt in another block to make sure the exec
             // message goes out of scope. Seems like the scoping rules for
             // the alt discriminant are wrong.
-            alt p.recv() {
+            alt recv(p) {
               exec(lib_path, prog, args, respchan) {
                 {
                     lib_path: str::unsafe_from_bytes(lib_path),
diff --git a/src/test/run-fail/port-type.rs b/src/test/run-fail/port-type.rs
index a5c077d0f8f..5954ba53065 100644
--- a/src/test/run-fail/port-type.rs
+++ b/src/test/run-fail/port-type.rs
@@ -4,7 +4,7 @@ import std::comm::_chan;
 import std::comm::mk_port;
 import std::comm::send;
 
-fn echo<~T>(c: _chan<T>, oc: _chan<_chan<T>>) {
+fn echo<~T>(c: &_chan<T>, oc: &_chan<_chan<T>>) {
     // Tests that the type argument in port gets
     // visited
     let p = mk_port::<T>();
diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs
index 919c45a55f4..cfc358a9106 100644
--- a/src/test/run-pass/send-type-inference.rs
+++ b/src/test/run-pass/send-type-inference.rs
@@ -1,13 +1,13 @@
 use std;
-import std::comm::_chan;
+import std::comm::chan;
 import std::comm::send;
-import std::comm::mk_port;
+import std::comm::port;
 
 // tests that ctrl's type gets inferred properly
-type command<K, V> = {key: K, val: V};
+type command<~K, ~V> = {key: K, val: V};
 
-fn cache_server<K, V>(c: _chan<_chan<command<K, V>>>) {
-    let ctrl = mk_port::<_chan<command<K, V>>>();
-    send(c, ctrl.mk_chan());
+fn cache_server<~K, ~V>(c: &chan<chan<command<K, V>>>) {
+    let ctrl = port();
+    send(c, chan(ctrl));
 }
 fn main() { }
diff --git a/src/test/stdtest/comm.rs b/src/test/stdtest/comm.rs
index 17c3bc1e929..7d20042e866 100644
--- a/src/test/stdtest/comm.rs
+++ b/src/test/stdtest/comm.rs
@@ -25,3 +25,19 @@ fn send_recv_fn() {
     comm::send(c, 42);
     assert(comm::recv(p) == 42);
 }
+
+#[test]
+fn send_recv_fn_infer() {
+    let p = comm::port();
+    let c = comm::chan(p);
+    comm::send(c, 42);
+    assert(comm::recv(p) == 42);
+}
+
+#[test]
+fn chan_chan() {
+    let p = comm::port(), p2 = comm::port::<int>();
+    let c = comm::chan(p);
+    comm::send(c, comm::chan(p2));
+    let c2 = comm::recv(p);
+}