]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #13704 : edwardw/rust/doc-hidden, r=alexcrichton
authorbors <bors@rust-lang.org>
Thu, 24 Apr 2014 04:46:34 +0000 (21:46 -0700)
committerbors <bors@rust-lang.org>
Thu, 24 Apr 2014 04:46:34 +0000 (21:46 -0700)
Closes #13698

93 files changed:
mk/tests.mk
src/libcollections/bitv.rs
src/libcollections/ringbuf.rs
src/libnative/io/c_win32.rs
src/libnative/io/net.rs
src/libnative/io/timer_win32.rs
src/libnum/bigint.rs
src/librustc/back/archive.rs
src/librustc/back/link.rs
src/librustc/back/rpath.rs
src/librustc/driver/driver.rs
src/librustc/driver/session.rs
src/librustc/front/config.rs
src/librustc/lib.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/filesearch.rs
src/librustc/metadata/loader.rs
src/librustc/middle/borrowck/check_loans.rs
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/lint.rs
src/librustc/middle/privacy.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustuv/net.rs
src/librustuv/timer.rs
src/libstd/io/net/ip.rs
src/libstd/io/net/tcp.rs
src/libstd/iter.rs
src/libstd/num/int_macros.rs
src/libstd/num/uint_macros.rs
src/libstd/option.rs
src/libstd/rc.rs
src/libstd/result.rs
src/libstd/rt/rtio.rs
src/libstd/rt/task.rs
src/libstd/slice.rs
src/libstd/str.rs
src/libstd/task.rs
src/libstd/unstable/finally.rs
src/libsync/lock.rs
src/libsyntax/ext/deriving/clone.rs
src/libsyntax/ext/deriving/cmp/eq.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/cmp/totaleq.rs
src/libsyntax/ext/deriving/cmp/totalord.rs
src/libsyntax/ext/deriving/decodable.rs
src/libsyntax/ext/deriving/default.rs
src/libsyntax/ext/deriving/encodable.rs
src/libsyntax/ext/deriving/generic.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/primitive.rs
src/libsyntax/ext/deriving/rand.rs
src/libsyntax/ext/deriving/show.rs
src/libsyntax/ext/deriving/zero.rs
src/libtest/lib.rs
src/test/bench/msgsend-pipes-shared.rs
src/test/bench/msgsend-pipes.rs
src/test/bench/shootout-pfib.rs
src/test/compile-fail/borrowck-call-is-borrow-issue-12224.rs [new file with mode: 0644]
src/test/compile-fail/macro-crate-unexported-macro.rs
src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs
src/test/compile-fail/phase-syntax-doesnt-resolve.rs
src/test/compile-fail/syntax-extension-fourcc-bad-len.rs
src/test/compile-fail/syntax-extension-fourcc-invalid-endian.rs
src/test/compile-fail/syntax-extension-fourcc-non-ascii-str.rs
src/test/compile-fail/syntax-extension-fourcc-non-literal.rs
src/test/compile-fail/syntax-extension-fourcc-unsupported-literal.rs
src/test/compile-fail/syntax-extension-hexfloat-bad-lits.rs
src/test/compile-fail/syntax-extension-hexfloat-bad-types.rs
src/test/run-fail/fail-task-name-owned.rs
src/test/run-fail/fail-task-name-send-str.rs
src/test/run-fail/fail-task-name-static.rs
src/test/run-pass-fulldeps/issue-13560.rs
src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
src/test/run-pass-fulldeps/macro-crate.rs
src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs
src/test/run-pass-fulldeps/syntax-extension-fourcc.rs
src/test/run-pass-fulldeps/syntax-extension-hexfloat.rs
src/test/run-pass/const-vec-of-fns.rs
src/test/run-pass/issue-2190-1.rs
src/test/run-pass/issue-6157.rs
src/test/run-pass/spawning-with-debug.rs
src/test/run-pass/task-comm-12.rs
src/test/run-pass/task-comm-3.rs
src/test/run-pass/task-comm-9.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/yield.rs
src/test/run-pass/yield1.rs

index b14b5a5152776e838622f31048c4e412a6bbb414..9fc1c7390ccd044eb6f79a5083162e87f713175a 100644 (file)
@@ -526,8 +526,6 @@ endif
 # triples).  The associated message will be printed as a warning
 # during attempts to run those tests.
 
-CTEST_DISABLE_NONSELFHOST_rpass-full = "run-pass-full suite is unavailable when cross-compiling."
-
 define DEF_CTEST_VARS
 
 # All the per-stage build rules you might want to call from the
@@ -573,7 +571,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) :=                                              \
         $$(CTEST_TESTARGS)
 
 CTEST_DEPS_rpass_$(1)-T-$(2)-H-$(3) = $$(RPASS_TESTS)
-CTEST_DEPS_rpass-full_$(1)-T-$(2)-H-$(3) = $$(RPASS_FULL_TESTS) $$(CSREQ$(1)_T_$(2)_H_$(3))
+CTEST_DEPS_rpass-full_$(1)-T-$(2)-H-$(3) = $$(RPASS_FULL_TESTS) $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3))
 CTEST_DEPS_rfail_$(1)-T-$(2)-H-$(3) = $$(RFAIL_TESTS)
 CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS)
 CTEST_DEPS_bench_$(1)-T-$(2)-H-$(3) = $$(BENCH_TESTS)
