about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-04 16:23:41 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-04 16:23:41 -0700
commit3c94b5044c2e589292def83e9cce187407c9328a (patch)
tree06e85206de2f41223f4cea47ead08e2198c67a2f /src/libstd/rt
parent5865a7597b060e81a6540b5d205b4a7d45a9b328 (diff)
parent3d14470be4194656e2f71120f232f9349e896711 (diff)
Merge remote-tracking branch 'remotes/origin/master' into str-remove-null
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/args.rs2
-rw-r--r--src/libstd/rt/borrowck.rs2
-rw-r--r--src/libstd/rt/io/net/ip.rs40
-rw-r--r--src/libstd/rt/io/net/tcp.rs38
-rw-r--r--src/libstd/rt/io/net/udp.rs20
-rw-r--r--src/libstd/rt/mod.rs4
-rw-r--r--src/libstd/rt/rtio.rs16
-rw-r--r--src/libstd/rt/sched.rs4
-rw-r--r--src/libstd/rt/select.rs14
-rw-r--r--src/libstd/rt/task.rs49
-rw-r--r--src/libstd/rt/test.rs18
-rw-r--r--src/libstd/rt/tube.rs2
-rw-r--r--src/libstd/rt/uv/mod.rs4
-rw-r--r--src/libstd/rt/uv/net.rs126
-rw-r--r--src/libstd/rt/uv/uvio.rs62
15 files changed, 195 insertions, 206 deletions
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index e701cb64fb6..6f26e3bd9ef 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -112,7 +112,7 @@ mod imp {
     // Copied from `os`.
     unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
         let mut args = ~[];
-        foreach i in range(0u, argc as uint) {
+        for i in range(0u, argc as uint) {
             args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i as int)));
         }
         args
diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs
index 3a51fd032c0..c18d0287bc8 100644
--- a/src/libstd/rt/borrowck.rs
+++ b/src/libstd/rt/borrowck.rs
@@ -84,7 +84,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
         Some(borrow_list) => { // recording borrows
             let mut msg = ~"borrowed";
             let mut sep = " at ";
-            foreach entry in borrow_list.rev_iter() {
+            for entry in borrow_list.rev_iter() {
                 if entry.box == box {
                     msg.push_str(sep);
                     let filename = str::raw::from_c_str(entry.file);
diff --git a/src/libstd/rt/io/net/ip.rs b/src/libstd/rt/io/net/ip.rs
index 2b572574b60..815ec9b5c61 100644
--- a/src/libstd/rt/io/net/ip.rs
+++ b/src/libstd/rt/io/net/ip.rs
@@ -15,19 +15,19 @@ type Port = u16;
 
 #[deriving(Eq, TotalEq)]
 pub enum IpAddr {
-    Ipv4(u8, u8, u8, u8, Port),
-    Ipv6(u16, u16, u16, u16, u16, u16, u16, u16, Port)
+    Ipv4Addr(u8, u8, u8, u8),
+    Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
 }
 
 impl ToStr for IpAddr {
     fn to_str(&self) -> ~str {
         match *self {
-            Ipv4(a, b, c, d, p) =>
-                fmt!("%u.%u.%u.%u:%u",
-                    a as uint, b as uint, c as uint, d as uint, p as uint),
+            Ipv4Addr(a, b, c, d) =>
+                fmt!("%u.%u.%u.%u",
+                    a as uint, b as uint, c as uint, d as uint),
 
             // Ipv4 Compatible address
-            Ipv6(0, 0, 0, 0, 0, 0, g, h, p) => {
+            Ipv6Addr(0, 0, 0, 0, 0, 0, g, h) => {
                 let a = fmt!("%04x", g as uint);
                 let b = FromStrRadix::from_str_radix(a.slice(2, 4), 16).unwrap();
                 let a = FromStrRadix::from_str_radix(a.slice(0, 2), 16).unwrap();
@@ -35,11 +35,11 @@ impl ToStr for IpAddr {
                 let d = FromStrRadix::from_str_radix(c.slice(2, 4), 16).unwrap();
                 let c = FromStrRadix::from_str_radix(c.slice(0, 2), 16).unwrap();
 
-                fmt!("[::%u.%u.%u.%u]:%u", a, b, c, d, p as uint)
+                fmt!("::%u.%u.%u.%u", a, b, c, d)
             }
 
             // Ipv4-Mapped address
-            Ipv6(0, 0, 0, 0, 0, 1, g, h, p) => {
+            Ipv6Addr(0, 0, 0, 0, 0, 1, g, h) => {
                 let a = fmt!("%04x", g as uint);
                 let b = FromStrRadix::from_str_radix(a.slice(2, 4), 16).unwrap();
                 let a = FromStrRadix::from_str_radix(a.slice(0, 2), 16).unwrap();
@@ -47,13 +47,29 @@ impl ToStr for IpAddr {
                 let d = FromStrRadix::from_str_radix(c.slice(2, 4), 16).unwrap();
                 let c = FromStrRadix::from_str_radix(c.slice(0, 2), 16).unwrap();
 
-                fmt!("[::FFFF:%u.%u.%u.%u]:%u", a, b, c, d, p as uint)
+                fmt!("::FFFF:%u.%u.%u.%u", a, b, c, d)
             }
 
-            Ipv6(a, b, c, d, e, f, g, h, p) =>
-                fmt!("[%x:%x:%x:%x:%x:%x:%x:%x]:%u",
+            Ipv6Addr(a, b, c, d, e, f, g, h) =>
+                fmt!("%x:%x:%x:%x:%x:%x:%x:%x",
                     a as uint, b as uint, c as uint, d as uint,
-                    e as uint, f as uint, g as uint, h as uint, p as uint)
+                    e as uint, f as uint, g as uint, h as uint)
+        }
+    }
+}
+
+#[deriving(Eq, TotalEq)]
+pub struct SocketAddr {
+    ip: IpAddr,
+    port: Port,
+}
+
+
+impl ToStr for SocketAddr {
+    fn to_str(&self) -> ~str {
+        match self.ip {
+            Ipv4Addr(*) => fmt!("%s:%u", self.ip.to_str(), self.port as uint),
+            Ipv6Addr(*) => fmt!("[%s]:%u", self.ip.to_str(), self.port as uint),
         }
     }
 }
diff --git a/src/libstd/rt/io/net/tcp.rs b/src/libstd/rt/io/net/tcp.rs
index 764ef283eb8..27222542e08 100644
--- a/src/libstd/rt/io/net/tcp.rs
+++ b/src/libstd/rt/io/net/tcp.rs
@@ -10,7 +10,7 @@
 
 use option::{Option, Some, None};
 use result::{Ok, Err};
-use rt::io::net::ip::IpAddr;
+use rt::io::net::ip::SocketAddr;
 use rt::io::{Reader, Writer, Listener};
 use rt::io::{io_error, read_error, EndOfFile};
 use rt::rtio::{IoFactory, IoFactoryObject,
@@ -26,7 +26,7 @@ impl TcpStream {
         TcpStream(s)
     }
 
-    pub fn connect(addr: IpAddr) -> Option<TcpStream> {
+    pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
         let stream = unsafe {
             rtdebug!("borrowing io to connect");
             let io = Local::unsafe_borrow::<IoFactoryObject>();
@@ -44,7 +44,7 @@ impl TcpStream {
         }
     }
 
-    pub fn peer_name(&mut self) -> Option<IpAddr> {
+    pub fn peer_name(&mut self) -> Option<SocketAddr> {
         match (**self).peer_name() {
             Ok(pn) => Some(pn),
             Err(ioerr) => {
@@ -55,7 +55,7 @@ impl TcpStream {
         }
     }
 
-    pub fn socket_name(&mut self) -> Option<IpAddr> {
+    pub fn socket_name(&mut self) -> Option<SocketAddr> {
         match (**self).socket_name() {
             Ok(sn) => Some(sn),
             Err(ioerr) => {
@@ -100,7 +100,7 @@ impl Writer for TcpStream {
 pub struct TcpListener(~RtioTcpListenerObject);
 
 impl TcpListener {
-    pub fn bind(addr: IpAddr) -> Option<TcpListener> {
+    pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
         let listener = unsafe {
             let io = Local::unsafe_borrow::<IoFactoryObject>();
             (*io).tcp_bind(addr)
@@ -114,7 +114,7 @@ impl TcpListener {
         }
     }
 
-    pub fn socket_name(&mut self) -> Option<IpAddr> {
+    pub fn socket_name(&mut self) -> Option<SocketAddr> {
         match (**self).socket_name() {
             Ok(sn) => Some(sn),
             Err(ioerr) => {
@@ -145,7 +145,7 @@ mod test {
     use super::*;
     use cell::Cell;
     use rt::test::*;
-    use rt::io::net::ip::Ipv4;
+    use rt::io::net::ip::{Ipv4Addr, SocketAddr};
     use rt::io::*;
     use prelude::*;
 
@@ -157,7 +157,7 @@ mod test {
                 assert!(e.kind == PermissionDenied);
                 called = true;
             }).inside {
-                let addr = Ipv4(0, 0, 0, 0, 1);
+                let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
                 let listener = TcpListener::bind(addr);
                 assert!(listener.is_none());
             }
@@ -173,7 +173,7 @@ mod test {
                 assert!(e.kind == ConnectionRefused);
                 called = true;
             }).inside {
-                let addr = Ipv4(0, 0, 0, 0, 1);
+                let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
                 let stream = TcpStream::connect(addr);
                 assert!(stream.is_none());
             }
@@ -421,7 +421,7 @@ mod test {
 
             do spawntask {
                 let mut listener = TcpListener::bind(addr);
-                foreach i in range(0, MAX) {
+                for i in range(0, MAX) {
                     let stream = Cell::new(listener.accept());
                     rtdebug!("accepted");
                     // Start another task to handle the connection
@@ -437,7 +437,7 @@ mod test {
 
             connect(0, addr);
 
-            fn connect(i: int, addr: IpAddr) {
+            fn connect(i: int, addr: SocketAddr) {
                 if i == MAX { return }
 
                 do spawntask {
@@ -460,7 +460,7 @@ mod test {
 
             do spawntask {
                 let mut listener = TcpListener::bind(addr);
-                foreach i in range(0, MAX) {
+                for i in range(0, MAX) {
                     let stream = Cell::new(listener.accept());
                     rtdebug!("accepted");
                     // Start another task to handle the connection
@@ -476,7 +476,7 @@ mod test {
 
             connect(0, addr);
 
-            fn connect(i: int, addr: IpAddr) {
+            fn connect(i: int, addr: SocketAddr) {
                 if i == MAX { return }
 
                 do spawntask {
@@ -499,7 +499,7 @@ mod test {
 
             do spawntask {
                 let mut listener = TcpListener::bind(addr);
-                foreach _ in range(0, MAX) {
+                for _ in range(0, MAX) {
                     let stream = Cell::new(listener.accept());
                     rtdebug!("accepted");
                     // Start another task to handle the connection
@@ -515,7 +515,7 @@ mod test {
 
             connect(0, addr);
 
-            fn connect(i: int, addr: IpAddr) {
+            fn connect(i: int, addr: SocketAddr) {
                 if i == MAX { return }
 
                 do spawntask_later {
@@ -537,7 +537,7 @@ mod test {
 
             do spawntask {
                 let mut listener = TcpListener::bind(addr);
-                foreach _ in range(0, MAX) {
+                for _ in range(0, MAX) {
                     let stream = Cell::new(listener.accept());
                     rtdebug!("accepted");
                     // Start another task to handle the connection
@@ -553,7 +553,7 @@ mod test {
 
             connect(0, addr);
 
-            fn connect(i: int, addr: IpAddr) {
+            fn connect(i: int, addr: SocketAddr) {
                 if i == MAX { return }
 
                 do spawntask_later {
@@ -569,7 +569,7 @@ mod test {
     }
 
     #[cfg(test)]
-    fn socket_name(addr: IpAddr) {
+    fn socket_name(addr: SocketAddr) {
         do run_in_newsched_task {
             do spawntask {
                 let listener = TcpListener::bind(addr);
@@ -588,7 +588,7 @@ mod test {
     }
 
     #[cfg(test)]
-    fn peer_name(addr: IpAddr) {
+    fn peer_name(addr: SocketAddr) {
         do run_in_newsched_task {
             do spawntask {
                 let mut listener = TcpListener::bind(addr);
diff --git a/src/libstd/rt/io/net/udp.rs b/src/libstd/rt/io/net/udp.rs
index c04abfa899b..644abcbe145 100644
--- a/src/libstd/rt/io/net/udp.rs
+++ b/src/libstd/rt/io/net/udp.rs
@@ -10,7 +10,7 @@
 
 use option::{Option, Some, None};
 use result::{Ok, Err};
-use rt::io::net::ip::IpAddr;
+use rt::io::net::ip::SocketAddr;
 use rt::io::{Reader, Writer};
 use rt::io::{io_error, read_error, EndOfFile};
 use rt::rtio::{RtioSocket, RtioUdpSocketObject, RtioUdpSocket, IoFactory, IoFactoryObject};
@@ -19,7 +19,7 @@ use rt::local::Local;
 pub struct UdpSocket(~RtioUdpSocketObject);
 
 impl UdpSocket {
-    pub fn bind(addr: IpAddr) -> Option<UdpSocket> {
+    pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
         let socket = unsafe { (*Local::unsafe_borrow::<IoFactoryObject>()).udp_bind(addr) };
         match socket {
             Ok(s) => Some(UdpSocket(s)),
@@ -30,7 +30,7 @@ impl UdpSocket {
         }
     }
 
-    pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, IpAddr)> {
+    pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, SocketAddr)> {
         match (**self).recvfrom(buf) {
             Ok((nread, src)) => Some((nread, src)),
             Err(ioerr) => {
@@ -43,18 +43,18 @@ impl UdpSocket {
         }
     }
 
-    pub fn sendto(&mut self, buf: &[u8], dst: IpAddr) {
+    pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) {
         match (**self).sendto(buf, dst) {
             Ok(_) => (),
             Err(ioerr) => io_error::cond.raise(ioerr),
         }
     }
 
-    pub fn connect(self, other: IpAddr) -> UdpStream {
+    pub fn connect(self, other: SocketAddr) -> UdpStream {
         UdpStream { socket: self, connectedTo: other }
     }
 
-    pub fn socket_name(&mut self) -> Option<IpAddr> {
+    pub fn socket_name(&mut self) -> Option<SocketAddr> {
         match (***self).socket_name() {
             Ok(sn) => Some(sn),
             Err(ioerr) => {
@@ -68,7 +68,7 @@ impl UdpSocket {
 
 pub struct UdpStream {
     socket: UdpSocket,
-    connectedTo: IpAddr
+    connectedTo: SocketAddr
 }
 
 impl UdpStream {
@@ -106,7 +106,7 @@ impl Writer for UdpStream {
 mod test {
     use super::*;
     use rt::test::*;
-    use rt::io::net::ip::Ipv4;
+    use rt::io::net::ip::{Ipv4Addr, SocketAddr};
     use rt::io::*;
     use option::{Some, None};
 
@@ -118,7 +118,7 @@ mod test {
                 assert!(e.kind == PermissionDenied);
                 called = true;
             }).inside {
-                let addr = Ipv4(0, 0, 0, 0, 1);
+                let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
                 let socket = UdpSocket::bind(addr);
                 assert!(socket.is_none());
             }
@@ -265,7 +265,7 @@ mod test {
     }
 
     #[cfg(test)]
-    fn socket_name(addr: IpAddr) {
+    fn socket_name(addr: SocketAddr) {
         do run_in_newsched_task {
             do spawntask {
                 let server = UdpSocket::bind(addr);
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index f0f4b646103..4cfe0efacfe 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -303,7 +303,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
     let on_exit: ~fn(bool) = |exit_success| {
 
         let mut handles = handles.take();
-        foreach handle in handles.mut_iter() {
+        for handle in handles.mut_iter() {
             handle.send(Shutdown);
         }
 
@@ -379,7 +379,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
     rtdebug!("waiting for threads");
 
     // Wait for schedulers
-    foreach thread in threads.consume_iter() {
+    for thread in threads.consume_iter() {
         thread.join();
     }
 
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index d293d46e012..a7c794fb5f1 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -12,7 +12,7 @@ use option::*;
 use result::*;
 
 use rt::io::IoError;
-use super::io::net::ip::IpAddr;
+use super::io::net::ip::{IpAddr, SocketAddr};
 use rt::uv::uvio;
 
 // XXX: ~object doesn't work currently so these are some placeholder
@@ -44,9 +44,9 @@ pub trait RemoteCallback {
 }
 
 pub trait IoFactory {
-    fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError>;
-    fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError>;
-    fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError>;
+    fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStreamObject, IoError>;
+    fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListenerObject, IoError>;
+    fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocketObject, IoError>;
     fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError>;
 }
 
@@ -59,7 +59,7 @@ pub trait RtioTcpListener : RtioSocket {
 pub trait RtioTcpStream : RtioSocket {
     fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
     fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
-    fn peer_name(&mut self) -> Result<IpAddr, IoError>;
+    fn peer_name(&mut self) -> Result<SocketAddr, IoError>;
     fn control_congestion(&mut self) -> Result<(), IoError>;
     fn nodelay(&mut self) -> Result<(), IoError>;
     fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError>;
@@ -67,12 +67,12 @@ pub trait RtioTcpStream : RtioSocket {
 }
 
 pub trait RtioSocket {
-    fn socket_name(&mut self) -> Result<IpAddr, IoError>;
+    fn socket_name(&mut self) -> Result<SocketAddr, IoError>;
 }
 
 pub trait RtioUdpSocket : RtioSocket {
-    fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, IpAddr), IoError>;
-    fn sendto(&mut self, buf: &[u8], dst: IpAddr) -> Result<(), IoError>;
+    fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError>;
+    fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError>;
 
     fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
     fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index dfe003253c2..18cfeade157 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -761,7 +761,7 @@ mod test {
         let mut task_run_count = 0;
         let task_run_count_ptr: *mut uint = &mut task_run_count;
         do run_in_newsched_task || {
-            foreach _ in range(0u, total) {
+            for _ in range(0u, total) {
                 do spawntask || {
                     unsafe { *task_run_count_ptr = *task_run_count_ptr + 1};
                 }
@@ -960,7 +960,7 @@ mod test {
     #[test]
     fn test_stress_schedule_task_states() {
         let n = stress_factor() * 120;
-        foreach _ in range(0, n as int) {
+        for _ in range(0, n as int) {
             test_schedule_home_states();
         }
     }
diff --git a/src/libstd/rt/select.rs b/src/libstd/rt/select.rs
index a5adb25b526..006b777b71b 100644
--- a/src/libstd/rt/select.rs
+++ b/src/libstd/rt/select.rs
@@ -37,7 +37,7 @@ pub fn select<A: Select>(ports: &mut [A]) -> uint {
         fail!("can't select on an empty list");
     }
 
-    foreach (index, port) in ports.mut_iter().enumerate() {
+    for (index, port) in ports.mut_iter().enumerate() {
         if port.optimistic_check() {
             return index;
         }
@@ -53,7 +53,7 @@ pub fn select<A: Select>(ports: &mut [A]) -> uint {
     do sched.deschedule_running_task_and_then |sched, task| {
         let task_handles = task.make_selectable(ports.len());
 
-        foreach (index, (port, task_handle)) in
+        for (index, (port, task_handle)) in
                 ports.mut_iter().zip(task_handles.consume_iter()).enumerate() {
             // If one of the ports has data by now, it will wake the handle.
             if port.block_on(sched, task_handle) {
@@ -66,7 +66,7 @@ pub fn select<A: Select>(ports: &mut [A]) -> uint {
     // Task resumes. Now unblock ourselves from all the ports we blocked on.
     // If the success index wasn't reset, 'take' will just take all of them.
     // Iterate in reverse so the 'earliest' index that's ready gets returned.
-    foreach (index, port) in ports.mut_slice(0, ready_index).mut_rev_iter().enumerate() {
+    for (index, port) in ports.mut_slice(0, ready_index).mut_rev_iter().enumerate() {
         if port.unblock_from() {
             ready_index = index;
         }
@@ -128,7 +128,7 @@ mod test {
         let (ports, chans) = unzip(from_fn(num_ports, |_| oneshot::<()>()));
         let mut dead_chans = ~[];
         let mut ports = ports;
-        foreach (i, chan) in chans.consume_iter().enumerate() {
+        for (i, chan) in chans.consume_iter().enumerate() {
             if send_on_chans.contains(&i) {
                 chan.send(());
             } else {
@@ -145,7 +145,7 @@ mod test {
         let (ports, chans) = unzip(from_fn(num_ports, |_| stream::<()>()));
         let mut dead_chans = ~[];
         let mut ports = ports;
-        foreach (i, chan) in chans.consume_iter().enumerate() {
+        for (i, chan) in chans.consume_iter().enumerate() {
             if send_on_chans.contains(&i) {
                 chan.send(());
             } else {
@@ -192,7 +192,7 @@ mod test {
             let mut ports = ports;
             let mut port = Some(port);
             let order = [5u,0,4,3,2,6,9,8,7,1];
-            foreach &index in order.iter() {
+            for &index in order.iter() {
                 // put the port in the vector at any index
                 util::swap(port.get_mut_ref(), &mut ports[index]);
                 assert!(select(ports) == index);
@@ -272,7 +272,7 @@ mod test {
                     let send_on_chans = send_on_chans.clone();
                     do task::spawn {
                         let mut ports = ~[];
-                        foreach i in range(0u, NUM_CHANS) {
+                        for i in range(0u, NUM_CHANS) {
                             let (p,c) = oneshot();
                             ports.push(p);
                             if send_on_chans.contains(&i) {
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index b242ee13fa6..abafe1cf209 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -27,6 +27,7 @@ use super::local_heap::LocalHeap;
 use rt::sched::{Scheduler, SchedHandle};
 use rt::stack::{StackSegment, StackPool};
 use rt::context::Context;
+use unstable::finally::Finally;
 use task::spawn::Taskgroup;
 use cell::Cell;
 
@@ -211,40 +212,34 @@ impl Task {
 
     pub fn run(&mut self, f: &fn()) {
         rtdebug!("run called on task: %u", borrow::to_uint(self));
-        self.unwinder.try(f);
-        // FIXME(#7544): We pass the taskgroup into death so that it can be
-        // dropped while the unkillable counter is set. This should not be
-        // necessary except for an extraneous clone() in task/spawn.rs that
-        // causes a killhandle to get dropped, which mustn't receive a kill
-        // signal since we're outside of the unwinder's try() scope.
-        // { let _ = self.taskgroup.take(); }
-        self.death.collect_failure(!self.unwinder.unwinding, self.taskgroup.take());
-        self.destroy();
-    }
 
-    /// must be called manually before finalization to clean up
-    /// thread-local resources. Some of the routines here expect
-    /// Task to be available recursively so this must be
-    /// called unsafely, without removing Task from
-    /// thread-local-storage.
-    fn destroy(&mut self) {
+        // The only try/catch block in the world. Attempt to run the task's
+        // client-specified code and catch any failures.
+        do self.unwinder.try {
 
-        rtdebug!("DESTROYING TASK: %u", borrow::to_uint(self));
+            // Run the task main function, then do some cleanup.
+            do f.finally {
 
-        do Local::borrow::<Task, ()> |task| {
-            assert!(borrow::ref_eq(task, self));
-        }
+                // Destroy task-local storage. This may run user dtors.
+                match self.storage {
+                    LocalStorage(ptr, Some(ref dtor)) => {
+                        (*dtor)(ptr)
+                    }
+                    _ => ()
+                }
 
-        match self.storage {
-            LocalStorage(ptr, Some(ref dtor)) => {
-                (*dtor)(ptr)
+                // Destroy remaining boxes. Also may run user dtors.
+                unsafe { cleanup::annihilate(); }
             }
-            _ => ()
         }
 
-        // Destroy remaining boxes
-        unsafe { cleanup::annihilate(); }
-
+        // FIXME(#7544): We pass the taskgroup into death so that it can be
+        // dropped while the unkillable counter is set. This should not be
+        // necessary except for an extraneous clone() in task/spawn.rs that
+        // causes a killhandle to get dropped, which mustn't receive a kill
+        // signal since we're outside of the unwinder's try() scope.
+        // { let _ = self.taskgroup.take(); }
+        self.death.collect_failure(!self.unwinder.unwinding, self.taskgroup.take());
         self.destroyed = true;
     }
 
diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs
index 66ae085b1a0..2427da01a0c 100644
--- a/src/libstd/rt/test.rs
+++ b/src/libstd/rt/test.rs
@@ -16,7 +16,7 @@ use clone::Clone;
 use container::Container;
 use iterator::{Iterator, range};
 use vec::{OwnedVector, MutableVector};
-use super::io::net::ip::{IpAddr, Ipv4, Ipv6};
+use super::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
 use rt::sched::Scheduler;
 use unstable::run_in_bare_thread;
 use rt::thread::Thread;
@@ -169,7 +169,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
         let mut handles = ~[];
         let mut scheds = ~[];
 
-        foreach _ in range(0u, nthreads) {
+        for _ in range(0u, nthreads) {
             let loop_ = ~UvEventLoop::new();
             let mut sched = ~Scheduler::new(loop_,
                                             work_queue.clone(),
@@ -184,7 +184,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
         let on_exit: ~fn(bool) = |exit_status| {
             let mut handles = handles.take();
             // Tell schedulers to exit
-            foreach handle in handles.mut_iter() {
+            for handle in handles.mut_iter() {
                 handle.send(Shutdown);
             }
 
@@ -223,7 +223,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
         }
 
         // Wait for schedulers
-        foreach thread in threads.consume_iter() {
+        for thread in threads.consume_iter() {
             thread.join();
         }
     }
@@ -306,13 +306,13 @@ pub fn next_test_port() -> u16 {
 }
 
 /// Get a unique IPv4 localhost:port pair starting at 9600
-pub fn next_test_ip4() -> IpAddr {
-    Ipv4(127, 0, 0, 1, next_test_port())
+pub fn next_test_ip4() -> SocketAddr {
+    SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: next_test_port() }
 }
 
 /// Get a unique IPv6 localhost:port pair starting at 9600
-pub fn next_test_ip6() -> IpAddr {
-    Ipv6(0, 0, 0, 0, 0, 0, 0, 1, next_test_port())
+pub fn next_test_ip6() -> SocketAddr {
+    SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1), port: next_test_port() }
 }
 
 /*
@@ -346,7 +346,7 @@ fn base_port() -> uint {
 
     let mut final_base = base;
 
-    foreach &(dir, base) in bases.iter() {
+    for &(dir, base) in bases.iter() {
         if path.contains(dir) {
             final_base = base;
             break;
diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs
index c014d0abda2..247893f75de 100644
--- a/src/libstd/rt/tube.rs
+++ b/src/libstd/rt/tube.rs
@@ -166,7 +166,7 @@ mod test {
                 sched.enqueue_blocked_task(task);
             }
 
-            foreach i in range(0, MAX) {
+            for i in range(0, MAX) {
                 let j = tube.recv();
                 assert!(j == i);
             }
diff --git a/src/libstd/rt/uv/mod.rs b/src/libstd/rt/uv/mod.rs
index fa5c497a877..ae5e7dd27b5 100644
--- a/src/libstd/rt/uv/mod.rs
+++ b/src/libstd/rt/uv/mod.rs
@@ -47,7 +47,7 @@ use libc::{c_void, c_int, size_t, malloc, free};
 use cast::transmute;
 use ptr::null;
 use unstable::finally::Finally;
-use rt::io::net::ip::IpAddr;
+use rt::io::net::ip::SocketAddr;
 
 use rt::io::IoError;
 
@@ -128,7 +128,7 @@ pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
 pub type FsCallback = ~fn(FsRequest, Option<UvError>);
 pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
 pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
-pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, IpAddr, uint, Option<UvError>);
+pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option<UvError>);
 pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
 
 
diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs
index 773adb3848a..67d3bbef8a9 100644
--- a/src/libstd/rt/uv/net.rs
+++ b/src/libstd/rt/uv/net.rs
@@ -15,56 +15,45 @@ use rt::uv::uvll::*;
 use rt::uv::{AllocCallback, ConnectionCallback, ReadCallback, UdpReceiveCallback, UdpSendCallback};
 use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle, NullCallback,
              status_to_maybe_uv_error};
-use rt::io::net::ip::{IpAddr, Ipv4, Ipv6};
+use rt::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
 use rt::uv::last_uv_error;
 use vec;
 use str;
 use from_str::{FromStr};
 use num;
 
-pub enum UvIpAddr {
-    UvIpv4(*sockaddr_in),
-    UvIpv6(*sockaddr_in6),
+pub enum UvSocketAddr {
+    UvIpv4SocketAddr(*sockaddr_in),
+    UvIpv6SocketAddr(*sockaddr_in6),
 }
 
-fn sockaddr_to_UvIpAddr(addr: *uvll::sockaddr) -> UvIpAddr {
+fn sockaddr_to_UvSocketAddr(addr: *uvll::sockaddr) -> UvSocketAddr {
     unsafe {
         assert!((is_ip4_addr(addr) || is_ip6_addr(addr)));
         assert!(!(is_ip4_addr(addr) && is_ip6_addr(addr)));
         match addr {
-            _ if is_ip4_addr(addr) => UvIpv4(addr as *uvll::sockaddr_in),
-            _ if is_ip6_addr(addr) => UvIpv6(addr as *uvll::sockaddr_in6),
+            _ if is_ip4_addr(addr) => UvIpv4SocketAddr(addr as *uvll::sockaddr_in),
+            _ if is_ip6_addr(addr) => UvIpv6SocketAddr(addr as *uvll::sockaddr_in6),
             _ => fail!(),
         }
     }
 }
 
-fn ip_as_uv_ip<T>(addr: IpAddr, f: &fn(UvIpAddr) -> T) -> T {
-    let malloc = match addr {
-        Ipv4(*) => malloc_ip4_addr,
-        Ipv6(*) => malloc_ip6_addr,
+fn socket_addr_as_uv_socket_addr<T>(addr: SocketAddr, f: &fn(UvSocketAddr) -> T) -> T {
+    let malloc = match addr.ip {
+        Ipv4Addr(*) => malloc_ip4_addr,
+        Ipv6Addr(*) => malloc_ip6_addr,
     };
-    let wrap = match addr {
-        Ipv4(*) => UvIpv4,
-        Ipv6(*) => UvIpv6,
+    let wrap = match addr.ip {
+        Ipv4Addr(*) => UvIpv4SocketAddr,
+        Ipv6Addr(*) => UvIpv6SocketAddr,
     };
-    let ip_str = match addr {
-        Ipv4(x1, x2, x3, x4, _) =>
-            fmt!("%u.%u.%u.%u", x1 as uint, x2 as uint, x3 as uint, x4 as uint),
-        Ipv6(x1, x2, x3, x4, x5, x6, x7, x8, _) =>
-            fmt!("%x:%x:%x:%x:%x:%x:%x:%x",
-                  x1 as uint, x2 as uint, x3 as uint, x4 as uint,
-                  x5 as uint, x6 as uint, x7 as uint, x8 as uint),
-    };
-    let port = match addr {
-        Ipv4(_, _, _, _, p) | Ipv6(_, _, _, _, _, _, _, _, p) => p as int
-    };
-    let free = match addr {
-        Ipv4(*) => free_ip4_addr,
-        Ipv6(*) => free_ip6_addr,
+    let free = match addr.ip {
+        Ipv4Addr(*) => free_ip4_addr,
+        Ipv6Addr(*) => free_ip6_addr,
     };
 
-    let addr = unsafe { malloc(ip_str, port) };
+    let addr = unsafe { malloc(addr.ip.to_str(), addr.port as int) };
     do (|| {
         f(wrap(addr))
     }).finally {
@@ -72,39 +61,43 @@ fn ip_as_uv_ip<T>(addr: IpAddr, f: &fn(UvIpAddr) -> T) -> T {
     }
 }
 
-fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
+fn uv_socket_addr_as_socket_addr<T>(addr: UvSocketAddr, f: &fn(SocketAddr) -> T) -> T {
     let ip_size = match addr {
-        UvIpv4(*) => 4/*groups of*/ * 3/*digits separated by*/ + 3/*periods*/,
-        UvIpv6(*) => 8/*groups of*/ * 4/*hex digits separated by*/ + 7 /*colons*/,
+        UvIpv4SocketAddr(*) => 4/*groups of*/ * 3/*digits separated by*/ + 3/*periods*/,
+        UvIpv6SocketAddr(*) => 8/*groups of*/ * 4/*hex digits separated by*/ + 7 /*colons*/,
     };
     let ip_name = {
         let buf = vec::from_elem(ip_size + 1 /*null terminated*/, 0u8);
         unsafe {
+            let buf_ptr = vec::raw::to_ptr(buf);
             match addr {
-                UvIpv4(addr) => uvll::ip4_name(addr, vec::raw::to_ptr(buf), ip_size as size_t),
-                UvIpv6(addr) => uvll::ip6_name(addr, vec::raw::to_ptr(buf), ip_size as size_t),
+                UvIpv4SocketAddr(addr) => uvll::ip4_name(addr, buf_ptr, ip_size as size_t),
+                UvIpv6SocketAddr(addr) => uvll::ip6_name(addr, buf_ptr, ip_size as size_t),
             }
         };
         buf
     };
     let ip_port = unsafe {
         let port = match addr {
-            UvIpv4(addr) => uvll::ip4_port(addr),
-            UvIpv6(addr) => uvll::ip6_port(addr),
+            UvIpv4SocketAddr(addr) => uvll::ip4_port(addr),
+            UvIpv6SocketAddr(addr) => uvll::ip6_port(addr),
         };
         port as u16
     };
     let ip_str = str::from_bytes_slice(ip_name).trim_right_chars(&'\x00');
     let ip = match addr {
-        UvIpv4(*) => {
+        UvIpv4SocketAddr(*) => {
             let ip: ~[u8] =
                 ip_str.split_iter('.')
                       .transform(|s: &str| -> u8 { FromStr::from_str(s).unwrap() })
                       .collect();
             assert_eq!(ip.len(), 4);
-            Ipv4(ip[0], ip[1], ip[2], ip[3], ip_port)
+            SocketAddr {
+                ip: Ipv4Addr(ip[0], ip[1], ip[2], ip[3]),
+                port: ip_port
+            }
         },
-        UvIpv6(*) => {
+        UvIpv6SocketAddr(*) => {
             let ip: ~[u16] = {
                 let expand_shorthand_and_convert = |s: &str| -> ~[~[u16]] {
                     let convert_each_segment = |s: &str| -> ~[u16] {
@@ -154,7 +147,10 @@ fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
                 }
             };
             assert_eq!(ip.len(), 8);
-            Ipv6(ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip_port)
+            SocketAddr {
+                ip: Ipv6Addr(ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]),
+                port: ip_port
+            }
         },
     };
 
@@ -162,9 +158,9 @@ fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
     f(ip)
 }
 
-pub fn uv_ip_to_ip(addr: UvIpAddr) -> IpAddr {
+pub fn uv_socket_addr_to_socket_addr(addr: UvSocketAddr) -> SocketAddr {
     use util;
-    uv_ip_as_ip(addr, util::id)
+    uv_socket_addr_as_socket_addr(addr, util::id)
 }
 
 #[cfg(test)]
@@ -172,7 +168,7 @@ pub fn uv_ip_to_ip(addr: UvIpAddr) -> IpAddr {
 fn test_ip4_conversion() {
     use rt;
     let ip4 = rt::test::next_test_ip4();
-    assert_eq!(ip4, ip_as_uv_ip(ip4, uv_ip_to_ip));
+    assert_eq!(ip4, socket_addr_as_uv_socket_addr(ip4, uv_socket_addr_to_socket_addr));
 }
 
 #[cfg(test)]
@@ -180,7 +176,7 @@ fn test_ip4_conversion() {
 fn test_ip6_conversion() {
     use rt;
     let ip6 = rt::test::next_test_ip6();
-    assert_eq!(ip6, ip_as_uv_ip(ip6, uv_ip_to_ip));
+    assert_eq!(ip6, socket_addr_as_uv_socket_addr(ip6, uv_socket_addr_to_socket_addr));
 }
 
 // uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t
@@ -293,12 +289,12 @@ impl TcpWatcher {
         }
     }
 
-    pub fn bind(&mut self, address: IpAddr) -> Result<(), UvError> {
-        do ip_as_uv_ip(address) |addr| {
+    pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
+        do socket_addr_as_uv_socket_addr(address) |addr| {
             let result = unsafe {
                 match addr {
-                    UvIpv4(addr) => uvll::tcp_bind(self.native_handle(), addr),
-                    UvIpv6(addr) => uvll::tcp_bind6(self.native_handle(), addr),
+                    UvIpv4SocketAddr(addr) => uvll::tcp_bind(self.native_handle(), addr),
+                    UvIpv6SocketAddr(addr) => uvll::tcp_bind6(self.native_handle(), addr),
                 }
             };
             match result {
@@ -308,18 +304,18 @@ impl TcpWatcher {
         }
     }
 
-    pub fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) {
+    pub fn connect(&mut self, address: SocketAddr, cb: ConnectionCallback) {
         unsafe {
             assert!(self.get_watcher_data().connect_cb.is_none());
             self.get_watcher_data().connect_cb = Some(cb);
 
             let connect_handle = ConnectRequest::new().native_handle();
             rtdebug!("connect_t: %x", connect_handle as uint);
-            do ip_as_uv_ip(address) |addr| {
+            do socket_addr_as_uv_socket_addr(address) |addr| {
                 let result = match addr {
-                    UvIpv4(addr) => uvll::tcp_connect(connect_handle,
+                    UvIpv4SocketAddr(addr) => uvll::tcp_connect(connect_handle,
                                                       self.native_handle(), addr, connect_cb),
-                    UvIpv6(addr) => uvll::tcp_connect6(connect_handle,
+                    UvIpv6SocketAddr(addr) => uvll::tcp_connect6(connect_handle,
                                                        self.native_handle(), addr, connect_cb),
                 };
                 assert_eq!(0, result);
@@ -388,12 +384,12 @@ impl UdpWatcher {
         }
     }
 
-    pub fn bind(&mut self, address: IpAddr) -> Result<(), UvError> {
-        do ip_as_uv_ip(address) |addr| {
+    pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
+        do socket_addr_as_uv_socket_addr(address) |addr| {
             let result = unsafe {
                 match addr {
-                    UvIpv4(addr) => uvll::udp_bind(self.native_handle(), addr, 0u32),
-                    UvIpv6(addr) => uvll::udp_bind6(self.native_handle(), addr, 0u32),
+                    UvIpv4SocketAddr(addr) => uvll::udp_bind(self.native_handle(), addr, 0u32),
+                    UvIpv6SocketAddr(addr) => uvll::udp_bind6(self.native_handle(), addr, 0u32),
                 }
             };
             match result {
@@ -432,7 +428,7 @@ impl UdpWatcher {
             let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
             let cb = udp_watcher.get_watcher_data().udp_recv_cb.get_ref();
             let status = status_to_maybe_uv_error(udp_watcher, nread as c_int);
-            let addr = uv_ip_to_ip(sockaddr_to_UvIpAddr(addr));
+            let addr = uv_socket_addr_to_socket_addr(sockaddr_to_UvSocketAddr(addr));
             (*cb)(udp_watcher, nread as int, buf, addr, flags as uint, status);
         }
     }
@@ -441,7 +437,7 @@ impl UdpWatcher {
         unsafe { uvll::udp_recv_stop(self.native_handle()); }
     }
 
-    pub fn send(&mut self, buf: Buf, address: IpAddr, cb: UdpSendCallback) {
+    pub fn send(&mut self, buf: Buf, address: SocketAddr, cb: UdpSendCallback) {
         {
             let data = self.get_watcher_data();
             assert!(data.udp_send_cb.is_none());
@@ -449,12 +445,12 @@ impl UdpWatcher {
         }
 
         let req = UdpSendRequest::new();
-        do ip_as_uv_ip(address) |addr| {
+        do socket_addr_as_uv_socket_addr(address) |addr| {
             let result = unsafe {
                 match addr {
-                    UvIpv4(addr) => uvll::udp_send(req.native_handle(),
+                    UvIpv4SocketAddr(addr) => uvll::udp_send(req.native_handle(),
                                                    self.native_handle(), [buf], addr, send_cb),
-                    UvIpv6(addr) => uvll::udp_send6(req.native_handle(),
+                    UvIpv6SocketAddr(addr) => uvll::udp_send6(req.native_handle(),
                                                     self.native_handle(), [buf], addr, send_cb),
                 }
             };
@@ -701,7 +697,7 @@ mod test {
                     if status.is_none() {
                         rtdebug!("got %d bytes", nread);
                         let buf = buf.unwrap();
-                        foreach byte in buf.slice(0, nread as uint).iter() {
+                        for byte in buf.slice(0, nread as uint).iter() {
                             assert!(*byte == count as u8);
                             rtdebug!("%u", *byte as uint);
                             count += 1;
@@ -777,7 +773,7 @@ mod test {
                         rtdebug!("got %d bytes", nread);
                         let buf = buf.unwrap();
                         let r = buf.slice(0, nread as uint);
-                        foreach byte in r.iter() {
+                        for byte in r.iter() {
                             assert!(*byte == count as u8);
                             rtdebug!("%u", *byte as uint);
                             count += 1;
@@ -848,7 +844,7 @@ mod test {
                 rtdebug!("got %d bytes", nread);
 
                 let buf = buf.unwrap();
-                foreach &byte in buf.slice(0, nread as uint).iter() {
+                for &byte in buf.slice(0, nread as uint).iter() {
                     assert!(byte == count as u8);
                     rtdebug!("%u", byte as uint);
                     count += 1;
@@ -908,7 +904,7 @@ mod test {
                 rtdebug!("got %d bytes", nread);
 
                 let buf = buf.unwrap();
-                foreach &byte in buf.slice(0, nread as uint).iter() {
+                for &byte in buf.slice(0, nread as uint).iter() {
                     assert!(byte == count as u8);
                     rtdebug!("%u", byte as uint);
                     count += 1;
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index 071a90f4a83..01d01de54ef 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -19,7 +19,7 @@ use option::*;
 use ptr;
 use result::*;
 use rt::io::IoError;
-use rt::io::net::ip::{IpAddr, Ipv4, Ipv6};
+use rt::io::net::ip::{SocketAddr, IpAddr};
 use rt::io::{standard_error, OtherIoError};
 use rt::local::Local;
 use rt::rtio::*;
@@ -27,7 +27,7 @@ use rt::sched::Scheduler;
 use rt::tube::Tube;
 use rt::uv::*;
 use rt::uv::idle::IdleWatcher;
-use rt::uv::net::{UvIpv4, UvIpv6};
+use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
 use unstable::sync::Exclusive;
 
 #[cfg(test)] use container::Container;
@@ -44,7 +44,7 @@ enum SocketNameKind {
 }
 
 fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
-                                                 handle: U) -> Result<IpAddr, IoError> {
+                                                 handle: U) -> Result<SocketAddr, IoError> {
 
     let getsockname = match sk {
         TcpPeer => uvll::rust_uv_tcp_getpeername,
@@ -67,9 +67,9 @@ fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
 
     let addr = unsafe {
         if uvll::is_ip6_addr(r_addr as *uvll::sockaddr) {
-            net::uv_ip_to_ip(UvIpv6(r_addr as *uvll::sockaddr_in6))
+            net::uv_socket_addr_to_socket_addr(UvIpv6SocketAddr(r_addr as *uvll::sockaddr_in6))
         } else {
-            net::uv_ip_to_ip(UvIpv4(r_addr as *uvll::sockaddr_in))
+            net::uv_socket_addr_to_socket_addr(UvIpv4SocketAddr(r_addr as *uvll::sockaddr_in))
         }
     };
 
@@ -244,7 +244,7 @@ impl IoFactory for UvIoFactory {
     // Connect to an address and return a new stream
     // NB: This blocks the task waiting on the connection.
     // It would probably be better to return a future
-    fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError> {
+    fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStreamObject, IoError> {
         // Create a cell in the task to hold the result. We will fill
         // the cell before resuming the task.
         let result_cell = Cell::new_empty();
@@ -291,7 +291,7 @@ impl IoFactory for UvIoFactory {
         return result_cell.take();
     }
 
-    fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError> {
+    fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListenerObject, IoError> {
         let mut watcher = TcpWatcher::new(self.uv_loop());
         match watcher.bind(addr) {
             Ok(_) => Ok(~UvTcpListener::new(watcher)),
@@ -309,7 +309,7 @@ impl IoFactory for UvIoFactory {
         }
     }
 
-    fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError> {
+    fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocketObject, IoError> {
         let mut watcher = UdpWatcher::new(self.uv_loop());
         match watcher.bind(addr) {
             Ok(_) => Ok(~UvUdpSocket(watcher)),
@@ -365,7 +365,7 @@ impl Drop for UvTcpListener {
 }
 
 impl RtioSocket for UvTcpListener {
-    fn socket_name(&mut self) -> Result<IpAddr, IoError> {
+    fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
         socket_name(Tcp, self.watcher)
     }
 }
@@ -445,7 +445,7 @@ impl Drop for UvTcpStream {
 }
 
 impl RtioSocket for UvTcpStream {
-    fn socket_name(&mut self) -> Result<IpAddr, IoError> {
+    fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
         socket_name(Tcp, **self)
     }
 }
@@ -519,7 +519,7 @@ impl RtioTcpStream for UvTcpStream {
         return result_cell.take();
     }
 
-    fn peer_name(&mut self) -> Result<IpAddr, IoError> {
+    fn peer_name(&mut self) -> Result<SocketAddr, IoError> {
         socket_name(TcpPeer, **self)
     }
 
@@ -586,15 +586,15 @@ impl Drop for UvUdpSocket {
 }
 
 impl RtioSocket for UvUdpSocket {
-    fn socket_name(&mut self) -> Result<IpAddr, IoError> {
+    fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
         socket_name(Udp, **self)
     }
 }
 
 impl RtioUdpSocket for UvUdpSocket {
-    fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, IpAddr), IoError> {
+    fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError> {
         let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<(uint, IpAddr), IoError>> = &result_cell;
+        let result_cell_ptr: *Cell<Result<(uint, SocketAddr), IoError>> = &result_cell;
 
         let scheduler = Local::take::<Scheduler>();
         let buf_ptr: *&mut [u8] = &buf;
@@ -626,7 +626,7 @@ impl RtioUdpSocket for UvUdpSocket {
         return result_cell.take();
     }
 
-    fn sendto(&mut self, buf: &[u8], dst: IpAddr) -> Result<(), IoError> {
+    fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> {
         let result_cell = Cell::new_empty();
         let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
         let scheduler = Local::take::<Scheduler>();
@@ -653,17 +653,8 @@ impl RtioUdpSocket for UvUdpSocket {
     }
 
     fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
-        let ip_str = match multi {
-            Ipv4(x1, x2, x3, x4, _) =>
-                fmt!("%u.%u.%u.%u", x1 as uint, x2 as uint, x3 as uint, x4 as uint),
-            Ipv6(x1, x2, x3, x4, x5, x6, x7, x8, _) =>
-                fmt!("%x:%x:%x:%x:%x:%x:%x:%x",
-                      x1 as uint, x2 as uint, x3 as uint, x4 as uint,
-                      x5 as uint, x6 as uint, x7 as uint, x8 as uint),
-        };
-
         let r = unsafe {
-            do ip_str.to_c_str().with_ref |m_addr| {
+            do multi.to_str().to_c_str().with_ref |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_JOIN_GROUP)
             }
@@ -676,17 +667,8 @@ impl RtioUdpSocket for UvUdpSocket {
     }
 
     fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
-        let ip_str = match multi {
-            Ipv4(x1, x2, x3, x4, _) =>
-                fmt!("%u.%u.%u.%u", x1 as uint, x2 as uint, x3 as uint, x4 as uint),
-            Ipv6(x1, x2, x3, x4, x5, x6, x7, x8, _) =>
-                fmt!("%x:%x:%x:%x:%x:%x:%x:%x",
-                      x1 as uint, x2 as uint, x3 as uint, x4 as uint,
-                      x5 as uint, x6 as uint, x7 as uint, x8 as uint),
-        };
-
         let r = unsafe {
-            do ip_str.to_c_str().with_ref |m_addr| {
+            do multi.to_str().to_c_str().with_ref |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_LEAVE_GROUP)
             }
@@ -843,7 +825,7 @@ fn test_simple_tcp_server_and_client() {
                 let mut buf = [0, .. 2048];
                 let nread = stream.read(buf).unwrap();
                 assert_eq!(nread, 8);
-                foreach i in range(0u, nread) {
+                for i in range(0u, nread) {
                     rtdebug!("%u", buf[i] as uint);
                     assert_eq!(buf[i], i as u8);
                 }
@@ -873,7 +855,7 @@ fn test_simple_udp_server_and_client() {
                 let mut buf = [0, .. 2048];
                 let (nread,src) = server_socket.recvfrom(buf).unwrap();
                 assert_eq!(nread, 8);
-                foreach i in range(0u, nread) {
+                for i in range(0u, nread) {
                     rtdebug!("%u", buf[i] as uint);
                     assert_eq!(buf[i], i as u8);
                 }
@@ -908,7 +890,7 @@ fn test_read_and_block() {
 
             while current < expected {
                 let nread = stream.read(buf).unwrap();
-                foreach i in range(0u, nread) {
+                for i in range(0u, nread) {
                     let val = buf[i] as uint;
                     assert_eq!(val, current % 8);
                     current += 1;
@@ -973,7 +955,7 @@ fn test_read_read_read() {
                     let nread = stream.read(buf).unwrap();
                     rtdebug!("read %u bytes", nread as uint);
                     total_bytes_read += nread;
-                    foreach i in range(0u, nread) {
+                    for i in range(0u, nread) {
                         assert_eq!(buf[i], 1);
                     }
                 }
@@ -1065,7 +1047,7 @@ fn test_udp_many_read() {
                     let (nread, src) = res.unwrap();
                     assert_eq!(src, server_out_addr);
                     total_bytes_recv += nread;
-                    foreach i in range(0u, nread) {
+                    for i in range(0u, nread) {
                         assert_eq!(buf[i], 1);
                     }
                 }