index 6326f83b497808b2f50d910adc37fcf52b7b9516..13180cdfa5b6c839e6cfdcd9ba8e5d98e5a0160d 100644 (file)
@@ -632,7 +632,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<bool> {
+    fn idx(&mut self, index: uint) -> Option<bool> {
         if index >= self.indexable() {
             None
         } else {
index 19dc2d2ae583b30937a5e4c1c46ecf7a34e54dee..9204a9ca4003dc461e0964b01e3cdff306d4f067 100644 (file)
@@ -272,7 +272,7 @@ impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
     fn indexable(&self) -> uint { self.rindex - self.index }
 
     #[inline]
-    fn idx(&self, j: uint) -> Option<&'a T> {
+    fn idx(&mut self, j: uint) -> Option<&'a T> {
         if j >= self.indexable() {
             None
         } else {
index 8d75a6739146d270b165cadac34b7510aa33ed44..dbbb39b3b7b52fd5363ff30a3430857ba46e349b 100644 (file)
@@ -50,9 +50,9 @@ pub fn WSAStartup(wVersionRequested: libc::WORD,
     pub fn ioctlsocket(s: libc::SOCKET, cmd: libc::c_long,
                        argp: *mut libc::c_ulong) -> libc::c_int;
     pub fn select(nfds: libc::c_int,
-                  readfds: *mut fd_set,
-                  writefds: *mut fd_set,
-                  exceptfds: *mut fd_set,
+                  readfds: *fd_set,
+                  writefds: *fd_set,
+                  exceptfds: *fd_set,
                   timeout: *libc::timeval) -> libc::c_int;
     pub fn getsockopt(sockfd: libc::SOCKET,
                       level: libc::c_int,
index be597761b1a8f8d774ca6ed5774d327bcb4d5e50..93ec23e32ad427da60e894b85eb94b366ae05a6e 100644 (file)
@@ -13,6 +13,7 @@
 use std::io::net::ip;
 use std::io;
 use std::mem;
+use std::os;
 use std::ptr;
 use std::rt::rtio;
 use std::sync::arc::UnsafeArc;
@@ -144,6 +145,21 @@ fn last_error() -> io::IoError {
     super::last_error()
 }
 
+fn ms_to_timeval(ms: u64) -> libc::timeval {
+    libc::timeval {
+        tv_sec: (ms / 1000) as libc::time_t,
+        tv_usec: ((ms % 1000) * 1000) as libc::suseconds_t,
+    }
+}
+
+fn timeout(desc: &'static str) -> io::IoError {
+    io::IoError {
+        kind: io::TimedOut,
+        desc: desc,
+        detail: None,
+    }
+}
+
 #[cfg(windows)] unsafe fn close(sock: sock_t) { let _ = libc::closesocket(sock); }
 #[cfg(unix)]    unsafe fn close(sock: sock_t) { let _ = libc::close(sock); }
 
@@ -271,8 +287,7 @@ pub fn connect(addr: ip::SocketAddr,
     fn connect_timeout(fd: sock_t,
                        addrp: *libc::sockaddr,
                        len: libc::socklen_t,
-                       timeout: u64) -> IoResult<()> {
-        use std::os;
+                       timeout_ms: u64) -> IoResult<()> {
         #[cfg(unix)]    use INPROGRESS = libc::EINPROGRESS;
         #[cfg(windows)] use INPROGRESS = libc::WSAEINPROGRESS;
         #[cfg(unix)]    use WOULDBLOCK = libc::EWOULDBLOCK;
@@ -289,12 +304,8 @@ fn connect_timeout(fd: sock_t,
                   os::errno() as int == WOULDBLOCK as int => {
                 let mut set: c::fd_set = unsafe { mem::init() };
                 c::fd_set(&mut set, fd);
-                match await(fd, &mut set, timeout) {
-                    0 => Err(io::IoError {
-                        kind: io::TimedOut,
-                        desc: "connection timed out",
-                        detail: None,
-                    }),
+                match await(fd, &mut set, timeout_ms) {
+                    0 => Err(timeout("connection timed out")),
                     -1 => Err(last_error()),
                     _ => {
                         let err: libc::c_int = try!(
@@ -338,22 +349,14 @@ fn await(fd: sock_t, set: &mut c::fd_set, timeout: u64) -> libc::c_int {
                 // Recalculate the timeout each iteration (it is generally
                 // undefined what the value of the 'tv' is after select
                 // returns EINTR).
-                let timeout = timeout - (::io::timer::now() - start);
-                let tv = libc::timeval {
-                    tv_sec: (timeout / 1000) as libc::time_t,
-                    tv_usec: ((timeout % 1000) * 1000) as libc::suseconds_t,
-                };
-                c::select(fd + 1, ptr::null(), set as *mut _ as *_,
-                          ptr::null(), &tv)
+                let tv = ms_to_timeval(timeout - (::io::timer::now() - start));
+                c::select(fd + 1, ptr::null(), &*set, ptr::null(), &tv)
             })
         }
         #[cfg(windows)]
         fn await(_fd: sock_t, set: &mut c::fd_set, timeout: u64) -> libc::c_int {
-            let tv = libc::timeval {
-                tv_sec: (timeout / 1000) as libc::time_t,
-                tv_usec: ((timeout % 1000) * 1000) as libc::suseconds_t,
-            };
-            unsafe { c::select(1, ptr::mut_null(), set, ptr::mut_null(), &tv) }
+            let tv = ms_to_timeval(timeout);
+            unsafe { c::select(1, ptr::null(), &*set, ptr::null(), &tv) }
         }
     }
 
@@ -467,7 +470,7 @@ impl Drop for Inner {
 ////////////////////////////////////////////////////////////////////////////////
 
 pub struct TcpListener {
-    inner: UnsafeArc<Inner>,
+    inner: Inner,
 }
 
 impl TcpListener {
@@ -477,7 +480,7 @@ pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
                 let (addr, len) = addr_to_sockaddr(addr);
                 let addrp = &addr as *libc::sockaddr_storage;
                 let inner = Inner { fd: fd };
-                let ret = TcpListener { inner: UnsafeArc::new(inner) };
+                let ret = TcpListener { inner: inner };
                 // On platforms with Berkeley-derived sockets, this allows
                 // to quickly rebind a socket, without needing to wait for
                 // the OS to clean up the previous one.
@@ -498,15 +501,12 @@ pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
         }
     }
 
-    pub fn fd(&self) -> sock_t {
-        // This is just a read-only arc so the unsafety is fine
-        unsafe { (*self.inner.get()).fd }
-    }
+    pub fn fd(&self) -> sock_t { self.inner.fd }
 
     pub fn native_listen(self, backlog: int) -> IoResult<TcpAcceptor> {
         match unsafe { libc::listen(self.fd(), backlog as libc::c_int) } {
             -1 => Err(last_error()),
-            _ => Ok(TcpAcceptor { listener: self })
+            _ => Ok(TcpAcceptor { listener: self, deadline: 0 })
         }
     }
 }
@@ -525,12 +525,16 @@ fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
 
 pub struct TcpAcceptor {
     listener: TcpListener,
+    deadline: u64,
 }
 
 impl TcpAcceptor {
     pub fn fd(&self) -> sock_t { self.listener.fd() }
 
     pub fn native_accept(&mut self) -> IoResult<TcpStream> {
+        if self.deadline != 0 {
+            try!(self.accept_deadline());
+        }
         unsafe {
             let mut storage: libc::sockaddr_storage = mem::init();
             let storagep = &mut storage as *mut libc::sockaddr_storage;
@@ -546,6 +550,25 @@ pub fn native_accept(&mut self) -> IoResult<TcpStream> {
             }
         }
     }
+
+    fn accept_deadline(&mut self) -> IoResult<()> {
+        let mut set: c::fd_set = unsafe { mem::init() };
+        c::fd_set(&mut set, self.fd());
+
+        match retry(|| {
+            // If we're past the deadline, then pass a 0 timeout to select() so
+            // we can poll the status of the socket.
+            let now = ::io::timer::now();
+            let ms = if self.deadline > now {0} else {self.deadline - now};
+            let tv = ms_to_timeval(ms);
+            let n = if cfg!(windows) {1} else {self.fd() as libc::c_int + 1};
+            unsafe { c::select(n, &set, ptr::null(), ptr::null(), &tv) }
+        }) {
+            -1 => Err(last_error()),
+            0 => Err(timeout("accept timed out")),
+            _ => return Ok(()),
+        }
+    }
 }
 
 impl rtio::RtioSocket for TcpAcceptor {
@@ -561,6 +584,12 @@ fn accept(&mut self) -> IoResult<~rtio::RtioTcpStream:Send> {
 
     fn accept_simultaneously(&mut self) -> IoResult<()> { Ok(()) }
     fn dont_accept_simultaneously(&mut self) -> IoResult<()> { Ok(()) }
+    fn set_timeout(&mut self, timeout: Option<u64>) {
+        self.deadline = match timeout {
+            None => 0,
+            Some(t) => ::io::timer::now() + t,
+        };
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index a15898feb92b793612a478c441fbd5f4eb376a68..588ec367d81769e52154faf331a680158b1375f1 100644 (file)
@@ -89,6 +89,17 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>) {
     }
 }
 
+// returns the current time (in milliseconds)
+pub fn now() -> u64 {
+    let mut ticks_per_s = 0;
+    assert_eq!(unsafe { libc::QueryPerformanceFrequency(&mut ticks_per_s) }, 1);
+    let ticks_per_s = if ticks_per_s == 0 {1} else {ticks_per_s};
+    let mut ticks = 0;
+    assert_eq!(unsafe { libc::QueryPerformanceCounter(&mut ticks) }, 1);
+
+    return (ticks as u64 * 1000) / (ticks_per_s as u64);
+}
+
 impl Timer {
     pub fn new() -> IoResult<Timer> {
         timer_helper::boot(helper);
index 46ee996608e4894741e843a03a8b25a0c4d92688..77c94d0150862fbe17a4a4e13bf0f2adee9e014d 100644 (file)
@@ -672,7 +672,7 @@ fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str {
                 s.push_str("0".repeat(l - ss.len()));
                 s.push_str(ss);
             }
-            s.as_slice().trim_left_chars(&'0').to_owned()
+            s.as_slice().trim_left_chars('0').to_owned()
         }
     }
 }
index 27211c4779f8eeae3fbf10fec092b07423b5b1d1..7ecea29db2ead761e7bf836eae1542daec53a2e7 100644 (file)
@@ -184,7 +184,7 @@ fn find_library(&self, name: &str) -> Path {
         let unixlibname = format!("lib{}.a", name);
 
         let mut rustpath = filesearch::rust_path();
-        rustpath.push(self.sess.filesearch().get_target_lib_path());
+        rustpath.push(self.sess.target_filesearch().get_lib_path());
         let search = self.sess.opts.addl_lib_search_paths.borrow();
         for path in search.iter().chain(rustpath.iter()) {
             debug!("looking for {} inside {}", name, path.display());
index 9fd3894d7948e831878505f396eaa662c8478c2d..b7842936af3b0ea22a592881aa13d86d6ff6e89f 100644 (file)
@@ -1088,7 +1088,7 @@ fn link_args(sess: &Session,
     // The default library location, we need this to find the runtime.
     // The location of crates will be determined as needed.
     // FIXME (#9639): This needs to handle non-utf8 paths
-    let lib_path = sess.filesearch().get_target_lib_path();
+    let lib_path = sess.target_filesearch().get_lib_path();
     let stage: ~str = "-L".to_owned() + lib_path.as_str().unwrap();
 
     let mut args = vec!(stage);
index d7d86e077de5be702acf9b9ec612309c2c6f67bd..ce79bea5cee7d459b908bc9b64190060e43448c8 100644 (file)
@@ -40,7 +40,7 @@ pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<~str> {
 
     debug!("preparing the RPATH!");
 
-    let sysroot = sess.filesearch().sysroot;
+    let sysroot = sess.sysroot();
     let output = out_filename;
     let libs = sess.cstore.get_used_crates(cstore::RequireDynamic);
     let libs = libs.move_iter().filter_map(|(_, l)| {
index cf0e7e161c1fc3d89110fbe74134f1cffeb01ef4..95ee250e24c1f080eacbc9879419be5490112ec3 100644 (file)
@@ -284,9 +284,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
     let time_passes = sess.time_passes();
 
     time(time_passes, "external crate/lib resolution", (), |_|
-         creader::read_crates(&sess, krate,
-                              session::sess_os_to_meta_os(sess.targ_cfg.os),
-                              token::get_ident_interner()));
+         creader::read_crates(&sess, krate));
 
     let lang_items = time(time_passes, "language item collection", (), |_|
                           middle::lang_items::collect_language_items(krate, &sess));
@@ -794,7 +792,7 @@ pub fn build_target_config(sopts: &session::Options) -> session::Config {
     }
 }
 
-pub fn host_triple() -> ~str {
+pub fn host_triple() -> &'static str {
     // Get the host triple out of the build environment. This ensures that our
     // idea of the host triple is the same as for the set of libraries we've
     // actually built.  We can't just take LLVM's host triple because they
@@ -803,7 +801,7 @@ pub fn host_triple() -> ~str {
     // Instead of grabbing the host triple (for the current host), we grab (at
     // compile time) the target triple that this rustc is built with and
     // calling that (at runtime) the host triple.
-    (env!("CFG_COMPILER_HOST_TRIPLE")).to_owned()
+    env!("CFG_COMPILER_HOST_TRIPLE")
 }
 
 pub fn build_session_options(matches: &getopts::Matches) -> session::Options {
@@ -895,7 +893,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> session::Options {
     }
 
     let sysroot_opt = matches.opt_str("sysroot").map(|m| Path::new(m));
-    let target = matches.opt_str("target").unwrap_or(host_triple());
+    let target = matches.opt_str("target").unwrap_or(host_triple().to_owned());
     let opt_level = {
         if (debugging_opts & session::NO_OPT) != 0 {
             No
index e23423bcd0b71fa1d7c1d182c7d2936895fd07b4..950e6bd8ee8333621f3437cbff875083ac8a7f1c 100644 (file)
@@ -319,17 +319,25 @@ pub fn no_landing_pads(&self) -> bool {
     pub fn show_span(&self) -> bool {
         self.debugging_opt(SHOW_SPAN)
     }
-    pub fn filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
-        let sysroot = match self.opts.maybe_sysroot {
-            Some(ref sysroot) => sysroot,
+    pub fn sysroot<'a>(&'a self) -> &'a Path {
+        match self.opts.maybe_sysroot {
+            Some (ref sysroot) => sysroot,
             None => self.default_sysroot.as_ref()
                         .expect("missing sysroot and default_sysroot in Session")
-        };
+        }
+    }
+    pub fn target_filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
         filesearch::FileSearch::new(
-            sysroot,
+            self.sysroot(),
             self.opts.target_triple,
             &self.opts.addl_lib_search_paths)
     }
+    pub fn host_filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
+        filesearch::FileSearch::new(
+            self.sysroot(),
+            host_triple(),
+            &self.opts.addl_lib_search_paths)
+    }
 }
 
 /// Some reasonable defaults
@@ -343,7 +351,7 @@ pub fn basic_options() -> Options {
         output_types: Vec::new(),
         addl_lib_search_paths: RefCell::new(HashSet::new()),
         maybe_sysroot: None,
-        target_triple: host_triple(),
+        target_triple: host_triple().to_owned(),
         cfg: Vec::new(),
         test: false,
         parse_only: false,
index b8f20b5e43968fad8fe43cac13dd5df7b89b9afa..888a8f6bd8d856feb69273ed9f0c70e6c3d2773d 100644 (file)
@@ -47,7 +47,7 @@ pub fn strip_items(krate: ast::Crate,
     ctxt.fold_crate(krate)
 }
 
-fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::ViewItem)
+fn filter_view_item<'r>(cx: &mut Context, view_item: &'r ast::ViewItem)
                         -> Option<&'r ast::ViewItem> {
     if view_item_in_cfg(cx, view_item) {
         Some(view_item)
@@ -72,7 +72,7 @@ fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
     }
 }
 
-fn filter_foreign_item(cx: &Context, item: @ast::ForeignItem)
+fn filter_foreign_item(cx: &mut Context, item: @ast::ForeignItem)
                        -> Option<@ast::ForeignItem> {
     if foreign_item_in_cfg(cx, item) {
         Some(item)
@@ -144,7 +144,7 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
     fold::noop_fold_item_underscore(&item, cx)
 }
 
-fn fold_struct(cx: &Context, def: &ast::StructDef) -> @ast::StructDef {
+fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> @ast::StructDef {
     let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
         (cx.in_cfg)(m.node.attrs.as_slice())
     });
@@ -156,7 +156,7 @@ fn fold_struct(cx: &Context, def: &ast::StructDef) -> @ast::StructDef {
     }
 }
 
-fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
+fn retain_stmt(cx: &mut Context, stmt: @ast::Stmt) -> bool {
     match stmt.node {
       ast::StmtDecl(decl, _) => {
         match decl.node {
@@ -189,23 +189,23 @@ fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
     })
 }
 
-fn item_in_cfg(cx: &Context, item: &ast::Item) -> bool {
+fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn foreign_item_in_cfg(cx: &Context, item: &ast::ForeignItem) -> bool {
+fn foreign_item_in_cfg(cx: &mut Context, item: &ast::ForeignItem) -> bool {
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn view_item_in_cfg(cx: &Context, item: &ast::ViewItem) -> bool {
+fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn method_in_cfg(cx: &Context, meth: &ast::Method) -> bool {
+fn method_in_cfg(cx: &mut Context, meth: &ast::Method) -> bool {
     return (cx.in_cfg)(meth.attrs.as_slice());
 }
 
-fn trait_method_in_cfg(cx: &Context, meth: &ast::TraitMethod) -> bool {
+fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
     match *meth {
         ast::Required(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
         ast::Provided(meth) => (cx.in_cfg)(meth.attrs.as_slice())
index 0c9aa60b4a1563de94cf6dc16d766a8cdfb807b2..8ffba905773bb163bc5858ed9bdd8f981ce9f4a3 100644 (file)
@@ -55,7 +55,7 @@
 use std::io;
 use std::os;
 use std::str;
-use std::task;
+use std::task::TaskBuilder;
 use syntax::ast;
 use syntax::diagnostic::Emitter;
 use syntax::diagnostic;
@@ -374,7 +374,7 @@ pub fn monitor(f: proc():Send) {
     #[cfg(not(rtopt))]
     static STACK_SIZE: uint = 20000000; // 20MB
 
-    let mut task_builder = task::task().named("rustc");
+    let mut task_builder = TaskBuilder::new().named("rustc");
 
     // FIXME: Hacks on hacks. If the env is trying to override the stack size
     // then *don't* set it explicitly.
index 0ea6598a99f00afe7456963a18c0900a19a935bb..8f71ac4ebf7ef537127919c50b6a82b136406d32 100644 (file)
@@ -201,6 +201,8 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 pub static tag_exported_macros: uint = 0x8c;
 pub static tag_macro_def: uint = 0x8d;
 
+pub static tag_crate_triple: uint = 0x66;
+
 #[deriving(Clone, Show)]
 pub struct LinkMeta {
     pub crateid: CrateId,
index efbfce1b2bb86c197314d96cc6f3219d2d28be02..916d2a6f07ca28f27517651b37989b95e85ce640 100644 (file)
 
 use back::link;
 use back::svh::Svh;
-use driver::{driver, session};
 use driver::session::Session;
+use driver::{driver, session};
 use metadata::cstore;
 use metadata::cstore::CStore;
 use metadata::decoder;
 use metadata::loader;
-use metadata::loader::Os;
 use metadata::loader::CratePaths;
 
 use std::rc::Rc;
 use syntax::codemap::{Span};
 use syntax::diagnostic::SpanHandler;
 use syntax::ext::base::{CrateLoader, MacroCrate};
-use syntax::parse::token::{IdentInterner, InternedString};
+use syntax::parse::token::InternedString;
 use syntax::parse::token;
 use syntax::crateid::CrateId;
 use syntax::visit;
 
 struct Env<'a> {
     sess: &'a Session,
-    os: loader::Os,
     next_crate_num: ast::CrateNum,
-    intr: Rc<IdentInterner>
 }
 
 // Traverses an AST, reading all the information about use'd crates and extern
 // libraries necessary for later resolving, typechecking, linking, etc.
 pub fn read_crates(sess: &Session,
-                   krate: &ast::Crate,
-                   os: loader::Os,
-                   intr: Rc<IdentInterner>) {
+                   krate: &ast::Crate) {
     let mut e = Env {
         sess: sess,
-        os: os,
         next_crate_num: sess.cstore.next_crate_num(),
-        intr: intr
     };
     visit_crate(&e, krate);
     visit::walk_crate(&mut e, krate, ());
@@ -84,7 +77,6 @@ fn dump_crates(cstore: &CStore) {
 
 fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
     let mut map = HashMap::new();
-
     cstore.iter_crate_data(|cnum, data| {
         let crateid = data.crate_id();
         let key = (crateid.name.clone(), crateid.path.clone());
@@ -129,7 +121,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
     match extract_crate_info(e, i) {
         Some(info) => {
             let (cnum, _, _) = resolve_crate(e, &None, info.ident,
-                                             &info.crate_id, None, true,
+                                             &info.crate_id, None,
                                              i.span);
             e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
         }
@@ -272,13 +264,60 @@ fn existing_match(e: &Env, crate_id: &CrateId,
     return ret;
 }
 
+fn register_crate<'a>(e: &mut Env,
+                  root: &Option<CratePaths>,
+                  ident: &str,
+                  crate_id: &CrateId,
+                  span: Span,
+                  lib: loader::Library)
+                        -> (ast::CrateNum, Rc<cstore::crate_metadata>,
+                            cstore::CrateSource) {
+    // Claim this crate number and cache it
+    let cnum = e.next_crate_num;
+    e.next_crate_num += 1;
+
+    // Stash paths for top-most crate locally if necessary.
+    let crate_paths = if root.is_none() {
+        Some(CratePaths {
+            ident: ident.to_owned(),
+            dylib: lib.dylib.clone(),
+            rlib:  lib.rlib.clone(),
+        })
+    } else {
+        None
+    };
+    // Maintain a reference to the top most crate.
+    let root = if root.is_some() { root } else { &crate_paths };
+
+    let cnum_map = resolve_crate_deps(e, root, lib.metadata.as_slice(), span);
+
+    let loader::Library{ dylib, rlib, metadata } = lib;
+
+    let cmeta = Rc::new( cstore::crate_metadata {
+        name: crate_id.name.to_owned(),
+        data: metadata,
+        cnum_map: cnum_map,
+        cnum: cnum,
+        span: span,
+    });
+
+    let source = cstore::CrateSource {
+        dylib: dylib,
+        rlib: rlib,
+        cnum: cnum,
+    };
+
+    e.sess.cstore.set_crate_data(cnum, cmeta.clone());
+    e.sess.cstore.add_used_crate_source(source.clone());
+    (cnum, cmeta, source)
+}
+
 fn resolve_crate<'a>(e: &mut Env,
-                     root: &Option<CratePaths>,
-                     ident: &str,
-                     crate_id: &CrateId,
-                     hash: Option<&Svh>,
-                     should_link: bool,
-                     span: Span)
+                 root: &Option<CratePaths>,
+                 ident: &str,
+                 crate_id: &CrateId,
+                 hash: Option<&Svh>,
+                 span: Span)
                      -> (ast::CrateNum, Rc<cstore::crate_metadata>,
                          cstore::CrateSource) {
     match existing_match(e, crate_id, hash) {
@@ -291,64 +330,15 @@ fn resolve_crate<'a>(e: &mut Env,
                 crate_id: crate_id,
                 id_hash: id_hash,
                 hash: hash.map(|a| &*a),
-                os: e.os,
-                intr: e.intr.clone(),
+                filesearch: e.sess.target_filesearch(),
+                os: session::sess_os_to_meta_os(e.sess.targ_cfg.os),
+                triple: e.sess.targ_cfg.target_strs.target_triple.as_slice(),
+                root: root,
                 rejected_via_hash: vec!(),
+                rejected_via_triple: vec!(),
             };
-            let loader::Library {
-                dylib, rlib, metadata
-            } = load_ctxt.load_library_crate(root);
-
-            // Stash paths for top-most crate locally if necessary.
-            let crate_paths = if root.is_none() {
-                Some(CratePaths {
-                    ident: load_ctxt.ident.to_owned(),
-                    dylib: dylib.clone(),
-                    rlib:  rlib.clone(),
-                })
-            } else {
-                None
-            };
-            // Maintain a reference to the top most crate.
-            let root = if root.is_some() { root } else { &crate_paths };
-
-            // Now resolve the crates referenced by this crate
-            let cnum_map = if should_link {
-                resolve_crate_deps(e, root, metadata.as_slice(), span)
-            } else {
-                HashMap::new()
-            };
-
-            // Claim this crate number and cache it if we're linking to the
-            // crate, otherwise it's a syntax-only crate and we don't need to
-            // reserve a number
-            let cnum = if should_link {
-                let n = e.next_crate_num;
-                e.next_crate_num += 1;
-                n
-            } else {
-                -1
-            };
-
-            let cmeta = Rc::new(cstore::crate_metadata {
-                name: load_ctxt.crate_id.name.to_owned(),
-                data: metadata,
-                cnum_map: cnum_map,
-                cnum: cnum,
-                span: span,
-            });
-
-            let source = cstore::CrateSource {
-                dylib: dylib,
-                rlib: rlib,
-                cnum: cnum,
-            };
-
-            if should_link {
-                e.sess.cstore.set_crate_data(cnum, cmeta.clone());
-                e.sess.cstore.add_used_crate_source(source.clone());
-            }
-            (cnum, cmeta, source)
+            let library = load_ctxt.load_library_crate();
+            register_crate(e, root, ident, crate_id, span, library)
         }
         Some(cnum) => (cnum,
                        e.sess.cstore.get_crate_data(cnum),
@@ -370,7 +360,6 @@ fn resolve_crate_deps(e: &mut Env,
                                                dep.crate_id.name.as_slice(),
                                                &dep.crate_id,
                                                Some(&dep.hash),
-                                               true,
                                                span);
         (dep.cnum, local_cnum)
     }).collect()
@@ -382,14 +371,10 @@ pub struct Loader<'a> {
 
 impl<'a> Loader<'a> {
     pub fn new(sess: &'a Session) -> Loader<'a> {
-        let os = driver::get_os(driver::host_triple()).unwrap();
-        let os = session::sess_os_to_meta_os(os);
         Loader {
             env: Env {
                 sess: sess,
-                os: os,
                 next_crate_num: sess.cstore.next_crate_num(),
-                intr: token::get_ident_interner(),
             }
         }
     }
@@ -398,18 +383,63 @@ pub fn new(sess: &'a Session) -> Loader<'a> {
 impl<'a> CrateLoader for Loader<'a> {
     fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
         let info = extract_crate_info(&self.env, krate).unwrap();
-        let (_, data, library) = resolve_crate(&mut self.env, &None,
-                                               info.ident, &info.crate_id,
-                                               None, info.should_link,
-                                               krate.span);
-        let macros = decoder::get_exported_macros(&*data);
-        let registrar = decoder::get_macro_registrar_fn(&*data).map(|id| {
-            decoder::get_symbol(data.data.as_slice(), id)
+        let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
+        let is_cross = target_triple != driver::host_triple();
+        let mut should_link = info.should_link && !is_cross;
+        let id_hash = link::crate_id_hash(&info.crate_id);
+        let os = driver::get_os(driver::host_triple()).unwrap();
+        let mut load_ctxt = loader::Context {
+            sess: self.env.sess,
+            span: krate.span,
+            ident: info.ident,
+            crate_id: &info.crate_id,
+            id_hash: id_hash,
+            hash: None,
+            filesearch: self.env.sess.host_filesearch(),
+            triple: driver::host_triple(),
+            os: session::sess_os_to_meta_os(os),
+            root: &None,
+            rejected_via_hash: vec!(),
+            rejected_via_triple: vec!(),
+        };
+        let library = match load_ctxt.maybe_load_library_crate() {
+            Some (l) => l,
+            None if is_cross => {
+                // try loading from target crates (only valid if there are
+                // no syntax extensions)
+                load_ctxt.triple = target_triple;
+                load_ctxt.os = session::sess_os_to_meta_os(self.env.sess.targ_cfg.os);
+                load_ctxt.filesearch = self.env.sess.target_filesearch();
+                let lib = load_ctxt.load_library_crate();
+                if decoder::get_macro_registrar_fn(lib.metadata.as_slice()).is_some() {
+                    let message = format!("crate `{}` contains a macro_registrar fn but \
+                                  only a version for triple `{}` could be found (need {})",
+                                  info.ident, target_triple, driver::host_triple());
+                    self.env.sess.span_err(krate.span, message);
+                    // need to abort now because the syntax expansion
+                    // code will shortly attempt to load and execute
+                    // code from the found library.
+                    self.env.sess.abort_if_errors();
+                }
+                should_link = info.should_link;
+                lib
+            }
+            None => { load_ctxt.report_load_errs(); unreachable!() },
+        };
+        let macros = decoder::get_exported_macros(library.metadata.as_slice());
+        let registrar = decoder::get_macro_registrar_fn(library.metadata.as_slice()).map(|id| {
+            decoder::get_symbol(library.metadata.as_slice(), id)
         });
-        MacroCrate {
-            lib: library.dylib,
+        let mc = MacroCrate {
+            lib: library.dylib.clone(),
             macros: macros.move_iter().collect(),
             registrar_symbol: registrar,
+        };
+        if should_link {
+            // register crate now to avoid double-reading metadata
+            register_crate(&mut self.env, &None, info.ident.as_slice(),
+                           &info.crate_id, krate.span, library);
         }
+        mc
     }
 }
index 4ebf4a52e41847fc4cb3bfbd2800a6fb40c02673..77b4871ea8b6f1c1991fe57171134196e72fbf07 100644 (file)
@@ -277,20 +277,6 @@ pub fn get_trait_of_method(cstore: &cstore::CStore,
     decoder::get_trait_of_method(&*cdata, def_id.node, tcx)
 }
 
-pub fn get_macro_registrar_fn(cstore: &cstore::CStore,
-                              crate_num: ast::CrateNum)
-                              -> Option<ast::NodeId> {
-    let cdata = cstore.get_crate_data(crate_num);
-    decoder::get_macro_registrar_fn(&*cdata)
-}
-
-pub fn get_exported_macros(cstore: &cstore::CStore,
-                           crate_num: ast::CrateNum)
-                           -> Vec<~str> {
-    let cdata = cstore.get_crate_data(crate_num);
-    decoder::get_exported_macros(&*cdata)
-}
-
 pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
                                            def_id: ast::DefId)
     -> Option<ast::DefId>
index b76b6d0c380659fa4ba37084741bd7d6c2144f63..6d5744340cc339462cc3792a838ec0e1884edcc8 100644 (file)
@@ -1147,6 +1147,12 @@ pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
     })
 }
 
+pub fn get_crate_triple(data: &[u8]) -> ~str {
+    let cratedoc = reader::Doc(data);
+    let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
+    triple_doc.expect("No triple in crate").as_str()
+}
+
 pub fn get_crate_id(data: &[u8]) -> CrateId {
     let cratedoc = reader::Doc(data);
     let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
@@ -1252,13 +1258,13 @@ pub fn get_native_libraries(cdata: Cmd) -> Vec<(cstore::NativeLibaryKind, ~str)>
     return result;
 }
 
-pub fn get_macro_registrar_fn(cdata: Cmd) -> Option<ast::NodeId> {
-    reader::maybe_get_doc(reader::Doc(cdata.data()), tag_macro_registrar_fn)
+pub fn get_macro_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
+    reader::maybe_get_doc(reader::Doc(data), tag_macro_registrar_fn)
         .map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap())
 }
 
-pub fn get_exported_macros(cdata: Cmd) -> Vec<~str> {
-    let macros = reader::get_doc(reader::Doc(cdata.data()),
+pub fn get_exported_macros(data: &[u8]) -> Vec<~str> {
+    let macros = reader::get_doc(reader::Doc(data),
                                  tag_exported_macros);
     let mut result = Vec::new();
     reader::tagged_docs(macros, tag_macro_def, |macro_doc| {
index d5ee1b15ae252ac4a988dd82ffc0d8f233aa8736..214fa3ee04bd942324bd30da74b99d754e815b98 100644 (file)
@@ -84,7 +84,7 @@ pub struct EncodeContext<'a> {
     pub non_inlineable_statics: &'a RefCell<NodeSet>,
     pub link_meta: &'a LinkMeta,
     pub cstore: &'a cstore::CStore,
-    pub encode_inlined_item: EncodeInlinedItem<'a>,
+    pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
     pub type_abbrevs: tyencode::abbrev_map,
 }
 
@@ -765,8 +765,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
         if num_params > 0u ||
                 is_default_impl ||
                 should_inline(ast_method.attrs.as_slice()) {
-            (ecx.encode_inlined_item)(
-                ecx, ebml_w, IIMethodRef(local_def(parent_id), false, ast_method));
+            encode_inlined_item(ecx, ebml_w,
+                                IIMethodRef(local_def(parent_id), false, ast_method));
         } else {
             encode_symbol(ecx, ebml_w, m.def_id.node);
         }
@@ -775,6 +775,14 @@ fn encode_info_for_method(ecx: &EncodeContext,
     ebml_w.end_tag();
 }
 
+fn encode_inlined_item(ecx: &EncodeContext,
+                       ebml_w: &mut Encoder,
+                       ii: InlinedItemRef) {
+    let mut eii = ecx.encode_inlined_item.borrow_mut();
+    let eii: &mut EncodeInlinedItem = &mut *eii;
+    (*eii)(ecx, ebml_w, ii)
+}
+
 fn style_fn_family(s: FnStyle) -> char {
     match s {
         UnsafeFn => 'u',
@@ -880,7 +888,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         let inlineable = !ecx.non_inlineable_statics.borrow().contains(&item.id);
 
         if inlineable {
-            (ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
+            encode_inlined_item(ecx, ebml_w, IIItemRef(item));
         }
         encode_visibility(ebml_w, vis);
         ebml_w.end_tag();
@@ -896,7 +904,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         encode_path(ebml_w, path);
         encode_attributes(ebml_w, item.attrs.as_slice());
         if tps_len > 0u || should_inline(item.attrs.as_slice()) {
-            (ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
+            encode_inlined_item(ecx, ebml_w, IIItemRef(item));
         } else {
             encode_symbol(ecx, ebml_w, item.id);
         }
@@ -954,7 +962,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         for v in (*enum_definition).variants.iter() {
             encode_variant_id(ebml_w, local_def(v.node.id));
         }
-        (ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
+        encode_inlined_item(ecx, ebml_w, IIItemRef(item));
         encode_path(ebml_w, path);
 
         // Encode inherent implementations for this enumeration.
@@ -1002,7 +1010,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
         needs to know*/
         encode_struct_fields(ebml_w, fields.as_slice(), def_id);
 
-        (ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
+        encode_inlined_item(ecx, ebml_w, IIItemRef(item));
 
         // Encode inherent implementations for this structure.
         encode_inherent_implementations(ecx, ebml_w, def_id);
@@ -1175,8 +1183,8 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
                         encode_bounds_and_type(ebml_w, ecx, &tpt);
                     }
                     encode_method_sort(ebml_w, 'p');
-                    (ecx.encode_inlined_item)(
-                        ecx, ebml_w, IIMethodRef(def_id, true, m));
+                    encode_inlined_item(ecx, ebml_w,
+                                        IIMethodRef(def_id, true, m));
                 }
             }
 
@@ -1212,7 +1220,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
                                &lookup_item_type(ecx.tcx,local_def(nitem.id)));
         encode_name(ebml_w, nitem.ident.name);
         if abi == abi::RustIntrinsic {
-            (ecx.encode_inlined_item)(ecx, ebml_w, IIForeignRef(nitem));
+            encode_inlined_item(ecx, ebml_w, IIForeignRef(nitem));
         } else {
             encode_symbol(ecx, ebml_w, nitem.id);
         }
@@ -1544,12 +1552,12 @@ fn encode_macro_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
     }
 }
 
-struct MacroDefVisitor<'a, 'b> {
-    ecx: &'a EncodeContext<'a>,
-    ebml_w: &'a mut Encoder<'b>
+struct MacroDefVisitor<'a, 'b, 'c> {
+    ecx: &'a EncodeContext<'b>,
+    ebml_w: &'a mut Encoder<'c>
 }
 
-impl<'a, 'b> Visitor<()> for MacroDefVisitor<'a, 'b> {
+impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> {
     fn visit_item(&mut self, item: &Item, _: ()) {
         match item.node {
             ItemMac(..) => {
@@ -1565,9 +1573,9 @@ fn visit_item(&mut self, item: &Item, _: ()) {
     }
 }
 
-fn encode_macro_defs(ecx: &EncodeContext,
-                     krate: &Crate,
-                     ebml_w: &mut Encoder) {
+fn encode_macro_defs<'a>(ecx: &'a EncodeContext,
+                         krate: &Crate,
+                         ebml_w: &'a mut Encoder) {
     ebml_w.start_tag(tag_exported_macros);
     {
         let mut visitor = MacroDefVisitor {
@@ -1579,12 +1587,12 @@ fn encode_macro_defs(ecx: &EncodeContext,
     ebml_w.end_tag();
 }
 
-struct ImplVisitor<'a,'b> {
-    ecx: &'a EncodeContext<'a>,
-    ebml_w: &'a mut Encoder<'b>,
+struct ImplVisitor<'a,'b,'c> {
+    ecx: &'a EncodeContext<'b>,
+    ebml_w: &'a mut Encoder<'c>,
 }
 
-impl<'a,'b> Visitor<()> for ImplVisitor<'a,'b> {
+impl<'a,'b,'c> Visitor<()> for ImplVisitor<'a,'b,'c> {
     fn visit_item(&mut self, item: &Item, _: ()) {
         match item.node {
             ItemImpl(_, Some(ref trait_ref), _, _) => {
@@ -1617,9 +1625,9 @@ fn visit_item(&mut self, item: &Item, _: ()) {
 /// * Destructors (implementations of the Drop trait).
 ///
 /// * Implementations of traits not defined in this crate.
-fn encode_impls(ecx: &EncodeContext,
-                krate: &Crate,
-                ebml_w: &mut Encoder) {
+fn encode_impls<'a>(ecx: &'a EncodeContext,
+                    krate: &Crate,
+                    ebml_w: &'a mut Encoder) {
     ebml_w.start_tag(tag_impls);
 
     {
@@ -1682,6 +1690,12 @@ fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
     ebml_w.end_tag();
 }
 
+fn encode_crate_triple(ebml_w: &mut Encoder, triple: &str) {
+    ebml_w.start_tag(tag_crate_triple);
+    ebml_w.writer.write(triple.as_bytes());
+    ebml_w.end_tag();
+}
+
 // NB: Increment this as you change the metadata encoding version.
 pub static metadata_encoding_version : &'static [u8] =
     &[0x72, //'r' as u8,
@@ -1744,13 +1758,14 @@ struct Stats {
         non_inlineable_statics: non_inlineable_statics,
         link_meta: link_meta,
         cstore: cstore,
-        encode_inlined_item: encode_inlined_item,
+        encode_inlined_item: RefCell::new(encode_inlined_item),
         type_abbrevs: RefCell::new(HashMap::new()),
      };
 
     let mut ebml_w = writer::Encoder(wr);
 
     encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
+    encode_crate_triple(&mut ebml_w, tcx.sess.targ_cfg.target_strs.target_triple);
     encode_hash(&mut ebml_w, &ecx.link_meta.crate_hash);
 
     let mut i = ebml_w.writer.tell().unwrap();
index 9b3dce6147b1a045ecb09ae78ac90f6e41a56605..a72e28eb805b1fb3de3e07bc71d1c2b8f43f3a8d 100644 (file)
@@ -30,7 +30,7 @@ pub enum FileMatch { FileMatches, FileDoesntMatch }
 pub struct FileSearch<'a> {
     pub sysroot: &'a Path,
     pub addl_lib_search_paths: &'a RefCell<HashSet<Path>>,
-    pub target_triple: &'a str
+    pub triple: &'a str,
 }
 
 impl<'a> FileSearch<'a> {
@@ -48,22 +48,23 @@ pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
             visited_dirs.insert(path.as_vec().to_owned());
         }
 
-        debug!("filesearch: searching target lib path");
+        debug!("filesearch: searching lib path");
         let tlib_path = make_target_lib_path(self.sysroot,
-                                    self.target_triple);
+                                    self.triple);
         if !visited_dirs.contains_equiv(&tlib_path.as_vec()) {
             match f(&tlib_path) {
                 FileMatches => found = true,
                 FileDoesntMatch => ()
             }
         }
+
         visited_dirs.insert(tlib_path.as_vec().to_owned());
         // Try RUST_PATH
         if !found {
             let rustpath = rust_path();
             for path in rustpath.iter() {
-                let tlib_path = make_rustpkg_target_lib_path(
-                    self.sysroot, path, self.target_triple);
+                let tlib_path = make_rustpkg_lib_path(
+                    self.sysroot, path, self.triple);
                 debug!("is {} in visited_dirs? {:?}", tlib_path.display(),
                         visited_dirs.contains_equiv(&tlib_path.as_vec().to_owned()));
 
@@ -82,8 +83,8 @@ pub fn for_each_lib_search_path(&self, f: |&Path| -> FileMatch) {
         }
     }
 
-    pub fn get_target_lib_path(&self) -> Path {
-        make_target_lib_path(self.sysroot, self.target_triple)
+    pub fn get_lib_path(&self) -> Path {
+        make_target_lib_path(self.sysroot, self.triple)
     }
 
     pub fn search(&self, pick: pick) {
@@ -92,9 +93,9 @@ pub fn search(&self, pick: pick) {
             match fs::readdir(lib_search_path) {
                 Ok(files) => {
                     let mut rslt = FileDoesntMatch;
-                    let is_rlib = |p: & &Path| {
+                    fn is_rlib(p: & &Path) -> bool {
                         p.extension_str() == Some("rlib")
-                    };
+                    }
                     // Reading metadata out of rlibs is faster, and if we find both
                     // an rlib and a dylib we only read one of the files of
                     // metadata, so in the name of speed, bring all rlib files to
@@ -122,13 +123,13 @@ pub fn search(&self, pick: pick) {
     }
 
     pub fn new(sysroot: &'a Path,
-               target_triple: &'a str,
+               triple: &'a str,
                addl_lib_search_paths: &'a RefCell<HashSet<Path>>) -> FileSearch<'a> {
-        debug!("using sysroot = {}", sysroot.display());
+        debug!("using sysroot = {}, triple = {}", sysroot.display(), triple);
         FileSearch {
             sysroot: sysroot,
             addl_lib_search_paths: addl_lib_search_paths,
-            target_triple: target_triple
+            triple: triple,
         }
     }
 }
@@ -147,11 +148,11 @@ fn make_target_lib_path(sysroot: &Path,
     sysroot.join(&relative_target_lib_path(sysroot, target_triple))
 }
 
-fn make_rustpkg_target_lib_path(sysroot: &Path,
-                                dir: &Path,
-                                target_triple: &str) -> Path {
+fn make_rustpkg_lib_path(sysroot: &Path,
+                         dir: &Path,
+                         triple: &str) -> Path {
     let mut p = dir.join(find_libdir(sysroot));
-    p.push(target_triple);
+    p.push(triple);
     p
 }
 
index bd95ba95c70d9c1ee3cdf85b6335ca331b83fd40..4e6f4e2c96520f00b5fd9a8a3df781fbd8f19bf7 100644 (file)
 use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
 use metadata::decoder;
 use metadata::encoder;
-use metadata::filesearch::{FileMatches, FileDoesntMatch};
+use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
 use syntax::codemap::Span;
 use syntax::diagnostic::SpanHandler;
-use syntax::parse::token::IdentInterner;
 use syntax::crateid::CrateId;
 use syntax::attr::AttrMetaMethods;
 
@@ -30,7 +29,6 @@
 use std::io;
 use std::os::consts::{macos, freebsd, linux, android, win32};
 use std::ptr;
-use std::rc::Rc;
 use std::slice;
 use std::str;
 
@@ -46,8 +44,9 @@ pub enum Os {
     OsFreebsd
 }
 
-pub struct HashMismatch {
+pub struct CrateMismatch {
     path: Path,
+    got: ~str,
 }
 
 pub struct Context<'a> {
@@ -57,9 +56,12 @@ pub struct Context<'a> {
     pub crate_id: &'a CrateId,
     pub id_hash: &'a str,
     pub hash: Option<&'a Svh>,
+    pub triple: &'a str,
     pub os: Os,
-    pub intr: Rc<IdentInterner>,
-    pub rejected_via_hash: Vec<HashMismatch>
+    pub filesearch: FileSearch<'a>,
+    pub root: &'a Option<CratePaths>,
+    pub rejected_via_hash: Vec<CrateMismatch>,
+    pub rejected_via_triple: Vec<CrateMismatch>,
 }
 
 pub struct Library {
@@ -104,52 +106,69 @@ fn realpath(p: &Path) -> Path {
 }
 
 impl<'a> Context<'a> {
-    pub fn load_library_crate(&mut self, root: &Option<CratePaths>) -> Library {
+    pub fn maybe_load_library_crate(&mut self) -> Option<Library> {
+        self.find_library_crate()
+    }
+
+    pub fn load_library_crate(&mut self) -> Library {
         match self.find_library_crate() {
             Some(t) => t,
             None => {
-                self.sess.abort_if_errors();
-                let message = if self.rejected_via_hash.len() > 0 {
-                    format!("found possibly newer version of crate `{}`",
-                            self.ident)
-                } else {
-                    format!("can't find crate for `{}`", self.ident)
-                };
-                let message = match root {
-                    &None => message,
-                    &Some(ref r) => format!("{} which `{}` depends on",
-                                            message, r.ident)
-                };
-                self.sess.span_err(self.span, message);
-
-                if self.rejected_via_hash.len() > 0 {
-                    self.sess.span_note(self.span, "perhaps this crate needs \
-                                                    to be recompiled?");
-                    let mismatches = self.rejected_via_hash.iter();
-                    for (i, &HashMismatch{ ref path }) in mismatches.enumerate() {
+                self.report_load_errs();
+                unreachable!()
+            }
+        }
+    }
+
+    pub fn report_load_errs(&mut self) {
+        let message = if self.rejected_via_hash.len() > 0 {
+            format!("found possibly newer version of crate `{}`",
+                    self.ident)
+        } else if self.rejected_via_triple.len() > 0 {
+            format!("found incorrect triple for crate `{}`", self.ident)
+        } else {
+            format!("can't find crate for `{}`", self.ident)
+        };
+        let message = match self.root {
+            &None => message,
+            &Some(ref r) => format!("{} which `{}` depends on",
+                                    message, r.ident)
+        };
+        self.sess.span_err(self.span, message);
+
+        let mismatches = self.rejected_via_triple.iter();
+        if self.rejected_via_triple.len() > 0 {
+            self.sess.span_note(self.span, format!("expected triple of {}", self.triple));
+            for (i, &CrateMismatch{ ref path, ref got }) in mismatches.enumerate() {
+                self.sess.fileline_note(self.span,
+                    format!("crate `{}` path \\#{}, triple {}: {}",
+                            self.ident, i+1, got, path.display()));
+            }
+        }
+        if self.rejected_via_hash.len() > 0 {
+            self.sess.span_note(self.span, "perhaps this crate needs \
+                                            to be recompiled?");
+            let mismatches = self.rejected_via_hash.iter();
+            for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() {
+                self.sess.fileline_note(self.span,
+                    format!("crate `{}` path \\#{}: {}",
+                            self.ident, i+1, path.display()));
+            }
+            match self.root {
+                &None => {}
+                &Some(ref r) => {
+                    for (i, path) in r.paths().iter().enumerate() {
                         self.sess.fileline_note(self.span,
                             format!("crate `{}` path \\#{}: {}",
-                                    self.ident, i+1, path.display()));
-                    }
-                    match root {
-                        &None => {}
-                        &Some(ref r) => {
-                            for (i, path) in r.paths().iter().enumerate() {
-                                self.sess.fileline_note(self.span,
-                                    format!("crate `{}` path \\#{}: {}",
-                                            r.ident, i+1, path.display()));
-                            }
-                        }
+                                    r.ident, i+1, path.display()));
                     }
                 }
-                self.sess.abort_if_errors();
-                unreachable!()
             }
         }
+        self.sess.abort_if_errors();
     }
 
     fn find_library_crate(&mut self) -> Option<Library> {
-        let filesearch = self.sess.filesearch();
         let (dyprefix, dysuffix) = self.dylibname();
 
         // want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
@@ -171,11 +190,12 @@ fn find_library_crate(&mut self) -> Option<Library> {
         // of the crate id (path/name/id).
         //
         // The goal of this step is to look at as little metadata as possible.
-        filesearch.search(|path| {
+        self.filesearch.search(|path| {
             let file = match path.filename_str() {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
+            info!("file: {}", file);
             if file.starts_with(rlib_prefix) && file.ends_with(".rlib") {
                 info!("rlib candidate: {}", path.display());
                 match self.try_match(file, rlib_prefix, ".rlib") {
@@ -376,16 +396,30 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
     fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
         match decoder::maybe_get_crate_id(crate_data) {
             Some(ref id) if self.crate_id.matches(id) => {}
-            _ => return false
+            _ => { info!("Rejecting via crate_id"); return false }
         }
         let hash = match decoder::maybe_get_crate_hash(crate_data) {
-            Some(hash) => hash, None => return false
+            Some(hash) => hash, None => {
+                info!("Rejecting via lack of crate hash");
+                return false;
+            }
         };
+
+        let triple = decoder::get_crate_triple(crate_data);
+        if triple.as_slice() != self.triple {
+            info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
+            self.rejected_via_triple.push(CrateMismatch{ path: libpath.clone(),
+                                                         got: triple.to_owned() });
+            return false;
+        }
+
         match self.hash {
             None => true,
             Some(myhash) => {
                 if *myhash != hash {
-                    self.rejected_via_hash.push(HashMismatch{ path: libpath.clone() });
+                    info!("Rejecting via hash: expected {} got {}", *myhash, hash);
+                    self.rejected_via_hash.push(CrateMismatch{ path: libpath.clone(),
+                                                               got: myhash.as_str().to_owned() });
                     false
                 } else {
                     true
@@ -394,6 +428,7 @@ fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
         }
     }
 
+
     // Returns the corresponding (prefix, suffix) that files need to have for
     // dynamic libraries
     fn dylibname(&self) -> (&'static str, &'static str) {
@@ -405,6 +440,7 @@ fn dylibname(&self) -> (&'static str, &'static str) {
             OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
         }
     }
+
 }
 
 pub fn note_crateid_attr(diag: &SpanHandler, crateid: &CrateId) {
index e09507f5d5f44ac9fdc296796a6ad9dd19c0735a..d0f4796683250dfe4b9ad4a6e5404aea475b4232 100644 (file)
@@ -327,7 +327,7 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                             self.bccx.loan_path_to_str(&*old_loan.loan_path))
                 }
 
-                AddrOf | AutoRef | RefBinding => {
+                AddrOf | AutoRef | RefBinding | ClosureInvocation => {
                     format!("previous borrow of `{}` occurs here",
                             self.bccx.loan_path_to_str(&*old_loan.loan_path))
                 }
index 7f748dffd702b6d16f27db7c19929974bb9a8ee4..8bb95b798d0aa46e11446ec0a7fa0204505a54bc 100644 (file)
@@ -292,6 +292,26 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
           visit::walk_expr(this, ex, ());
       }
 
+      ast::ExprCall(f, _) => {
+          let expr_ty = ty::expr_ty_adjusted(tcx, f);
+          match ty::get(expr_ty).sty {
+              ty::ty_closure(~ty::ClosureTy {
+                  store: ty::RegionTraitStore(..), ..
+              }) => {
+                  let scope_r = ty::ReScope(ex.id);
+                  let base_cmt = this.bccx.cat_expr(f);
+                  this.guarantee_valid_kind(f.id,
+                                            f.span,
+                                            base_cmt,
+                                            ty::UniqueImmBorrow,
+                                            scope_r,
+                                            ClosureInvocation);
+              }
+              _ => {}
+          }
+          visit::walk_expr(this, ex, ());
+      }
+
       _ => {
           visit::walk_expr(this, ex, ());
       }
index 06491d36b021b5312ece3a25cb5b926800e66080..3de64f151917e24436ec0f05671aa25959c9f276 100644 (file)
@@ -202,6 +202,7 @@ pub enum LoanCause {
     AddrOf,
     AutoRef,
     RefBinding,
+    ClosureInvocation,
 }
 
 #[deriving(Eq, TotalEq, Hash)]
@@ -629,6 +630,10 @@ pub fn bckerr_to_str(&self, err: &BckError) -> ~str {
                     AddrOf | RefBinding | AutoRef => {
                         format!("cannot borrow {} as mutable", descr)
                     }
+                    ClosureInvocation => {
+                        self.tcx.sess.span_bug(err.span,
+                            "err_mutbl with a closure invocation");
+                    }
                 }
             }
             err_out_of_root_scope(..) => {
@@ -677,6 +682,10 @@ pub fn report_aliasability_violation(&self,
             BorrowViolation(RefBinding) => {
                 "cannot borrow data mutably"
             }
+
+            BorrowViolation(ClosureInvocation) => {
+                "closure invocation"
+            }
         };
 
         match cause {
index d1cc7d7bc401b60d1519f879f73f9d4ef7aa1812..05a225d8953fce281575459cf42eb0ea1b48ef17 100644 (file)
@@ -1164,7 +1164,7 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::Item) {
     fn is_camel_case(ident: ast::Ident) -> bool {
         let ident = token::get_ident(ident);
         assert!(!ident.get().is_empty());
-        let ident = ident.get().trim_chars(&'_');
+        let ident = ident.get().trim_chars('_');
 
         // start with a non-lowercase letter rather than non-uppercase
         // ones (some scripts don't have a concept of upper/lowercase)
index eeccd1ca334497c6498dc09b7ba66aa6c70120f8..4e2d8cf585f2cebca8af26699f4c6c1ea5485500 100644 (file)
@@ -1104,34 +1104,34 @@ fn check_sane_privacy(&self, item: &ast::Item) {
     /// control over anything so this forbids any mention of any visibility
     fn check_all_inherited(&self, item: &ast::Item) {
         let tcx = self.tcx;
-        let check_inherited = |sp: Span, vis: ast::Visibility| {
+        fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
             if vis != ast::Inherited {
                 tcx.sess.span_err(sp, "visibility has no effect inside functions");
             }
-        };
+        }
         let check_struct = |def: &@ast::StructDef| {
             for f in def.fields.iter() {
                match f.node.kind {
-                    ast::NamedField(_, p) => check_inherited(f.span, p),
+                    ast::NamedField(_, p) => check_inherited(tcx, f.span, p),
                     ast::UnnamedField(..) => {}
                 }
             }
         };
-        check_inherited(item.span, item.vis);
+        check_inherited(tcx, item.span, item.vis);
         match item.node {
             ast::ItemImpl(_, _, _, ref methods) => {
                 for m in methods.iter() {
-                    check_inherited(m.span, m.vis);
+                    check_inherited(tcx, m.span, m.vis);
                 }
             }
             ast::ItemForeignMod(ref fm) => {
                 for i in fm.items.iter() {
-                    check_inherited(i.span, i.vis);
+                    check_inherited(tcx, i.span, i.vis);
                 }
             }
             ast::ItemEnum(ref def, _) => {
                 for v in def.variants.iter() {
-                    check_inherited(v.span, v.node.vis);
+                    check_inherited(tcx, v.span, v.node.vis);
 
                     match v.node.kind {
                         ast::StructVariantKind(ref s) => check_struct(s),
@@ -1146,7 +1146,8 @@ fn check_all_inherited(&self, item: &ast::Item) {
                 for m in methods.iter() {
                     match *m {
                         ast::Required(..) => {}
-                        ast::Provided(ref m) => check_inherited(m.span, m.vis),
+                        ast::Provided(ref m) => check_inherited(tcx, m.span,
+                                                                m.vis),
                     }
                 }
             }
index 94cbd3a3a750748000085fb95bcc18a1d0310b21..b59da8910af8b4ff8d00f590c46f5168a9dabdd7 100644 (file)
@@ -751,7 +751,15 @@ fn constrain_callee(rcx: &mut Rcx,
         ty::ty_bare_fn(..) => { }
         ty::ty_closure(ref closure_ty) => {
             let region = match closure_ty.store {
-                ty::RegionTraitStore(r, _) => r,
+                ty::RegionTraitStore(r, _) => {
+                    // While we're here, link the closure's region with a unique
+                    // immutable borrow (gathered later in borrowck)
+                    let mc = mc::MemCategorizationContext { typer: &*rcx };
+                    let expr_cmt = ignore_err!(mc.cat_expr(callee_expr));
+                    link_region(mc.typer, callee_expr.span, call_region,
+                                ty::UniqueImmBorrow, expr_cmt);
+                    r
+                }
                 ty::UniqTraitStore => ty::ReStatic
             };
             rcx.fcx.mk_subr(true, infer::InvokeClosure(callee_expr.span),
@@ -874,7 +882,8 @@ fn constrain_autoderefs(rcx: &mut Rcx,
                 {
                     let mc = mc::MemCategorizationContext { typer: &*rcx };
                     let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i));
-                    link_region(mc.typer, deref_expr.span, r, m, self_cmt);
+                    link_region(mc.typer, deref_expr.span, r,
+                                ty::BorrowKind::from_mutbl(m), self_cmt);
                 }
 
                 // Specialized version of constrain_call.
@@ -1092,7 +1101,8 @@ fn link_pattern(mc: mc::MemCategorizationContext<&Rcx>,
                     match mc.cat_slice_pattern(sub_cmt, slice_pat) {
                         Ok((slice_cmt, slice_mutbl, slice_r)) => {
                             link_region(mc.typer, sub_pat.span, slice_r,
-                                        slice_mutbl, slice_cmt);
+                                        ty::BorrowKind::from_mutbl(slice_mutbl),
+                                        slice_cmt);
                         }
                         Err(()) => {}
                     }
@@ -1118,17 +1128,20 @@ fn link_autoref(rcx: &Rcx,
 
     match *autoref {
         ty::AutoPtr(r, m) => {
-            link_region(mc.typer, expr.span, r, m, expr_cmt);
+            link_region(mc.typer, expr.span, r,
+                        ty::BorrowKind::from_mutbl(m), expr_cmt);
         }
 
         ty::AutoBorrowVec(r, m) | ty::AutoBorrowVecRef(r, m) => {
             let cmt_index = mc.cat_index(expr, expr_cmt, autoderefs+1);
-            link_region(mc.typer, expr.span, r, m, cmt_index);
+            link_region(mc.typer, expr.span, r,
+                        ty::BorrowKind::from_mutbl(m), cmt_index);
         }
 
         ty::AutoBorrowObj(r, m) => {
             let cmt_deref = mc.cat_deref_obj(expr, expr_cmt);
-            link_region(mc.typer, expr.span, r, m, cmt_deref);
+            link_region(mc.typer, expr.span, r,
+                        ty::BorrowKind::from_mutbl(m), cmt_deref);
         }
 
         ty::AutoUnsafe(_) => {}
@@ -1150,7 +1163,7 @@ fn link_by_ref(rcx: &Rcx,
     let mc = mc::MemCategorizationContext { typer: rcx };
     let expr_cmt = ignore_err!(mc.cat_expr(expr));
     let region_min = ty::ReScope(callee_scope);
-    link_region(mc.typer, expr.span, region_min, ast::MutImmutable, expr_cmt);
+    link_region(mc.typer, expr.span, region_min, ty::ImmBorrow, expr_cmt);
 }
 
 fn link_region_from_node_type(rcx: &Rcx,
@@ -1169,18 +1182,19 @@ fn link_region_from_node_type(rcx: &Rcx,
         let tcx = rcx.fcx.ccx.tcx;
         debug!("rptr_ty={}", ty_to_str(tcx, rptr_ty));
         let r = ty::ty_region(tcx, span, rptr_ty);
-        link_region(rcx, span, r, mutbl, cmt_borrowed);
+        link_region(rcx, span, r, ty::BorrowKind::from_mutbl(mutbl),
+                    cmt_borrowed);
     }
 }
 
 fn link_region(rcx: &Rcx,
                span: Span,
                region_min: ty::Region,
-               mutbl: ast::Mutability,
+               kind: ty::BorrowKind,
                cmt_borrowed: mc::cmt) {
     /*!
      * Informs the inference engine that a borrow of `cmt`
-     * must have mutability `mutbl` and lifetime `region_min`.
+     * must have the borrow kind `kind` and lifetime `region_min`.
      * If `cmt` is a deref of a region pointer with
      * lifetime `r_borrowed`, this will add the constraint that
      * `region_min <= r_borrowed`.
@@ -1190,9 +1204,9 @@ fn link_region(rcx: &Rcx,
     // for the lifetime `region_min` for the borrow to be valid:
     let mut cmt_borrowed = cmt_borrowed;
     loop {
-        debug!("link_region(region_min={}, mutbl={}, cmt_borrowed={})",
+        debug!("link_region(region_min={}, kind={}, cmt_borrowed={})",
                region_min.repr(rcx.tcx()),
-               mutbl.repr(rcx.tcx()),
+               kind.repr(rcx.tcx()),
                cmt_borrowed.repr(rcx.tcx()));
         match cmt_borrowed.cat.clone() {
             mc::cat_deref(base, _, mc::BorrowedPtr(_, r_borrowed)) => {
@@ -1214,7 +1228,7 @@ fn link_region(rcx: &Rcx,
                                 adjust_upvar_borrow_kind_for_loan(
                                     *upvar_id,
                                     upvar_borrow,
-                                    mutbl);
+                                    kind);
                                 infer::ReborrowUpvar(span, *upvar_id)
                             }
                             None => {
@@ -1236,7 +1250,7 @@ fn link_region(rcx: &Rcx,
                        r_borrowed.repr(rcx.tcx()));
                 rcx.fcx.mk_subr(true, cause, region_min, r_borrowed);
 
-                if mutbl == ast::MutMutable {
+                if kind != ty::ImmBorrow {
                     // If this is a mutable borrow, then the thing
                     // being borrowed will have to be unique.
                     // In user code, this means it must be an `&mut`
@@ -1428,12 +1442,11 @@ fn link_upvar_borrow_kind_for_nested_closures(rcx: &mut Rcx,
 
 fn adjust_upvar_borrow_kind_for_loan(upvar_id: ty::UpvarId,
                                      upvar_borrow: &mut ty::UpvarBorrow,
-                                     mutbl: ast::Mutability) {
+                                     kind: ty::BorrowKind) {
     debug!("adjust_upvar_borrow_kind_for_loan: upvar_id={:?} kind={:?} -> {:?}",
-           upvar_id, upvar_borrow.kind, mutbl);
+           upvar_id, upvar_borrow.kind, kind);
 
-    adjust_upvar_borrow_kind(upvar_id, upvar_borrow,
-                             ty::BorrowKind::from_mutbl(mutbl))
+    adjust_upvar_borrow_kind(upvar_id, upvar_borrow, kind)
 }
 
 fn adjust_upvar_borrow_kind(upvar_id: ty::UpvarId,
index 69d978b24334fec56c0ae1dea0e5970478e42f56..f8df9263be1dbc55b4b091b46f292c8cd7656999 100644 (file)
@@ -174,6 +174,9 @@ pub struct TcpListener {
 
 pub struct TcpAcceptor {
     listener: ~TcpListener,
+    timer: Option<TimerWatcher>,
+    timeout_tx: Option<Sender<()>>,
+    timeout_rx: Option<Receiver<()>>,
 }
 
 // TCP watchers (clients/streams)
@@ -459,7 +462,12 @@ fn socket_name(&mut self) -> Result<ip::SocketAddr, IoError> {
 impl rtio::RtioTcpListener for TcpListener {
     fn listen(~self) -> Result<~rtio::RtioTcpAcceptor:Send, IoError> {
         // create the acceptor object from ourselves
-        let mut acceptor = ~TcpAcceptor { listener: self };
+        let mut acceptor = ~TcpAcceptor {
+            listener: self,
+            timer: None,
+            timeout_tx: None,
+            timeout_rx: None,
+        };
 
         let _m = acceptor.fire_homing_missile();
         // FIXME: the 128 backlog should be configurable
@@ -509,7 +517,37 @@ fn socket_name(&mut self) -> Result<ip::SocketAddr, IoError> {
 
 impl rtio::RtioTcpAcceptor for TcpAcceptor {
     fn accept(&mut self) -> Result<~rtio::RtioTcpStream:Send, IoError> {
-        self.listener.incoming.recv()
+        match self.timeout_rx {
+            None => self.listener.incoming.recv(),
+            Some(ref rx) => {
+                use std::comm::Select;
+
+                // Poll the incoming channel first (don't rely on the order of
+                // select just yet). If someone's pending then we should return
+                // them immediately.
+                match self.listener.incoming.try_recv() {
+                    Ok(data) => return data,
+                    Err(..) => {}
+                }
+
+                // Use select to figure out which channel gets ready first. We
+                // do some custom handling of select to ensure that we never
+                // actually drain the timeout channel (we'll keep seeing the
+                // timeout message in the future).
+                let s = Select::new();
+                let mut timeout = s.handle(rx);
+                let mut data = s.handle(&self.listener.incoming);
+                unsafe {
+                    timeout.add();
+                    data.add();
+                }
+                if s.wait() == timeout.id() {
+                    Err(uv_error_to_io_error(UvError(uvll::ECANCELED)))
+                } else {
+                    self.listener.incoming.recv()
+                }
+            }
+        }
     }
 
     fn accept_simultaneously(&mut self) -> Result<(), IoError> {
@@ -525,6 +563,52 @@ fn dont_accept_simultaneously(&mut self) -> Result<(), IoError> {
             uvll::uv_tcp_simultaneous_accepts(self.listener.handle, 0)
         })
     }
+
+    fn set_timeout(&mut self, ms: Option<u64>) {
+        // First, if the timeout is none, clear any previous timeout by dropping
+        // the timer and transmission channels
+        let ms = match ms {
+            None => {
+                return drop((self.timer.take(),
+                             self.timeout_tx.take(),
+                             self.timeout_rx.take()))
+            }
+            Some(ms) => ms,
+        };
+
+        // If we have a timeout, lazily initialize the timer which will be used
+        // to fire when the timeout runs out.
+        if self.timer.is_none() {
+            let _m = self.fire_homing_missile();
+            let loop_ = Loop::wrap(unsafe {
+                uvll::get_loop_for_uv_handle(self.listener.handle)
+            });
+            let mut timer = TimerWatcher::new_home(&loop_, self.home().clone());
+            unsafe {
+                timer.set_data(self as *mut _ as *TcpAcceptor);
+            }
+            self.timer = Some(timer);
+        }
+
+        // Once we've got a timer, stop any previous timeout, reset it for the
+        // current one, and install some new channels to send/receive data on
+        let timer = self.timer.get_mut_ref();
+        timer.stop();
+        timer.start(timer_cb, ms, 0);
+        let (tx, rx) = channel();
+        self.timeout_tx = Some(tx);
+        self.timeout_rx = Some(rx);
+
+        extern fn timer_cb(timer: *uvll::uv_timer_t, status: c_int) {
+            assert_eq!(status, 0);
+            let acceptor: &mut TcpAcceptor = unsafe {
+                &mut *(uvll::get_data_for_uv_handle(timer) as *mut TcpAcceptor)
+            };
+            // This send can never fail because if this timer is active then the
+            // receiving channel is guaranteed to be alive
+            acceptor.timeout_tx.get_ref().send(());
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index 3710d97827f2819fbd0ceaf4250fcdef60c494a3..65ab32c6965a786fbef3f47e42d79c43f81be8e5 100644 (file)
@@ -14,7 +14,7 @@
 use std::rt::task::BlockedTask;
 
 use homing::{HomeHandle, HomingIO};
-use super::{UvHandle, ForbidUnwind, ForbidSwitch, wait_until_woken_after};
+use super::{UvHandle, ForbidUnwind, ForbidSwitch, wait_until_woken_after, Loop};
 use uvio::UvIoFactory;
 use uvll;
 
@@ -34,18 +34,21 @@ pub enum NextAction {
 
 impl TimerWatcher {
     pub fn new(io: &mut UvIoFactory) -> ~TimerWatcher {
+        let handle = io.make_handle();
+        let me = ~TimerWatcher::new_home(&io.loop_, handle);
+        me.install()
+    }
+
+    pub fn new_home(loop_: &Loop, home: HomeHandle) -> TimerWatcher {
         let handle = UvHandle::alloc(None::<TimerWatcher>, uvll::UV_TIMER);
-        assert_eq!(unsafe {
-            uvll::uv_timer_init(io.uv_loop(), handle)
-        }, 0);
-        let me = ~TimerWatcher {
+        assert_eq!(unsafe { uvll::uv_timer_init(loop_.handle, handle) }, 0);
+        TimerWatcher {
             handle: handle,
             action: None,
             blocker: None,
-            home: io.make_handle(),
+            home: home,
             id: 0,
-        };
-        return me.install();
+        }
     }
 
     pub fn start(&mut self, f: uvll::uv_timer_cb, msecs: u64, period: u64) {
index f61b282767f7161f8e835ecb82ab7218e9625ad9..7621a7ec4cd5efdc948a9d9e20438225a1f7429b 100644 (file)
@@ -107,9 +107,9 @@ fn read_till_eof<T>(&mut self, cb: |&mut Parser| -> Option<T>)
     }
 
     // Return result of first successful parser
-    fn read_or<T>(&mut self, parsers: &[|&mut Parser| -> Option<T>])
+    fn read_or<T>(&mut self, parsers: &mut [|&mut Parser| -> Option<T>])
                -> Option<T> {
-        for pf in parsers.iter() {
+        for pf in parsers.mut_iter() {
             match self.read_atomically(|p: &mut Parser| (*pf)(p)) {
                 Some(r) => return Some(r),
                 None => {}
@@ -305,7 +305,7 @@ fn read_ipv6_addr(&mut self) -> Option<IpAddr> {
     fn read_ip_addr(&mut self) -> Option<IpAddr> {
         let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
         let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
-        self.read_or([ipv4_addr, ipv6_addr])
+        self.read_or(&mut [ipv4_addr, ipv6_addr])
     }
 
     fn read_socket_addr(&mut self) -> Option<SocketAddr> {
@@ -318,7 +318,7 @@ fn read_socket_addr(&mut self) -> Option<SocketAddr> {
                 p.read_seq_3::<char, IpAddr, char>(open_br, ip_addr, clos_br)
                         .map(|t| match t { (_, ip, _) => ip })
             };
-            p.read_or([ipv4_p, ipv6_p])
+            p.read_or(&mut [ipv4_p, ipv6_p])
         };
         let colon = |p: &mut Parser| p.read_given_char(':');
         let port  = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
index 4f1e6bd741817c4cb598985d62cf0ad7a03c92e6..0619c89aac1c440df8c6ecf780dc66ed81362281 100644 (file)
@@ -22,7 +22,7 @@
 use io::net::ip::SocketAddr;
 use io::{Reader, Writer, Listener, Acceptor};
 use kinds::Send;
-use option::{None, Some};
+use option::{None, Some, Option};
 use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
 use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
 
@@ -184,6 +184,56 @@ pub struct TcpAcceptor {
     obj: ~RtioTcpAcceptor:Send
 }
 
+impl TcpAcceptor {
+    /// Prevents blocking on all future accepts after `ms` milliseconds have
+    /// elapsed.
+    ///
+    /// This function is used to set a deadline after which this acceptor will
+    /// time out accepting any connections. The argument is the relative
+    /// distance, in milliseconds, to a point in the future after which all
+    /// accepts will fail.
+    ///
+    /// If the argument specified is `None`, then any previously registered
+    /// timeout is cleared.
+    ///
+    /// A timeout of `0` can be used to "poll" this acceptor to see if it has
+    /// any pending connections. All pending connections will be accepted,
+    /// regardless of whether the timeout has expired or not (the accept will
+    /// not block in this case).
+    ///
+    /// # Example
+    ///
+    /// ```no_run
+    /// # #![allow(experimental)]
+    /// use std::io::net::tcp::TcpListener;
+    /// use std::io::net::ip::{SocketAddr, Ipv4Addr};
+    /// use std::io::{Listener, Acceptor, TimedOut};
+    ///
+    /// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8482 };
+    /// let mut a = TcpListener::bind(addr).listen().unwrap();
+    ///
+    /// // After 100ms have passed, all accepts will fail
+    /// a.set_timeout(Some(100));
+    ///
+    /// match a.accept() {
+    ///     Ok(..) => println!("accepted a socket"),
+    ///     Err(ref e) if e.kind == TimedOut => { println!("timed out!"); }
+    ///     Err(e) => println!("err: {}", e),
+    /// }
+    ///
+    /// // Reset the timeout and try again
+    /// a.set_timeout(Some(100));
+    /// let socket = a.accept();
+    ///
+    /// // Clear the timeout and block indefinitely waiting for a connection
+    /// a.set_timeout(None);
+    /// let socket = a.accept();
+    /// ```
+    #[experimental = "the type of the argument and name of this function are \
+                      subject to change"]
+    pub fn set_timeout(&mut self, ms: Option<u64>) { self.obj.set_timeout(ms); }
+}
+
 impl Acceptor<TcpStream> for TcpAcceptor {
     fn accept(&mut self) -> IoResult<TcpStream> {
         self.obj.accept().map(TcpStream::new)
@@ -191,6 +241,7 @@ fn accept(&mut self) -> IoResult<TcpStream> {
 }
 
 #[cfg(test)]
+#[allow(experimental)]
 mod test {
     use super::*;
     use io::net::ip::SocketAddr;
@@ -749,4 +800,37 @@ pub fn peer_name(addr: SocketAddr) {
         assert!(s.write([1]).is_err());
         assert_eq!(s.read_to_end(), Ok(vec!(1)));
     })
+
+    iotest!(fn accept_timeout() {
+        let addr = next_test_ip4();
+        let mut a = TcpListener::bind(addr).unwrap().listen().unwrap();
+
+        a.set_timeout(Some(10));
+
+        // Make sure we time out once and future invocations also time out
+        let err = a.accept().err().unwrap();
+        assert_eq!(err.kind, TimedOut);
+        let err = a.accept().err().unwrap();
+        assert_eq!(err.kind, TimedOut);
+
+        // Also make sure that even though the timeout is expired that we will
+        // continue to receive any pending connections.
+        let l = TcpStream::connect(addr).unwrap();
+        for i in range(0, 1001) {
+            match a.accept() {
+                Ok(..) => break,
+                Err(ref e) if e.kind == TimedOut => {}
+                Err(e) => fail!("error: {}", e),
+            }
+            if i == 1000 { fail!("should have a pending connection") }
+        }
+        drop(l);
+
+        // Unset the timeout and make sure that this always blocks.
+        a.set_timeout(None);
+        spawn(proc() {
+            drop(TcpStream::connect(addr));
+        });
+        a.accept().unwrap();
+    })
 }
index 7a04303268b1fce5f1521dd0e5895c5dfbd03753..d895331752f882a1422d38368b1e1c29b35c8796 100644 (file)
@@ -703,7 +703,7 @@ pub trait RandomAccessIterator<A>: Iterator<A> {
     fn indexable(&self) -> uint;
 
     /// Return an element at an index
-    fn idx(&self, index: uint) -> Option<A>;
+    fn idx(&mut self, index: uint) -> Option<A>;
 }
 
 /// An iterator that knows its exact length
@@ -771,8 +771,9 @@ impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterato
     #[inline]
     fn indexable(&self) -> uint { self.iter.indexable() }
     #[inline]
-    fn idx(&self, index: uint) -> Option<A> {
-        self.iter.idx(self.indexable() - index - 1)
+    fn idx(&mut self, index: uint) -> Option<A> {
+        let amt = self.indexable();
+        self.iter.idx(amt - index - 1)
     }
 }
 
@@ -1071,7 +1072,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<A> {
+    fn idx(&mut self, index: uint) -> Option<A> {
         let liter = self.iter.indexable();
         let lorig = self.orig.indexable();
         if lorig == 0 {
@@ -1143,7 +1144,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<A> {
+    fn idx(&mut self, index: uint) -> Option<A> {
         let len = self.a.indexable();
         if index < len {
             self.a.idx(index)
@@ -1221,7 +1222,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<(A, B)> {
+    fn idx(&mut self, index: uint) -> Option<(A, B)> {
         match self.a.idx(index) {
             None => None,
             Some(x) => match self.b.idx(index) {
@@ -1240,7 +1241,7 @@ pub struct Map<'a, A, B, T> {
 
 impl<'a, A, B, T> Map<'a, A, B, T> {
     #[inline]
-    fn do_map(&self, elt: Option<A>) -> Option<B> {
+    fn do_map(&mut self, elt: Option<A>) -> Option<B> {
         match elt {
             Some(a) => Some((self.f)(a)),
             _ => None
@@ -1276,8 +1277,9 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<B> {
-        self.do_map(self.iter.idx(index))
+    fn idx(&mut self, index: uint) -> Option<B> {
+        let elt = self.iter.idx(index);
+        self.do_map(elt)
     }
 }
 
@@ -1415,7 +1417,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<(uint, A)> {
+    fn idx(&mut self, index: uint) -> Option<(uint, A)> {
         match self.iter.idx(index) {
             Some(a) => Some((self.count + index, a)),
             _ => None,
@@ -1600,7 +1602,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<A> {
+    fn idx(&mut self, index: uint) -> Option<A> {
         if index >= self.indexable() {
             None
         } else {
@@ -1649,7 +1651,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<A> {
+    fn idx(&mut self, index: uint) -> Option<A> {
         if index >= self.n {
             None
         } else {
@@ -1799,7 +1801,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<A> {
+    fn idx(&mut self, index: uint) -> Option<A> {
         self.iter.idx(index)
     }
 }
@@ -1822,7 +1824,7 @@ pub struct Inspect<'a, A, T> {
 
 impl<'a, A, T> Inspect<'a, A, T> {
     #[inline]
-    fn do_inspect(&self, elt: Option<A>) -> Option<A> {
+    fn do_inspect(&mut self, elt: Option<A>) -> Option<A> {
         match elt {
             Some(ref a) => (self.f)(a),
             None => ()
@@ -1862,8 +1864,9 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<A> {
-        self.do_inspect(self.iter.idx(index))
+    fn idx(&mut self, index: uint) -> Option<A> {
+        let element = self.iter.idx(index);
+        self.do_inspect(element)
     }
 }
 
@@ -2164,7 +2167,7 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
     #[inline]
     fn indexable(&self) -> uint { uint::MAX }
     #[inline]
-    fn idx(&self, _: uint) -> Option<A> { Some(self.element.clone()) }
+    fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) }
 }
 
 /// Functions for lexicographical ordering of sequences.
@@ -2907,7 +2910,7 @@ fn test_random_access_inspect() {
         let xs = [1, 2, 3, 4, 5];
 
         // test .map and .inspect that don't implement Clone
-        let it = xs.iter().inspect(|_| {});
+        let mut it = xs.iter().inspect(|_| {});
         assert_eq!(xs.len(), it.indexable());
         for (i, elt) in xs.iter().enumerate() {
             assert_eq!(Some(elt), it.idx(i));
@@ -2919,7 +2922,7 @@ fn test_random_access_inspect() {
     fn test_random_access_map() {
         let xs = [1, 2, 3, 4, 5];
 
-        let it = xs.iter().map(|x| *x);
+        let mut it = xs.iter().map(|x| *x);
         assert_eq!(xs.len(), it.indexable());
         for (i, elt) in xs.iter().enumerate() {
             assert_eq!(Some(*elt), it.idx(i));
index a6b0ccf3a87251ffa12390bd3abab94f6fd27b08..cacd8d0aef91ac391fd550beb199bc7b5283d4b0 100644 (file)
@@ -235,6 +235,16 @@ impl Primitive for $T {}
 // String conversion functions and impl str -> num
 
 /// Parse a byte slice as a number in the given base.
+///
+/// Yields an `Option` because `buf` may or may not actually be parseable.
+///
+/// # Examples
+///
+/// ```rust
+/// let digits = [49,50,51,52,53,54,55,56,57];
+/// let base   = 10;
+/// let num    = std::i64::parse_bytes(digits, base);
+/// ```
 #[inline]
 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
     strconv::from_str_bytes_common(buf, radix, true, false, false,
index 9b9aee672a0f51a6ea6bb829fc35782d89ed78bb..697390a00699c20271ad761bdea61eb36389692e 100644 (file)
@@ -149,6 +149,16 @@ impl Int for $T {}
 // String conversion functions and impl str -> num
 
 /// Parse a byte slice as a number in the given base.
+///
+/// Yields an `Option` because `buf` may or may not actually be parseable.
+///
+/// # Examples
+///
+/// ```rust
+/// let digits = [49,50,51,52,53,54,55,56,57];
+/// let base   = 10;
+/// let num    = std::i64::parse_bytes(digits, base);
+/// ```
 #[inline]
 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
     strconv::from_str_bytes_common(buf, radix, false, false, false,
index 557e2043381326cc0233e713a0186f68005c5218..efbb1abacfaa9d8e60dde7b32689816a3620d56a 100644 (file)
@@ -873,9 +873,9 @@ fn test_collect() {
         assert_eq!(v, None);
 
         // test that it does not take more elements than it needs
-        let functions = [|| Some(()), || None, || fail!()];
+        let mut functions = [|| Some(()), || None, || fail!()];
 
-        let v: Option<~[()]> = collect(functions.iter().map(|f| (*f)()));
+        let v: Option<~[()]> = collect(functions.mut_iter().map(|f| (*f)()));
 
         assert_eq!(v, None);
     }
index ff6e494b948c60dfd045568c075e1e2374d733c1..5673929d5a1213629bf9f12ad7e44df6db8f7701 100644 (file)
@@ -192,7 +192,7 @@ fn clone(&self) -> Weak<T> {
     }
 }
 
-#[allow(missing_doc)]
+#[doc(hidden)]
 trait RcBoxPtr<T> {
     fn inner<'a>(&'a self) -> &'a RcBox<T>;
 
index 7080da266f6660662a7457c0a469b67349253ca4..058548eb151a26a83093cce67f87ec28983d00e2 100644 (file)
@@ -695,9 +695,9 @@ fn test_collect() {
         assert_eq!(v, Err(2));
 
         // test that it does not take more elements than it needs
-        let functions = [|| Ok(()), || Err(1), || fail!()];
+        let mut functions = [|| Ok(()), || Err(1), || fail!()];
 
-        let v: Result<~[()], int> = collect(functions.iter().map(|f| (*f)()));
+        let v: Result<~[()], int> = collect(functions.mut_iter().map(|f| (*f)()));
         assert_eq!(v, Err(1));
     }
 
@@ -715,9 +715,9 @@ fn test_fold() {
                    Err(2));
 
         // test that it does not take more elements than it needs
-        let functions = [|| Ok(()), || Err(1), || fail!()];
+        let mut functions = [|| Ok(()), || Err(1), || fail!()];
 
-        assert_eq!(fold_(functions.iter()
+        assert_eq!(fold_(functions.mut_iter()
                         .map(|f| (*f)())),
                    Err(1));
     }
index 0f3fc9c21ced01992793eb8e6415db317b205fb2..5dd148346695d8606770fb6dd762c6443f570284 100644 (file)
@@ -200,6 +200,7 @@ pub trait RtioTcpAcceptor : RtioSocket {
     fn accept(&mut self) -> IoResult<~RtioTcpStream:Send>;
     fn accept_simultaneously(&mut self) -> IoResult<()>;
     fn dont_accept_simultaneously(&mut self) -> IoResult<()>;
+    fn set_timeout(&mut self, timeout: Option<u64>);
 }
 
 pub trait RtioTcpStream : RtioSocket {
index f75b5315207ccceed4786ea57d7118e518386526..2dab0e975da3c0b4bc8bc3dbcb8ede55d571f112 100644 (file)
@@ -109,7 +109,7 @@ pub fn new() -> Task {
     /// This function is *not* meant to be abused as a "try/catch" block. This
     /// is meant to be used at the absolute boundaries of a task's lifetime, and
     /// only for that purpose.
-    pub fn run(~self, f: ||) -> ~Task {
+    pub fn run(~self, mut f: ||) -> ~Task {
         // Need to put ourselves into TLS, but also need access to the unwinder.
         // Unsafely get a handle to the task so we can continue to use it after
         // putting it in tls (so we can invoke the unwinder).
index 620baabeef53988c5dd9c7017bf2a1935a1ca817..929c47b05b923b1b18262f43c49149183b1da434 100644 (file)
@@ -212,8 +212,7 @@ fn next(&mut self) -> Option<&'a [T]> {
             return Some(self.v);
         }
 
-        let pred = &mut self.pred;
-        match self.v.iter().rposition(|x| (*pred)(x)) {
+        match self.v.iter().rposition(|x| (self.pred)(x)) {
             None => {
                 self.finished = true;
                 Some(self.v)
@@ -489,7 +488,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<&'a [T]> {
+    fn idx(&mut self, index: uint) -> Option<&'a [T]> {
         if index < self.indexable() {
             let lo = index * self.size;
             let mut hi = lo + self.size;
@@ -2101,7 +2100,7 @@ fn indexable(&self) -> uint {
     }
 
     #[inline]
-    fn idx(&self, index: uint) -> Option<&'a T> {
+    fn idx(&mut self, index: uint) -> Option<&'a T> {
         unsafe {
             if index < self.indexable() {
                 transmute(self.ptr.offset(index as int))
@@ -2138,7 +2137,8 @@ impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
     fn next(&mut self) -> Option<&'a mut [T]> {
         if self.finished { return None; }
 
-        match self.v.iter().position(|x| (self.pred)(x)) {
+        let pred = &mut self.pred;
+        match self.v.iter().position(|x| (*pred)(x)) {
             None => {
                 self.finished = true;
                 let tmp = mem::replace(&mut self.v, &mut []);
@@ -2173,7 +2173,8 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
     fn next_back(&mut self) -> Option<&'a mut [T]> {
         if self.finished { return None; }
 
-        match self.v.iter().rposition(|x| (self.pred)(x)) {
+        let pred = &mut self.pred;
+        match self.v.iter().rposition(|x| (*pred)(x)) {
             None => {
                 self.finished = true;
                 let tmp = mem::replace(&mut self.v, &mut []);
@@ -3346,7 +3347,7 @@ fn test_chunksator() {
         assert_eq!(v.chunks(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
 
         assert_eq!(v.chunks(2).rev().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
-        let it = v.chunks(2);
+        let mut it = v.chunks(2);
         assert_eq!(it.indexable(), 3);
         assert_eq!(it.idx(0).unwrap(), &[1,2]);
         assert_eq!(it.idx(1).unwrap(), &[3,4]);
index 9d91545bc126e9d9e6ca566e46eec87db166f3c4..99f1c66e70272970539cbb3df62990817b25b1b8 100644 (file)
@@ -217,7 +217,7 @@ fn connect(&self, sep: &str) -> ~str {
 /// Something that can be used to compare against a character
 pub trait CharEq {
     /// Determine if the splitter should split at the given character
-    fn matches(&self, char) -> bool;
+    fn matches(&mut self, char) -> bool;
     /// Indicate if this is only concerned about ASCII characters,
     /// which can allow for a faster implementation.
     fn only_ascii(&self) -> bool;
@@ -225,7 +225,7 @@ pub trait CharEq {
 
 impl CharEq for char {
     #[inline]
-    fn matches(&self, c: char) -> bool { *self == c }
+    fn matches(&mut self, c: char) -> bool { *self == c }
 
     #[inline]
     fn only_ascii(&self) -> bool { (*self as uint) < 128 }
@@ -233,7 +233,7 @@ fn only_ascii(&self) -> bool { (*self as uint) < 128 }
 
 impl<'a> CharEq for |char|: 'a -> bool {
     #[inline]
-    fn matches(&self, c: char) -> bool { (*self)(c) }
+    fn matches(&mut self, c: char) -> bool { (*self)(c) }
 
     #[inline]
     fn only_ascii(&self) -> bool { false }
@@ -241,16 +241,16 @@ fn only_ascii(&self) -> bool { false }
 
 impl CharEq for extern "Rust" fn(char) -> bool {
     #[inline]
-    fn matches(&self, c: char) -> bool { (*self)(c) }
+    fn matches(&mut self, c: char) -> bool { (*self)(c) }
 
     #[inline]
     fn only_ascii(&self) -> bool { false }
 }
 
-impl<'a, C: CharEq> CharEq for &'a [C] {
+impl<'a> CharEq for &'a [char] {
     #[inline]
-    fn matches(&self, c: char) -> bool {
-        self.iter().any(|m| m.matches(c))
+    fn matches(&mut self, c: char) -> bool {
+        self.iter().any(|&mut m| m.matches(c))
     }
 
     #[inline]
@@ -1981,11 +1981,11 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
-    /// assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
-    /// assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
+    /// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar")
+    /// assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar")
+    /// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar")
     /// ```
-    fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
+    fn trim_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
 
     /// Returns a string with leading `chars_to_trim` removed.
     ///
@@ -1996,11 +1996,11 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
-    /// assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
-    /// assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
+    /// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11")
+    /// assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12")
+    /// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123")
     /// ```
-    fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
+    fn trim_left_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
 
     /// Returns a string with trailing `chars_to_trim` removed.
     ///
@@ -2011,11 +2011,11 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
-    /// assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
-    /// assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
+    /// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar")
+    /// assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar")
+    /// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar")
     /// ```
-    fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
+    fn trim_right_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
 
     /// Replace all occurrences of one string with another.
     ///
@@ -2491,21 +2491,31 @@ fn trim(&self) -> &'a str {
 
     #[inline]
     fn trim_left(&self) -> &'a str {
-        self.trim_left_chars(&char::is_whitespace)
+        self.trim_left_chars(char::is_whitespace)
     }
 
     #[inline]
     fn trim_right(&self) -> &'a str {
-        self.trim_right_chars(&char::is_whitespace)
+        self.trim_right_chars(char::is_whitespace)
     }
 
     #[inline]
-    fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
-        self.trim_left_chars(to_trim).trim_right_chars(to_trim)
+    fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
+        let cur = match self.find(|c: char| !to_trim.matches(c)) {
+            None => "",
+            Some(i) => unsafe { raw::slice_bytes(*self, i, self.len()) }
+        };
+        match cur.rfind(|c: char| !to_trim.matches(c)) {
+            None => "",
+            Some(i) => {
+                let right = cur.char_range_at(i).next;
+                unsafe { raw::slice_bytes(cur, 0, right) }
+            }
+        }
     }
 
     #[inline]
-    fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
+    fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
         match self.find(|c: char| !to_trim.matches(c)) {
             None => "",
             Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
@@ -2513,7 +2523,7 @@ fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
     }
 
     #[inline]
-    fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
+    fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
         match self.rfind(|c: char| !to_trim.matches(c)) {
             None => "",
             Some(last) => {
@@ -2631,7 +2641,7 @@ fn as_bytes(&self) -> &'a [u8] {
         unsafe { cast::transmute(*self) }
     }
 
-    fn find<C: CharEq>(&self, search: C) -> Option<uint> {
+    fn find<C: CharEq>(&self, mut search: C) -> Option<uint> {
         if search.only_ascii() {
             self.bytes().position(|b| search.matches(b as char))
         } else {
@@ -2642,7 +2652,7 @@ fn find<C: CharEq>(&self, search: C) -> Option<uint> {
         }
     }
 
-    fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
+    fn rfind<C: CharEq>(&self, mut search: C) -> Option<uint> {
         if search.only_ascii() {
             self.bytes().rposition(|b| search.matches(b as char))
         } else {
@@ -3160,40 +3170,40 @@ fn test_slice_to() {
     #[test]
     fn test_trim_left_chars() {
         let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_left_chars(&v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
-        assert_eq!(" ***  *** ".trim_left_chars(& &['*', ' ']), "");
-        assert_eq!("foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
+        assert_eq!(" *** foo *** ".trim_left_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
+        assert_eq!(" ***  *** ".trim_left_chars(&['*', ' ']), "");
+        assert_eq!("foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
 
-        assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11");
-        assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12");
-        assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123");
+        assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
+        assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12");
+        assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123");
     }
 
     #[test]
     fn test_trim_right_chars() {
         let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_right_chars(&v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_right_chars(& &['*', ' ']), " *** foo");
-        assert_eq!(" ***  *** ".trim_right_chars(& &['*', ' ']), "");
-        assert_eq!(" *** foo".trim_right_chars(& &['*', ' ']), " *** foo");
+        assert_eq!(" *** foo *** ".trim_right_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_right_chars(&['*', ' ']), " *** foo");
+        assert_eq!(" ***  *** ".trim_right_chars(&['*', ' ']), "");
+        assert_eq!(" *** foo".trim_right_chars(&['*', ' ']), " *** foo");
 
-        assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar");
-        assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar");
-        assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar");
+        assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
+        assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar");
+        assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar");
     }
 
     #[test]
     fn test_trim_chars() {
         let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_chars(&v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_chars(& &['*', ' ']), "foo");
-        assert_eq!(" ***  *** ".trim_chars(& &['*', ' ']), "");
-        assert_eq!("foo".trim_chars(& &['*', ' ']), "foo");
+        assert_eq!(" *** foo *** ".trim_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_chars(&['*', ' ']), "foo");
+        assert_eq!(" ***  *** ".trim_chars(&['*', ' ']), "");
+        assert_eq!("foo".trim_chars(&['*', ' ']), "foo");
 
-        assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar");
-        assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar");
-        assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar");
+        assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
+        assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar");
+        assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar");
     }
 
     #[test]
@@ -4123,7 +4133,7 @@ fn split_unicode_ascii(b: &mut Bencher) {
     fn split_unicode_not_ascii(b: &mut Bencher) {
         struct NotAscii(char);
         impl CharEq for NotAscii {
-            fn matches(&self, c: char) -> bool {
+            fn matches(&mut self, c: char) -> bool {
                 let NotAscii(cc) = *self;
                 cc == c
             }
@@ -4148,7 +4158,7 @@ fn split_not_ascii(b: &mut Bencher) {
         struct NotAscii(char);
         impl CharEq for NotAscii {
             #[inline]
-            fn matches(&self, c: char) -> bool {
+            fn matches(&mut self, c: char) -> bool {
                 let NotAscii(cc) = *self;
                 cc == c
             }
index 610df320fa52464c2eead07b7a091c5d636b75a7..f8b3d25033c81839a49b33ebae4a59156b493304 100644 (file)
@@ -91,19 +91,17 @@ pub struct TaskBuilder {
     nocopy: Option<marker::NoCopy>,
 }
 
-/**
* Generate the base configuration for spawning a task, off of which more
* configuration methods can be chained.
- */
-pub fn task() -> TaskBuilder {
-    TaskBuilder {
-        opts: TaskOpts::new(),
-        gen_body: None,
-        nocopy: None,
+impl TaskBuilder {
    /// Generate the base configuration for spawning a task, off of which more
    /// configuration methods can be chained.
+    pub fn new() -> TaskBuilder {
+        TaskBuilder {
+            opts: TaskOpts::new(),
+            gen_body: None,
+            nocopy: None,
+        }
     }
-}
 
-impl TaskBuilder {
     /// Get a future representing the exit status of the task.
     ///
     /// Taking the value of the future will block until the child task
@@ -233,22 +231,17 @@ pub fn new() -> TaskOpts {
 /// Sets up a new task with its own call stack and schedules it to run
 /// the provided unique closure.
 ///
-/// This function is equivalent to `task().spawn(f)`.
+/// This function is equivalent to `TaskBuilder::new().spawn(f)`.
 pub fn spawn(f: proc():Send) {
-    let task = task();
-    task.spawn(f)
+    TaskBuilder::new().spawn(f)
 }
 
+/// Execute a function in another task and return either the return value of
+/// the function or an error if the task failed
+///
+/// This is equivalent to TaskBuilder::new().try
 pub fn try<T:Send>(f: proc():Send -> T) -> Result<T, ~Any:Send> {
-    /*!
-     * Execute a function in another task and return either the return value
-     * of the function or result::err.
-     *
-     * This is equivalent to task().try.
-     */
-
-    let task = task();
-    task.try(f)
+    TaskBuilder::new().try(f)
 }
 
 
@@ -298,7 +291,7 @@ fn test_unnamed_task() {
 
 #[test]
 fn test_owned_named_task() {
-    task().named("ada lovelace".to_owned()).spawn(proc() {
+    TaskBuilder::new().named("ada lovelace".to_owned()).spawn(proc() {
         with_task_name(|name| {
             assert!(name.unwrap() == "ada lovelace");
         })
@@ -307,7 +300,7 @@ fn test_owned_named_task() {
 
 #[test]
 fn test_static_named_task() {
-    task().named("ada lovelace").spawn(proc() {
+    TaskBuilder::new().named("ada lovelace").spawn(proc() {
         with_task_name(|name| {
             assert!(name.unwrap() == "ada lovelace");
         })
@@ -316,7 +309,7 @@ fn test_static_named_task() {
 
 #[test]
 fn test_send_named_task() {
-    task().named("ada lovelace".into_maybe_owned()).spawn(proc() {
+    TaskBuilder::new().named("ada lovelace".into_maybe_owned()).spawn(proc() {
         with_task_name(|name| {
             assert!(name.unwrap() == "ada lovelace");
         })
@@ -326,7 +319,7 @@ fn test_send_named_task() {
 #[test]
 fn test_run_basic() {
     let (tx, rx) = channel();
-    task().spawn(proc() {
+    TaskBuilder::new().spawn(proc() {
         tx.send(());
     });
     rx.recv();
@@ -335,7 +328,7 @@ fn test_run_basic() {
 #[test]
 fn test_with_wrapper() {
     let (tx, rx) = channel();
-    task().with_wrapper(proc(body) {
+    TaskBuilder::new().with_wrapper(proc(body) {
         let result: proc():Send = proc() {
             body();
             tx.send(());
@@ -347,12 +340,12 @@ fn test_with_wrapper() {
 
 #[test]
 fn test_future_result() {
-    let mut builder = task();
+    let mut builder = TaskBuilder::new();
     let result = builder.future_result();
     builder.spawn(proc() {});
     assert!(result.recv().is_ok());
 
-    let mut builder = task();
+    let mut builder = TaskBuilder::new();
     let result = builder.future_result();
     builder.spawn(proc() {
         fail!();
@@ -362,7 +355,7 @@ fn test_future_result() {
 
 #[test] #[should_fail]
 fn test_back_to_the_future_result() {
-    let mut builder = task();
+    let mut builder = TaskBuilder::new();
     builder.future_result();
     builder.future_result();
 }
@@ -445,7 +438,7 @@ fn test_avoid_copying_the_body_spawn() {
 #[test]
 fn test_avoid_copying_the_body_task_spawn() {
     avoid_copying_the_body(|f| {
-        let builder = task();
+        let builder = TaskBuilder::new();
         builder.spawn(proc() {
             f();
         });
@@ -471,11 +464,11 @@ fn test_child_doesnt_ref_parent() {
     fn child_no(x: uint) -> proc():Send {
         return proc() {
             if x < generations {
-                task().spawn(child_no(x+1));
+                TaskBuilder::new().spawn(child_no(x+1));
             }
         }
     }
-    task().spawn(child_no(0));
+    TaskBuilder::new().spawn(child_no(0));
 }
 
 #[test]
index c98ef880c10d5299376e93bb8fb041d9999e89cb..3d00c0ac74a6cabf340499cd2daf9440505573e2 100644 (file)
 #[cfg(test)] use task::failing;
 
 pub trait Finally<T> {
-    fn finally(&self, dtor: ||) -> T;
+    fn finally(&mut self, dtor: ||) -> T;
 }
 
 impl<'a,T> Finally<T> for ||: 'a -> T {
-    fn finally(&self, dtor: ||) -> T {
-        try_finally(&mut (), (),
-                    |_, _| (*self)(),
+    fn finally(&mut self, dtor: ||) -> T {
+        try_finally(&mut (), self,
+                    |_, f| (*f)(),
                     |_| dtor())
     }
 }
 
 impl<T> Finally<T> for fn() -> T {
-    fn finally(&self, dtor: ||) -> T {
+    fn finally(&mut self, dtor: ||) -> T {
         try_finally(&mut (), (),
                     |_, _| (*self)(),
                     |_| dtor())
@@ -145,7 +145,7 @@ fn test_fail() {
 
 #[test]
 fn test_retval() {
-    let closure: || -> int = || 10;
+    let mut closure: || -> int = || 10;
     let i = closure.finally(|| { });
     assert_eq!(i, 10);
 }
@@ -154,6 +154,6 @@ fn test_retval() {
 fn test_compact() {
     fn do_some_fallible_work() {}
     fn but_always_run_this_function() { }
-    do_some_fallible_work.finally(
-        but_always_run_this_function);
+    let mut f = do_some_fallible_work;
+    f.finally(but_always_run_this_function);
 }
index 911cd1d2eb1ccdb80036a64160363a8509a37887..930b3009042422387d79e38e8f77745e91aa8cf6 100644 (file)
@@ -445,6 +445,7 @@ pub fn wait(&self) {
 mod tests {
     use std::comm::Empty;
     use std::task;
+    use std::task::TaskBuilder;
 
     use arc::Arc;
     use super::{Mutex, Barrier, RWLock};
@@ -614,7 +615,7 @@ fn test_rw_arc() {
         let mut children = Vec::new();
         for _ in range(0, 5) {
             let arc3 = arc.clone();
-            let mut builder = task::task();
+            let mut builder = TaskBuilder::new();
             children.push(builder.future_result());
             builder.spawn(proc() {
                 let lock = arc3.read();
index 6db9954820678d942475097346953f3eb0ce40d4..510241588228ce105ba5e86abda2d487220db2ce 100644 (file)
@@ -37,7 +37,9 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                 ret_ty: Self,
                 attributes: attrs,
                 const_nonmatching: false,
-                combine_substructure: |c, s, sub| cs_clone("Clone", c, s, sub)
+                combine_substructure: combine_substructure(|c, s, sub| {
+                    cs_clone("Clone", c, s, sub)
+                }),
             }
         )
     };
index 8a877a2a7a4a35b081836018e5aace6baa9867cb..92b3788c247443c53791a8eecbb6e8480ac52d09 100644 (file)
@@ -43,7 +43,9 @@ macro_rules! md (
                 ret_ty: Literal(Path::new(vec!("bool"))),
                 attributes: attrs,
                 const_nonmatching: true,
-                combine_substructure: $f
+                combine_substructure: combine_substructure(|a, b, c| {
+                    $f(a, b, c)
+                })
             }
         } }
     );
index 2b2a490e5a403932f493f1ec4049cb94c20276e6..dd2f90cfa5fae9ac21880ad8a78513c6567d063d 100644 (file)
@@ -33,7 +33,9 @@ macro_rules! md (
                 ret_ty: Literal(Path::new(vec!("bool"))),
                 attributes: attrs,
                 const_nonmatching: false,
-                combine_substructure: |cx, span, substr| cs_op($op, $equal, cx, span, substr)
+                combine_substructure: combine_substructure(|cx, span, substr| {
+                    cs_op($op, $equal, cx, span, substr)
+                })
             }
         } }
     );
index 24e0fc73f2a3d1234e322a2c116013725d9ab1a1..b76caccffecc6095b168fcd4474987124f94bc51 100644 (file)
@@ -54,7 +54,9 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @E
                 ret_ty: nil_ty(),
                 attributes: attrs,
                 const_nonmatching: true,
-                combine_substructure: cs_total_eq_assert
+                combine_substructure: combine_substructure(|a, b, c| {
+                    cs_total_eq_assert(a, b, c)
+                })
             }
         )
     };
index c2e52f7ef7701a8a054112aab68e2c51448b2718..3ca4f9e28626380da776cee61b04e8c3a0d70cf3 100644 (file)
@@ -40,7 +40,9 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
                 ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
                 attributes: attrs,
                 const_nonmatching: false,
-                combine_substructure: cs_cmp
+                combine_substructure: combine_substructure(|a, b, c| {
+                    cs_cmp(a, b, c)
+                }),
             }
         )
     };
index 56fde41635f18befd0c29587f03121448900dd5d..062f198425b28d0ab7289608e18c26c5063e13ef 100644 (file)
@@ -52,7 +52,9 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
                                           vec!(~Self, ~Literal(Path::new_local("__E"))), true)),
                 attributes: Vec::new(),
                 const_nonmatching: true,
-                combine_substructure: decodable_substructure,
+                combine_substructure: combine_substructure(|a, b, c| {
+                    decodable_substructure(a, b, c)
+                }),
             })
     };
 
index e89e25dd26c8337eeb0d7b62688bcd0c9d34b60b..c225906ed2babafcf00398b5b991b8423cd1fcfc 100644 (file)
@@ -37,7 +37,9 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
                 ret_ty: Self,
                 attributes: attrs,
                 const_nonmatching: false,
-                combine_substructure: default_substructure
+                combine_substructure: combine_substructure(|a, b, c| {
+                    default_substructure(a, b, c)
+                })
             })
     };
     trait_def.expand(cx, mitem, item, push)
index 8fdb994ecdd80ba2142e8cf062abc35395565fe6..ec3d4e0078bc6c5c0037088705bff066048a5c97 100644 (file)
@@ -123,7 +123,9 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                            true)),
                 attributes: Vec::new(),
                 const_nonmatching: true,
-                combine_substructure: encodable_substructure,
+                combine_substructure: combine_substructure(|a, b, c| {
+                    encodable_substructure(a, b, c)
+                }),
             })
     };
 
index f5bc3319da163391ef758d4fc8ba2b07793df7e0..2b48cd58f50831b1b91a03c2489c9b514c0c4bb1 100644 (file)
@@ -177,6 +177,8 @@ fn eq(&self, other: &int) -> bool {
 
 */
 
+use std::cell::RefCell;
+
 use ast;
 use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
 use ast_util;
@@ -233,7 +235,7 @@ pub struct MethodDef<'a> {
     /// actual enum variants, i.e. can use _ => .. match.
     pub const_nonmatching: bool,
 
-    pub combine_substructure: CombineSubstructureFunc<'a>,
+    pub combine_substructure: RefCell<CombineSubstructureFunc<'a>>,
 }
 
 /// All the data about the data structure/method being derived upon.
@@ -316,6 +318,11 @@ pub enum SubstructureFields<'a> {
            &[@Expr]|: 'a
            -> @Expr;
 
+pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
+    -> RefCell<CombineSubstructureFunc<'a>> {
+    RefCell::new(f)
+}
+
 
 impl<'a> TraitDef<'a> {
     pub fn expand(&self,
@@ -508,8 +515,9 @@ fn call_substructure_method(&self,
             nonself_args: nonself_args,
             fields: fields
         };
-        (self.combine_substructure)(cx, trait_.span,
-                                    &substructure)
+        let mut f = self.combine_substructure.borrow_mut();
+        let f: &mut CombineSubstructureFunc = &mut *f;
+        (*f)(cx, trait_.span, &substructure)
     }
 
     fn get_ret_ty(&self,
index c6f0900d27bd73a90d8d6e76fa6f04b9af86e3c0..d367ae61e0b8f3e86d62e417821d0607620110eb 100644 (file)
@@ -52,7 +52,9 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                 ret_ty: nil_ty(),
                 attributes: attrs,
                 const_nonmatching: false,
-                combine_substructure: hash_substructure
+                combine_substructure: combine_substructure(|a, b, c| {
+                    hash_substructure(a, b, c)
+                })
             }
         )
     };
index 90b011d24e3eacc3b29528272f7ad8d508203f95..0a7aa591657668441b368b0ee3b0eb1d42462ad3 100644 (file)
@@ -43,7 +43,9 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                 // #[inline] liable to cause code-bloat
                 attributes: attrs.clone(),
                 const_nonmatching: false,
-                combine_substructure: |c, s, sub| cs_from("i64", c, s, sub),
+                combine_substructure: combine_substructure(|c, s, sub| {
+                    cs_from("i64", c, s, sub)
+                }),
             },
             MethodDef {
                 name: "from_u64",
@@ -58,7 +60,9 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                 // #[inline] liable to cause code-bloat
                 attributes: attrs,
                 const_nonmatching: false,
-                combine_substructure: |c, s, sub| cs_from("u64", c, s, sub),
+                combine_substructure: combine_substructure(|c, s, sub| {
+                    cs_from("u64", c, s, sub)
+                }),
             })
     };
 
index 597e0959de2df8a4a7ebeeb62580f2c2b7ce6146..23877dd29ea79d6c55e909cb7309e8ea33e2416d 100644 (file)
@@ -43,7 +43,9 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                 ret_ty: Self,
                 attributes: Vec::new(),
                 const_nonmatching: false,
-                combine_substructure: rand_substructure
+                combine_substructure: combine_substructure(|a, b, c| {
+                    rand_substructure(a, b, c)
+                })
             }
         )
     };
index 153374fbc1630d60a8547fdf62e0fc2700eb5f51..b9725361538d1fbc9500d63f640b07711ab9cab1 100644 (file)
@@ -44,7 +44,9 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
                 ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
                 attributes: Vec::new(),
                 const_nonmatching: false,
-                combine_substructure: show_substructure
+                combine_substructure: combine_substructure(|a, b, c| {
+                    show_substructure(a, b, c)
+                })
             }
         )
     };
index cbb113f15f707169479f425690151da9a1296c31..449851dd3ea5913aecc03654a5d5f5f55958c801 100644 (file)
@@ -37,7 +37,9 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                 ret_ty: Self,
                 attributes: attrs.clone(),
                 const_nonmatching: false,
-                combine_substructure: zero_substructure
+                combine_substructure: combine_substructure(|a, b, c| {
+                    zero_substructure(a, b, c)
+                })
             },
             MethodDef {
                 name: "is_zero",
@@ -47,13 +49,13 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                 ret_ty: Literal(Path::new(vec!("bool"))),
                 attributes: attrs,
                 const_nonmatching: false,
-                combine_substructure: |cx, span, substr| {
+                combine_substructure: combine_substructure(|cx, span, substr| {
                     cs_and(|cx, span, _, _| cx.span_bug(span,
                                                         "Non-matching enum \
                                                          variant in \
                                                          deriving(Zero)"),
                            cx, span, substr)
-                }
+                })
             }
         )
     };
index 758b7532acc20bafa0558dcdddf0ff7c561ab2f4..145fea18cb238d652c333cb97db19ea292ec7761 100644 (file)
@@ -60,7 +60,7 @@
 use std::os;
 use std::str;
 use std::strbuf::StrBuf;
-use std::task;
+use std::task::TaskBuilder;
 
 // to be used by rustc to compile tests in libtest
 pub mod test {
@@ -961,7 +961,7 @@ fn run_test_inner(desc: TestDesc,
             let mut reader = ChanReader::new(rx);
             let stdout = ChanWriter::new(tx.clone());
             let stderr = ChanWriter::new(tx);
-            let mut task = task::task().named(match desc.name {
+            let mut task = TaskBuilder::new().named(match desc.name {
                 DynTestName(ref name) => name.clone().into_maybe_owned(),
                 StaticTestName(name) => name.into_maybe_owned(),
             });
index b99d778c39925500d5017eb585caab3e16de5c91..5a42d2e3c59fa5ebc35243da8a278f5c06d941a0 100644 (file)
@@ -23,6 +23,7 @@
 use std::comm;
 use std::os;
 use std::task;
+use std::task::TaskBuilder;
 use std::uint;
 
 fn move_out<T>(_x: T) {}
@@ -62,7 +63,7 @@ fn run(args: &[~str]) {
     let mut worker_results = Vec::new();
     for _ in range(0u, workers) {
         let to_child = to_child.clone();
-        let mut builder = task::task();
+        let mut builder = TaskBuilder::new();
         worker_results.push(builder.future_result());
         builder.spawn(proc() {
             for _ in range(0u, size / workers) {
index af8a89cc5978ed367608d30645f2b9033380e38f..741cc4be4faed499cfbdd782e3ff1ffc23e28946 100644 (file)
@@ -18,6 +18,7 @@
 
 use std::os;
 use std::task;
+use std::task::TaskBuilder;
 use std::uint;
 
 fn move_out<T>(_x: T) {}
@@ -56,7 +57,7 @@ fn run(args: &[~str]) {
     let mut worker_results = Vec::new();
     let from_parent = if workers == 1 {
         let (to_child, from_parent) = channel();
-        let mut builder = task::task();
+        let mut builder = TaskBuilder::new();
         worker_results.push(builder.future_result());
         builder.spawn(proc() {
             for _ in range(0u, size / workers) {
@@ -70,7 +71,7 @@ fn run(args: &[~str]) {
         let (to_child, from_parent) = channel();
         for _ in range(0u, workers) {
             let to_child = to_child.clone();
-            let mut builder = task::task();
+            let mut builder = TaskBuilder::new();
             worker_results.push(builder.future_result());
             builder.spawn(proc() {
                 for _ in range(0u, size / workers) {
index 39384ce275a5f6ef91ed8412305eff2a5deadc13..0819b71853a49d6c4bb5b5ffac61d3fe6cc02697 100644 (file)
@@ -24,6 +24,7 @@
 use std::os;
 use std::result::{Ok, Err};
 use std::task;
+use std::task::TaskBuilder;
 use std::uint;
 
 fn fib(n: int) -> int {
@@ -77,7 +78,7 @@ fn stress_task(id: int) {
 fn stress(num_tasks: int) {
     let mut results = Vec::new();
     for i in range(0, num_tasks) {
-        let mut builder = task::task();
+        let mut builder = TaskBuilder::new();
         results.push(builder.future_result());
         builder.spawn(proc() {
             stress_task(i);
diff --git a/src/test/compile-fail/borrowck-call-is-borrow-issue-12224.rs b/src/test/compile-fail/borrowck-call-is-borrow-issue-12224.rs
new file mode 100644 (file)
index 0000000..002ae5a
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Ensure that invoking a closure counts as a unique immutable borrow
+
+
+type Fn<'a> = ||:'a;
+
+struct Test<'a> {
+    f: ||: 'a
+}
+
+fn call(f: |Fn|) {
+    f(|| {
+    //~^ ERROR: closure requires unique access to `f` but it is already borrowed
+        f(|| {})
+    });
+}
+
+fn test1() {
+    call(|a| {
+        a();
+    });
+}
+
+fn test2(f: &||) {
+    (*f)(); //~ ERROR: closure invocation in a `&` reference
+}
+
+fn test3(f: &mut ||) {
+    (*f)();
+}
+
+fn test4(f: &Test) {
+    (f.f)() //~ ERROR: closure invocation in a `&` reference
+}
+
+fn test5(f: &mut Test) {
+    (f.f)()
+}
+
+fn test6() {
+    let f = || {};
+    (|| {
+        f();
+    })();
+}
+
+fn test7() {
+    fn foo(_: |g: |int|, b: int|) {}
+    let f = |g: |int|, b: int| {};
+    f(|a| { //~ ERROR: cannot borrow `f` as immutable because previous closure
+        foo(f); //~ ERROR: cannot move out of captured outer variable
+    }, 3);
+}
+
+fn main() {}
index 6f4c450940e0f5b47947b87f138383acd6bd3612..f8eb9868a5b69413047261f344dfd11aeb957be9 100644 (file)
@@ -11,7 +11,6 @@
 // aux-build:macro_crate_test.rs
 // ignore-stage1
 // ignore-android
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index e5fe1891cb87825279bdd34f79b7322891b4aad5..6556d0a51f84e356f30ad0c5848dcaad72fdd296 100644 (file)
@@ -16,7 +16,7 @@ struct R<'a> {
     // This struct is needed to create the
     // otherwise infinite type of a fn that
     // accepts itself as argument:
-    c: |&R, bool|: 'a
+    c: |&mut R, bool|: 'a
 }
 
 fn innocent_looking_victim() {
@@ -28,6 +28,7 @@ fn innocent_looking_victim() {
             match x {
                 Some(ref msg) => {
                     (f.c)(f, true);
+                    //~^ ERROR: cannot borrow `*f` as mutable because
                     println!("{:?}", msg);
                 },
                 None => fail!("oops"),
@@ -36,9 +37,9 @@ fn innocent_looking_victim() {
     })
 }
 
-fn conspirator(f: |&R, bool|) {
-    let r = R {c: f};
-    f(&r, false) //~ ERROR use of moved value
+fn conspirator(f: |&mut R, bool|) {
+    let mut r = R {c: f};
+    f(&mut r, false) //~ ERROR use of moved value
 }
 
 fn main() { innocent_looking_victim() }
index 9bfc7fc34bb5b25408a99de50822b53b25afdb89..2053f81683d7a3d50582dc9276c74da5cbd5766d 100644 (file)
@@ -11,7 +11,6 @@
 // aux-build:macro_crate_test.rs
 // ignore-stage1
 // ignore-android
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 865ab7e6e84b68468e9a41f16b6a151a4a76a491..fbcdf55f1acbfca0380ef9f9861feaf62fda58e3 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index c127035bf1e45fb020e471c11223d61d0889c8c2..569b54b93fb097f346853b3e4839b7efd4dfbfc9 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 28b146635f1458366be64fbf7983372f3c7596ba..c0e2304354cc478d74260c3a32fb9c5054bbbef5 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 1f1a7ab80f96679958f609b99a4b4452bd13ed68..536594f3063111ce1c0345418322999de5bbd8b6 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index a745c227fb14dcc4ef8ccb4b43f689865cb5d8bf..8a0b0856d24de8897e0b03b22d7ffd615c5c41e1 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 04b34c85b78f7959c19dfc7bebe92f16726ad7e8..1cd4f654d2e37106192cca90b5fd161cabcdcccd 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 6b2f8067ccc44324df22e3027a2f959e7ee72721..4a6475cea96722b2998d4a7bb4120d1b3952da9b 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 23ceead0cb01e2f7f3280cc60468bc3c1fb915fe..f30af563aa6d33a66083a4927be718c94fb576e4 100644 (file)
 
 // error-pattern:task 'owned name' failed at 'test'
 
-use std::task;
+use std::task::TaskBuilder;
 
 fn main() {
-    task::task().named("owned name".to_owned()).try(proc() {
+    TaskBuilder::new().named("owned name".to_owned()).try(proc() {
         fail!("test");
         1
     }).unwrap()
index c21c6c42f6f92a066abd72c7166ee0684f3c0aef..d99c805323f3eddf6e4564b28642c24911b3d115 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:task 'send name' failed at 'test'
 
 fn main() {
-    ::std::task::task().named("send name".into_maybe_owned()).try(proc() {
+    ::std::task::TaskBuilder::new().named("send name".into_maybe_owned()).try(proc() {
         fail!("test");
         3
     }).unwrap()
index 516f9b2e1d77dfec0298aca4eba6937a6ff3b234..e0c98c5744e6ac98f6d3dae652abc3010af30984 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:task 'static name' failed at 'test'
 
 fn main() {
-    ::std::task::task().named("static name").try(proc() {
+    ::std::task::TaskBuilder::new().named("static name").try(proc() {
         fail!("test");
     }).unwrap()
 }
index 24010c7c8b18cec8e241f4ba63904159a2f91d0f..d72c82852dd72cc50f04600f041bed0b77171982 100644 (file)
@@ -12,8 +12,6 @@
 // aux-build:issue-13560-2.rs
 // aux-build:issue-13560-3.rs
 // ignore-stage1
-// ignore-android
-// ignore-cross-compile #12102
 
 // Regression test for issue #13560, the test itself is all in the dependent
 // libraries. The fail which previously failed to compile is the one numbered 3.
index f61cddace825d7613834e94f6744934294a96c85..58663bb44c7440efac69ba493d6155b520240a29 100644 (file)
@@ -10,8 +10,6 @@
 
 // aux-build:macro_crate_outlive_expansion_phase.rs
 // ignore-stage1
-// ignore-android
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 24d416a416c1e34d24b6f247714329adae3a2cdd..0c086ae99f74ebe9f140be7e66062566f8c14776 100644 (file)
@@ -10,8 +10,6 @@
 
 // aux-build:macro_crate_test.rs
 // ignore-stage1
-// ignore-android
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 
index 1700ceaec4ffe6eaea982aa37c9edc16df043d59..b8d3ab2383100010a96a9f97a6426885838c74e0 100644 (file)
 
 // aux-build:macro_crate_test.rs
 // ignore-stage1
-// ignore-android
-// force-host
-
-// You'll note that there's lots of directives above. This is a very particular
-// test in which we're both linking to a macro crate and loading macros from it.
-// This implies that both versions are the host architecture, meaning this test
-// must also be compiled with the host arch.
+// ignore-cross-compile
 //
-// because this doesn't work with that test runner, ignore-android because it
-// can't run host binaries, and force-host to make this test build as the host
-// arch.
+// macro_crate_test will not compile on a cross-compiled target because
+// libsyntax is not compiled for it.
 
 #![feature(phase)]
 
index 53ea4fbe0c35d08f263c3b2c44c48d985e0e6f45..0681ec63b9ed08c7ac61964ef6964ee490919db2 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile
 
 #![feature(phase)]
 
index 5eb6a30c015623f4c81a93d3980252b467e5cf5e..3601b6101159890dd577389652af4372d693fd5b 100644 (file)
@@ -10,7 +10,6 @@
 
 // ignore-stage1
 // ignore-pretty
-// ignore-cross-compile #12102
 
 #![feature(phase)]
 #[phase(syntax)]
index 1f5c1a556a991090a2fb486e86d2e615839cd0cc..202354b1326dd4879983949022a84391496ecefb 100644 (file)
 fn f() { }
 static bare_fns: &'static [fn()] = &[f, f];
 struct S<'a>(||:'a);
-static mut closures: &'static [S<'static>] = &[S(f), S(f)];
+static mut closures: &'static mut [S<'static>] = &mut [S(f), S(f)];
 
 pub fn main() {
     unsafe {
         for &bare_fn in bare_fns.iter() { bare_fn() }
-        for closure in closures.iter() {
-            let S(ref closure) = *closure;
+        for closure in closures.mut_iter() {
+            let S(ref mut closure) = *closure;
             (*closure)()
         }
     }
index c8735e79e502c296429ddf5290ec692f556f0cc9..f1217be3484fe99014c9f3f121ddc77e8e2693b1 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::task;
+use std::task::TaskBuilder;
 
 static generations: uint = 1024+256+128+49;
 
 fn spawn(f: proc():Send) {
-    let mut t = task::task();
+    let mut t = TaskBuilder::new();
     t.opts.stack_size = Some(32 * 1024);
     t.spawn(f);
 }
index 5a78aed5826de45dc11ab19d952848ee064c9b56..4144c8227dcd76aff637c38dbb8facadb9bec559 100644 (file)
@@ -8,23 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait OpInt<'a> { fn call<'a>(&'a self, int, int) -> int; }
+pub trait OpInt<'a> { fn call<'a>(&'a mut self, int, int) -> int; }
 
 impl<'a> OpInt<'a> for |int, int|: 'a -> int {
-    fn call(&self, a:int, b:int) -> int {
+    fn call(&mut self, a:int, b:int) -> int {
         (*self)(a, b)
     }
 }
 
-fn squarei<'a>(x: int, op: &'a OpInt) -> int { op.call(x, x) }
+fn squarei<'a>(x: int, op: &'a mut OpInt) -> int { op.call(x, x) }
 
 fn muli(x:int, y:int) -> int { x * y }
 
 pub fn main() {
-    let f = |x,y| muli(x,y);
+    let mut f = |x,y| muli(x,y);
     {
-        let g = &f;
-        let h = g as &OpInt;
+        let g = &mut f;
+        let h = g as &mut OpInt;
         squarei(3, h);
     }
 }
index df6bf767b9d0af2bacd53e300c9b6308a1f9813c..c8918fda9e79ebc493e1c91e8dc9811fca746e3b 100644 (file)
@@ -13,9 +13,9 @@
 
 // regression test for issue #10405, make sure we don't call println! too soon.
 
-use std::task;
+use std::task::TaskBuilder;
 
 pub fn main() {
-    let mut t = task::task();
+    let mut t = TaskBuilder::new();
     t.spawn(proc() ());
 }
index 275c99f99a95d8725b196f204c7c79e9ce59efc5..a78bbefed44db64eeed99d811e7c70fd9e7dbf9f 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::task;
+use std::task::TaskBuilder;
 
 pub fn main() { test00(); }
 
@@ -16,7 +17,7 @@
 
 fn test00() {
     let i: int = 0;
-    let mut builder = task::task();
+    let mut builder = TaskBuilder::new();
     let mut result = builder.future_result();
     builder.spawn(proc() {
         start(i)
index c2f6fe580fc455619ee4db4a9902eda2b1251d27..3fb91b67c9d27cf698adfa78ffb6e1ba426978ce 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-use std::task;
+use std::task::TaskBuilder;
 
 pub fn main() { println!("===== WITHOUT THREADS ====="); test00(); }
 
@@ -38,7 +38,7 @@ fn test00() {
     let mut results = Vec::new();
     while i < number_of_tasks {
         let tx = tx.clone();
-        let mut builder = task::task();
+        let mut builder = TaskBuilder::new();
         results.push(builder.future_result());
         builder.spawn({
             let i = i;
index 009b013353c8b70d64f7b7fc894e7744fee7992e..188d8288b095ea2aeb98dc4ea4554378642038bf 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-use std::task;
+use std::task::TaskBuilder;
 
 pub fn main() { test00(); }
 
@@ -24,7 +24,7 @@ fn test00() {
     let (tx, rx) = channel();
     let number_of_messages: int = 10;
 
-    let mut builder = task::task();
+    let mut builder = TaskBuilder::new();
     let result = builder.future_result();
     builder.spawn(proc() {
         test00_start(&tx, number_of_messages);
index 26f9b2ea6b7b438895d75e8cc5ae7a274823a5ee..68db134419a5a403540a9cfa304a4e6cb30932b8 100644 (file)
@@ -29,7 +29,7 @@ fn start(argc: int, argv: **u8) -> int {
 }
 
 macro_rules! iotest (
-    { fn $name:ident() $b:block $($a:attr)* } => (
+    { fn $name:ident() $b:block $(#[$a:meta])* } => (
         mod $name {
             #![allow(unused_imports)]
 
@@ -40,8 +40,8 @@ mod $name {
 
             fn f() $b
 
-            $($a)* #[test] fn green() { f() }
-            $($a)* #[test] fn native() {
+            $(#[$a])* #[test] fn green() { f() }
+            $(#[$a])* #[test] fn native() {
                 use native;
                 let (tx, rx) = channel();
                 native::task::spawn(proc() { tx.send(f()) });
@@ -76,7 +76,7 @@ fn f() $b
         }
     }
     fail!("never timed out!");
-})
+} #[ignore(cfg(target_os = "freebsd"))])
 
 iotest!(fn timeout_success() {
     let addr = next_test_ip4();
index 063ffed3151276ff931db5e6ed78bae0040f140c..0c38abb20fc48564019840ee9baac71877d697e6 100644 (file)
@@ -22,7 +22,7 @@
 use std::io::net::ip::{Ipv4Addr, SocketAddr};
 use std::io::net::tcp::{TcpListener, TcpStream};
 use std::io::{Acceptor, Listener};
-use std::task;
+use std::task::TaskBuilder;
 
 #[start]
 fn start(argc: int, argv: **u8) -> int {
@@ -61,7 +61,7 @@ fn main() {
     let (tx, rx) = channel();
     for _ in range(0, 1000) {
         let tx = tx.clone();
-        let mut builder = task::task();
+        let mut builder = TaskBuilder::new();
         builder.opts.stack_size = Some(32 * 1024);
         builder.spawn(proc() {
             match TcpStream::connect(addr) {
index bd44bdd51cd85bfe3513b5ec0a7ce4761270f42c..2662a6c6568b9834b25e333f201b629427c03632 100644 (file)
@@ -9,9 +9,10 @@
 // except according to those terms.
 
 use std::task;
+use std::task::TaskBuilder;
 
 pub fn main() {
-    let mut builder = task::task();
+    let mut builder = TaskBuilder::new();
     let mut result = builder.future_result();
     builder.spawn(child);
     println!("1");
index 14ba368bdfad6231438d420a35f9a4cb3541565c..8c5504725bb483e9e13a8f2ee40d1f118f7e75a4 100644 (file)
@@ -9,9 +9,10 @@
 // except according to those terms.
 
 use std::task;
+use std::task::TaskBuilder;
 
 pub fn main() {
-    let mut builder = task::task();
+    let mut builder = TaskBuilder::new();
     let mut result = builder.future_result();
     builder.spawn(child);
     println!("1");