]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #13711 : alexcrichton/rust/snapshots, r=brson
authorbors <bors@rust-lang.org>
Fri, 25 Apr 2014 01:26:15 +0000 (18:26 -0700)
committerbors <bors@rust-lang.org>
Fri, 25 Apr 2014 01:26:15 +0000 (18:26 -0700)
These are the first successful snapshots after the LLVM upgrade, built with LLVM
that requires C++11

117 files changed:
src/compiletest/compiletest.rs
src/compiletest/runtest.rs
src/etc/vim/indent/rust.vim
src/libfourcc/lib.rs
src/libnative/io/c_win32.rs
src/libnative/io/net.rs
src/libnative/io/timer_win32.rs
src/librustc/back/link.rs
src/librustc/driver/driver.rs
src/librustc/front/config.rs
src/librustc/lib.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/gather_loans/lifetime.rs
src/librustc/middle/borrowck/gather_loans/restrictions.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/kind.rs
src/librustc/middle/lint.rs
src/librustc/middle/moves.rs
src/librustc/middle/privacy.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/mod.rs
src/librustc/middle/trans/write_guard.rs [deleted file]
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustdoc/clean.rs
src/librustuv/async.rs
src/librustuv/file.rs
src/librustuv/idle.rs
src/librustuv/net.rs
src/librustuv/queue.rs
src/librustuv/timer.rs
src/librustuv/tty.rs
src/librustuv/uvio.rs
src/librustuv/uvll.rs
src/libstd/hash/sip.rs
src/libstd/io/fs.rs
src/libstd/io/net/tcp.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/mod.rs
src/libstd/rc.rs
src/libstd/rt/args.rs
src/libstd/rt/rtio.rs
src/libstd/task.rs
src/libsync/lock.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map.rs
src/libsyntax/ast_util.rs
src/libsyntax/ext/build.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/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libtest/lib.rs
src/libuv
src/rt/libuv-auto-clean-trigger
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/bench/msgsend-pipes-shared.rs
src/test/bench/msgsend-pipes.rs
src/test/bench/shootout-pfib.rs
src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-preserve-box-in-field.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-preserve-box-in-uniq.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-preserve-box.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-preserve-cond-box.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-preserve-expl-deref.rs [new file with mode: 0644]
src/test/compile-fail/lint-directives-on-use-items-issue-10534.rs [new file with mode: 0644]
src/test/compile-fail/method-call-err-msg.rs [new file with mode: 0644]
src/test/compile-fail/regions-appearance-constraint.rs [new file with mode: 0644]
src/test/compile-fail/regions-infer-borrow-scope-too-big.rs
src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs
src/test/compile-fail/struct-field-assignability.rs [new file with mode: 0644]
src/test/compile-fail/unsized5.rs
src/test/compile-fail/unsized6.rs [new file with mode: 0644]
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-make/error-writing-dependencies/Makefile [new file with mode: 0644]
src/test/run-make/error-writing-dependencies/foo.rs [new file with mode: 0644]
src/test/run-make/weird-output-filenames/Makefile [new file with mode: 0644]
src/test/run-make/weird-output-filenames/foo.rs [new file with mode: 0644]
src/test/run-pass/borrowck-preserve-box-in-field.rs [deleted file]
src/test/run-pass/borrowck-preserve-box-in-uniq.rs [deleted file]
src/test/run-pass/borrowck-preserve-box.rs [deleted file]
src/test/run-pass/borrowck-preserve-cond-box.rs [deleted file]
src/test/run-pass/borrowck-preserve-expl-deref.rs [deleted file]
src/test/run-pass/cfg-match-arm.rs [new file with mode: 0644]
src/test/run-pass/issue-2190-1.rs
src/test/run-pass/regions-appearance-constraint.rs [deleted file]
src/test/run-pass/spawning-with-debug.rs
src/test/run-pass/struct-field-assignability.rs [deleted file]
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-stress.rs
src/test/run-pass/yield.rs
src/test/run-pass/yield1.rs

index cae6c2b656d6542323eeec7fa74d22f9f4434e2b..2e287135dc2643e321c490efa04bc44742929aee 100644 (file)
@@ -267,7 +267,8 @@ pub fn test_opts(config: &config) -> test::TestOpts {
         ratchet_metrics: config.ratchet_metrics.clone(),
         ratchet_noise_percent: config.ratchet_noise_percent.clone(),
         save_metrics: config.save_metrics.clone(),
-        test_shard: config.test_shard.clone()
+        test_shard: config.test_shard.clone(),
+        nocapture: false,
     }
 }
 
index dd246cf611444b7c64c755edcb2a21cc9fd5b965..9ce81c5bae53d9915c9e04d7394799c2d392d838 100644 (file)
@@ -955,6 +955,7 @@ fn maybe_dump_to_stdout(config: &config, out: &str, err: &str) {
 fn fatal_ProcRes(err: ~str, proc_res: &ProcRes) -> ! {
     print!("\n\
 error: {}\n\
+status: {}\n\
 command: {}\n\
 stdout:\n\
 ------------------------------------------\n\
@@ -965,7 +966,8 @@ fn fatal_ProcRes(err: ~str, proc_res: &ProcRes) -> ! {
 {}\n\
 ------------------------------------------\n\
 \n",
-             err, proc_res.cmdline, proc_res.stdout, proc_res.stderr);
+             err, proc_res.status, proc_res.cmdline, proc_res.stdout,
+             proc_res.stderr);
     fail!();
 }
 
index f7ac357b23a7fe53257bbc6e21eb92ac2dfc4fb7..54094a741196747ce38476866bd9f2a753bdcb2b 100644 (file)
@@ -105,7 +105,7 @@ function GetRustIndent(lnum)
        if prevline[len(prevline) - 1] == ","
                                \ && s:get_line_trimmed(a:lnum) !~ "^\\s*[\\[\\]{}]"
                                \ && prevline !~ "^\\s*fn\\s"
-                               \ && prevline !~ "\\([^\\(\\)]\+,$"
+                               \ && prevline !~ "([^()]\\+,$"
                " Oh ho! The previous line ended in a comma! I bet cindent will try to
                " take this too far... For now, let's normally use the previous line's
                " indent.
index 50cdd6cedc23c0683dad05e36603db338234e211..fe0b6bcfd0f0afea41e730bcaa0fa77a739551c2 100644 (file)
@@ -91,7 +91,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) ->
 
     let s = match expr.node {
         // expression is a literal
-        ast::ExprLit(lit) => match lit.node {
+        ast::ExprLit(ref lit) => match lit.node {
             // string literal
             ast::LitStr(ref s, _) => {
                 if s.get().char_len() != 4 {
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 b7842936af3b0ea22a592881aa13d86d6ff6e89f..f8ed6bdce95a6804296e4dc6aa61d381eebf5ab0 100644 (file)
@@ -60,7 +60,7 @@ pub fn llvm_err(sess: &Session, msg: ~str) -> ! {
         if cstr == ptr::null() {
             sess.fatal(msg);
         } else {
-            let err = CString::new(cstr, false);
+            let err = CString::new(cstr, true);
             let err = str::from_utf8_lossy(err.as_bytes());
             sess.fatal(msg + ": " + err.as_slice());
         }
@@ -516,7 +516,10 @@ unsafe fn populate_llvm_passes(fpm: lib::llvm::PassManagerRef,
 
 pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
     match attr::find_crateid(attrs) {
-        None => from_str(out_filestem).unwrap(),
+        None => from_str(out_filestem).unwrap_or_else(|| {
+            let mut s = out_filestem.chars().filter(|c| c.is_XID_continue());
+            from_str(s.collect::<~str>()).or(from_str("rust-out")).unwrap()
+        }),
         Some(s) => s,
     }
 }
index 95ee250e24c1f080eacbc9879419be5490112ec3..e4ace2a2b9594fda98d2d2b7d4a90145dc22f124 100644 (file)
@@ -346,8 +346,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
     time(time_passes, "effect checking", (), |_|
          middle::effect::check_crate(&ty_cx, krate));
 
-    let middle::moves::MoveMaps {moves_map, moved_variables_set,
-                                 capture_map} =
+    let middle::moves::MoveMaps {moves_map, capture_map} =
         time(time_passes, "compute moves", (), |_|
              middle::moves::compute_moves(&ty_cx, krate));
 
@@ -357,14 +356,11 @@ pub fn phase_3_run_analysis_passes(sess: Session,
     time(time_passes, "liveness checking", (), |_|
          middle::liveness::check_crate(&ty_cx, &capture_map, krate));
 
-    let root_map =
-        time(time_passes, "borrow checking", (), |_|
-             middle::borrowck::check_crate(&ty_cx, &moves_map,
-                                           &moved_variables_set,
-                                           &capture_map, krate));
+    time(time_passes, "borrow checking", (), |_|
+         middle::borrowck::check_crate(&ty_cx, &moves_map,
+                                       &capture_map, krate));
 
     drop(moves_map);
-    drop(moved_variables_set);
 
     time(time_passes, "kind checking", (), |_|
          kind::check_crate(&ty_cx, krate));
@@ -389,7 +385,6 @@ pub fn phase_3_run_analysis_passes(sess: Session,
         exported_items: exported_items,
         public_items: public_items,
         maps: astencode::Maps {
-            root_map: root_map,
             capture_map: RefCell::new(capture_map)
         },
         reachable: reachable_map
@@ -493,7 +488,7 @@ pub fn stop_after_phase_5(sess: &Session) -> bool {
 fn write_out_deps(sess: &Session,
                   input: &Input,
                   outputs: &OutputFilenames,
-                  krate: &ast::Crate) -> io::IoResult<()> {
+                  krate: &ast::Crate) {
     let id = link::find_crate_id(krate.attrs.as_slice(), outputs.out_filestem);
 
     let mut out_filenames = Vec::new();
@@ -522,28 +517,34 @@ fn write_out_deps(sess: &Session,
             StrInput(..) => {
                 sess.warn("can not write --dep-info without a filename \
                            when compiling stdin.");
-                return Ok(());
+                return
             },
         },
-        _ => return Ok(()),
+        _ => return,
     };
 
-    // Build a list of files used to compile the output and
-    // write Makefile-compatible dependency rules
-    let files: Vec<~str> = sess.codemap().files.borrow()
-                               .iter().filter_map(|fmap| {
-                                    if fmap.is_real_file() {
-                                        Some(fmap.name.clone())
-                                    } else {
-                                        None
-                                    }
-                                }).collect();
-    let mut file = try!(io::File::create(&deps_filename));
-    for path in out_filenames.iter() {
-        try!(write!(&mut file as &mut Writer,
-                      "{}: {}\n\n", path.display(), files.connect(" ")));
+    let result = (|| {
+        // Build a list of files used to compile the output and
+        // write Makefile-compatible dependency rules
+        let files: Vec<~str> = sess.codemap().files.borrow()
+                                   .iter().filter(|fmap| fmap.is_real_file())
+                                   .map(|fmap| fmap.name.clone())
+                                   .collect();
+        let mut file = try!(io::File::create(&deps_filename));
+        for path in out_filenames.iter() {
+            try!(write!(&mut file as &mut Writer,
+                          "{}: {}\n\n", path.display(), files.connect(" ")));
+        }
+        Ok(())
+    })();
+
+    match result {
+        Ok(()) => {}
+        Err(e) => {
+            sess.fatal(format!("error writing dependencies to `{}`: {}",
+                               deps_filename.display(), e));
+        }
     }
-    Ok(())
 }
 
 pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
@@ -567,7 +568,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
                                                                          krate, &id);
             (outputs, expanded_crate, ast_map)
         };
-        write_out_deps(&sess, input, &outputs, &expanded_crate).unwrap();
+        write_out_deps(&sess, input, &outputs, &expanded_crate);
 
         if stop_after_phase_2(&sess) { return; }
 
index 888a8f6bd8d856feb69273ed9f0c70e6c3d2773d..8dcc97c936cbbbb53cc5d08ab226bfb7251b7640 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -36,6 +36,9 @@ fn fold_foreign_mod(&mut self, foreign_mod: &ast::ForeignMod) -> ast::ForeignMod
     fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
         fold_item_underscore(self, item)
     }
+    fn fold_expr(&mut self, expr: @ast::Expr) -> @ast::Expr {
+        fold_expr(self, expr)
+    }
 }
 
 pub fn strip_items(krate: ast::Crate,
@@ -189,6 +192,24 @@ fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
     })
 }
 
+fn fold_expr(cx: &mut Context, expr: @ast::Expr) -> @ast::Expr {
+    let expr = match expr.node {
+        ast::ExprMatch(ref m, ref arms) => {
+            let arms = arms.iter()
+                .filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
+                .map(|a| a.clone())
+                .collect();
+            @ast::Expr {
+                id: expr.id,
+                span: expr.span.clone(),
+                node: ast::ExprMatch(m.clone(), arms),
+            }
+        }
+        _ => expr.clone()
+    };
+    fold::noop_fold_expr(expr, cx)
+}
+
 fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
     return (cx.in_cfg)(item.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 08133a8b69e40f76af295438ad5663b649674000..7f3757c478c02e3b87949b292d82077b563c097d 100644 (file)
@@ -54,7 +54,6 @@
 
 // Auxiliary maps of things to be encoded
 pub struct Maps {
-    pub root_map: middle::borrowck::root_map,
     pub capture_map: RefCell<middle::moves::CaptureMap>,
 }
 
index a27fe5cec225260b32d44ec880199c97c330e4d2..4c17ddbb31f8604a44180371afa1d0e2b3d62ee8 100644 (file)
@@ -65,9 +65,6 @@ struct GuaranteeLifetimeContext<'a> {
 }
 
 impl<'a> GuaranteeLifetimeContext<'a> {
-    fn tcx(&self) -> &'a ty::ctxt {
-        self.bccx.tcx
-    }
 
     fn check(&self, cmt: &mc::cmt, discr_scope: Option<ast::NodeId>) -> R {
         //! Main routine. Walks down `cmt` until we find the "guarantor".
@@ -90,29 +87,10 @@ fn check(&self, cmt: &mc::cmt, discr_scope: Option<ast::NodeId>) -> R {
                 Ok(())
             }
 
-            mc::cat_deref(ref base, derefs, mc::GcPtr) => {
-                let base_scope = self.scope(base);
-
-                // L-Deref-Managed-Imm-User-Root
-                let omit_root =
-                    self.bccx.is_subregion_of(self.loan_region, base_scope) &&
-                    self.is_rvalue_or_immutable(base) &&
-                    !self.is_moved(base);
-
-                if !omit_root {
-                    // L-Deref-Managed-Imm-Compiler-Root
-                    // L-Deref-Managed-Mut-Compiler-Root
-                    self.check_root(cmt, base, derefs, discr_scope)
-                } else {
-                    debug!("omitting root, base={}, base_scope={:?}",
-                           base.repr(self.tcx()), base_scope);
-                    Ok(())
-                }
-            }
-
             mc::cat_downcast(ref base) |
             mc::cat_deref(ref base, _, mc::OwnedPtr) |     // L-Deref-Send
-            mc::cat_interior(ref base, _) => {             // L-Field
+            mc::cat_interior(ref base, _) |                // L-Field
+            mc::cat_deref(ref base, _, mc::GcPtr) => {
                 self.check(base, discr_scope)
             }
 
@@ -174,74 +152,6 @@ fn check(&self, cmt: &mc::cmt, discr_scope: Option<ast::NodeId>) -> R {
         }
     }
 
-    fn is_rvalue_or_immutable(&self,
-                              cmt: &mc::cmt) -> bool {
-        //! We can omit the root on an `@T` value if the location
-        //! that holds the box is either (1) an rvalue, in which case
-        //! it is in a non-user-accessible temporary, or (2) an immutable
-        //! lvalue.
-
-        cmt.mutbl.is_immutable() || match cmt.guarantor().cat {
-            mc::cat_rvalue(..) => true,
-            _ => false
-        }
-    }
-
-    fn check_root(&self,
-                  cmt_deref: &mc::cmt,
-                  cmt_base: &mc::cmt,
-                  derefs: uint,
-                  discr_scope: Option<ast::NodeId>) -> R {
-        debug!("check_root(cmt_deref={}, cmt_base={}, derefs={:?}, \
-                discr_scope={:?})",
-               cmt_deref.repr(self.tcx()),
-               cmt_base.repr(self.tcx()),
-               derefs,
-               discr_scope);
-
-        // Make sure that the loan does not exceed the maximum time
-        // that we can root the value, dynamically.
-        let root_region = ty::ReScope(self.root_scope_id);
-        if !self.bccx.is_subregion_of(self.loan_region, root_region) {
-            return Err(self.report_error(
-                err_out_of_root_scope(root_region, self.loan_region)));
-        }
-
-        // Extract the scope id that indicates how long the rooting is required
-        let root_scope = match self.loan_region {
-            ty::ReScope(id) => id,
-            _ => {
-                // the check above should fail for anything is not ReScope
-                self.bccx.tcx.sess.span_bug(
-                    cmt_base.span,
-                    format!("cannot issue root for scope region: {:?}",
-                         self.loan_region));
-            }
-        };
-
-        // If inside of a match arm, expand the rooting to the entire
-        // match. See the detailed discussion in `check()` above.
-        let root_scope = match discr_scope {
-            None => root_scope,
-            Some(id) => {
-                if self.bccx.is_subscope_of(root_scope, id) {
-                    id
-                } else {
-                    root_scope
-                }
-            }
-        };
-
-        // Add a record of what is required
-        let rm_key = root_map_key {id: cmt_deref.id, derefs: derefs};
-        let root_info = RootInfo {scope: root_scope};
-
-        self.bccx.root_map.borrow_mut().insert(rm_key, root_info);
-
-        debug!("root_key: {:?} root_info: {:?}", rm_key, root_info);
-        Ok(())
-    }
-
     fn check_scope(&self, max_scope: ty::Region) -> R {
         //! Reports an error if `loan_region` is larger than `valid_scope`
 
@@ -252,32 +162,6 @@ fn check_scope(&self, max_scope: ty::Region) -> R {
         }
     }
 
-    fn is_moved(&self, cmt: &mc::cmt) -> bool {
-        //! True if `cmt` is something that is potentially moved
-        //! out of the current stack frame.
-
-        match cmt.guarantor().cat {
-            mc::cat_local(id) |
-            mc::cat_arg(id) => {
-                self.bccx.moved_variables_set.contains(&id)
-            }
-            mc::cat_rvalue(..) |
-            mc::cat_static_item |
-            mc::cat_copied_upvar(..) |
-            mc::cat_deref(..) |
-            mc::cat_upvar(..) => {
-                false
-            }
-            ref r @ mc::cat_downcast(..) |
-            ref r @ mc::cat_interior(..) |
-            ref r @ mc::cat_discr(..) => {
-                self.tcx().sess.span_bug(
-                    cmt.span,
-                    format!("illegal guarantor category: {:?}", r));
-            }
-        }
-    }
-
     fn scope(&self, cmt: &mc::cmt) -> ty::Region {
         //! Returns the maximal region scope for the which the
         //! lvalue `cmt` is guaranteed to be valid without any
index de4ce84fb0a59fd655886e49f8d472dbaba98d9b..4d0249a3011bd8369a2625b1c1d36baab76ff4db 100644 (file)
@@ -101,12 +101,18 @@ fn restrict(&self,
                 self.extend(result, cmt.mutbl, LpInterior(i), restrictions)
             }
 
-            mc::cat_deref(cmt_base, _, pk @ mc::OwnedPtr) => {
+            mc::cat_deref(cmt_base, _, pk @ mc::OwnedPtr) |
+            mc::cat_deref(cmt_base, _, pk @ mc::GcPtr) => {
                 // R-Deref-Send-Pointer
                 //
                 // When we borrow the interior of an owned pointer, we
                 // cannot permit the base to be mutated, because that
                 // would cause the unique pointer to be freed.
+                //
+                // For a managed pointer, the rules are basically the
+                // same, because this could be the last ref.
+                // Eventually we should make these non-special and
+                // just rely on Deref<T> implementation.
                 let result = self.restrict(
                     cmt_base,
                     restrictions | RESTR_MUTATE);
@@ -134,11 +140,6 @@ fn restrict(&self,
                 Safe
             }
 
-            mc::cat_deref(_, _, mc::GcPtr) => {
-                // R-Deref-Imm-Managed
-                Safe
-            }
-
             mc::cat_deref(cmt_base, _, pk @ mc::BorrowedPtr(ty::MutBorrow, lt)) => {
                 // R-Deref-Mut-Borrowed
                 if !self.bccx.is_subregion_of(self.loan_region, lt) {
index 3de64f151917e24436ec0f05671aa25959c9f276..1af0e48c46dd678d5dfa71f24e75250e8c407c90 100644 (file)
 use util::nodemap::{NodeMap, NodeSet};
 use util::ppaux::{note_and_explain_region, Repr, UserString};
 
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 use std::ops::{BitOr, BitAnd};
 use std::rc::Rc;
 use std::strbuf::StrBuf;
-use collections::HashMap;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util;
@@ -77,21 +76,39 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
 
 pub fn check_crate(tcx: &ty::ctxt,
                    moves_map: &NodeSet,
-                   moved_variables_set: &NodeSet,
                    capture_map: &moves::CaptureMap,
-                   krate: &ast::Crate)
-                   -> root_map {
+                   krate: &ast::Crate) {
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
         moves_map: moves_map,
-        moved_variables_set: moved_variables_set,
         capture_map: capture_map,
-        root_map: RefCell::new(HashMap::new())
+        stats: @BorrowStats {
+            loaned_paths_same: Cell::new(0),
+            loaned_paths_imm: Cell::new(0),
+            stable_paths: Cell::new(0),
+            guaranteed_paths: Cell::new(0),
+        }
     };
 
     visit::walk_crate(&mut bccx, krate, ());
 
-    return bccx.root_map.unwrap();
+    if tcx.sess.borrowck_stats() {
+        println!("--- borrowck stats ---");
+        println!("paths requiring guarantees: {}",
+                 bccx.stats.guaranteed_paths.get());
+        println!("paths requiring loans     : {}",
+                 make_stat(&bccx, bccx.stats.loaned_paths_same.get()));
+        println!("paths requiring imm loans : {}",
+                 make_stat(&bccx, bccx.stats.loaned_paths_imm.get()));
+        println!("stable paths              : {}",
+                 make_stat(&bccx, bccx.stats.stable_paths.get()));
+    }
+
+    fn make_stat(bccx: &BorrowckCtxt, stat: uint) -> ~str {
+        let stat_f = stat as f64;
+        let total = bccx.stats.guaranteed_paths.get() as f64;
+        format!("{} ({:.0f}%)", stat  , stat_f * 100.0 / total)
+    }
 }
 
 fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
@@ -148,28 +165,17 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
 pub struct BorrowckCtxt<'a> {
     tcx: &'a ty::ctxt,
     moves_map: &'a NodeSet,
-    moved_variables_set: &'a NodeSet,
     capture_map: &'a moves::CaptureMap,
-    root_map: RefCell<root_map>,
+
+    // Statistics:
+    stats: @BorrowStats
 }
 
-// The keys to the root map combine the `id` of the deref expression
-// with the number of types that it is *autodereferenced*. So, for
-// example, imagine I have a variable `x: @@@T` and an expression
-// `(*x).f`.  This will have 3 derefs, one explicit and then two
-// autoderefs. These are the relevant `root_map_key` values that could
-// appear:
-//
-//    {id:*x, derefs:0} --> roots `x` (type: @@@T, due to explicit deref)
-//    {id:*x, derefs:1} --> roots `*x` (type: @@T, due to autoderef #1)
-//    {id:*x, derefs:2} --> roots `**x` (type: @T, due to autoderef #2)
-//
-// Note that there is no entry with derefs:3---the type of that expression
-// is T, which is not a box.
-#[deriving(Eq, TotalEq, Hash)]
-pub struct root_map_key {
-    pub id: ast::NodeId,
-    pub derefs: uint
+pub struct BorrowStats {
+    loaned_paths_same: Cell<uint>,
+    loaned_paths_imm: Cell<uint>,
+    stable_paths: Cell<uint>,
+    guaranteed_paths: Cell<uint>,
 }
 
 pub type BckResult<T> = Result<T, BckError>;
@@ -318,31 +324,6 @@ fn repr(&self, _tcx: &ty::ctxt) -> ~str {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-// Rooting of managed boxes
-//
-// When we borrow the interior of a managed box, it is sometimes
-// necessary to *root* the box, meaning to stash a copy of the box
-// somewhere that the garbage collector will find it. This ensures
-// that the box is not collected for the lifetime of the borrow.
-//
-// As part of this rooting, we sometimes also freeze the box at
-// runtime, meaning that we dynamically detect when the box is
-// borrowed in incompatible ways.
-//
-// Both of these actions are driven through the `root_map`, which maps
-// from a node to the dynamic rooting action that should be taken when
-// that node executes. The node is identified through a
-// `root_map_key`, which pairs a node-id and a deref count---the
-// problem is that sometimes the box that needs to be rooted is only
-// uncovered after a certain number of auto-derefs.
-
-pub struct RootInfo {
-    pub scope: ast::NodeId,
-}
-
-pub type root_map = HashMap<root_map_key, RootInfo>;
-
 ///////////////////////////////////////////////////////////////////////////
 // Errors
 
@@ -350,7 +331,6 @@ pub struct RootInfo {
 #[deriving(Eq)]
 pub enum bckerr_code {
     err_mutbl,
-    err_out_of_root_scope(ty::Region, ty::Region), // superscope, subscope
     err_out_of_scope(ty::Region, ty::Region), // superscope, subscope
     err_borrowed_pointer_too_short(
         ty::Region, ty::Region, RestrictionSet), // loan, ptr
@@ -636,9 +616,6 @@ pub fn bckerr_to_str(&self, err: &BckError) -> ~str {
                     }
                 }
             }
-            err_out_of_root_scope(..) => {
-                format!("cannot root managed value long enough")
-            }
             err_out_of_scope(..) => {
                 let msg = match opt_loan_path(&err.cmt) {
                     None => format!("borrowed value"),
@@ -718,19 +695,6 @@ pub fn note_and_explain_bckerr(&self, err: BckError) {
         match code {
             err_mutbl(..) => { }
 
-            err_out_of_root_scope(super_scope, sub_scope) => {
-                note_and_explain_region(
-                    self.tcx,
-                    "managed value would have to be rooted for ",
-                    sub_scope,
-                    "...");
-                note_and_explain_region(
-                    self.tcx,
-                    "...but can only be rooted for ",
-                    super_scope,
-                    "");
-            }
-
             err_out_of_scope(super_scope, sub_scope) => {
                 note_and_explain_region(
                     self.tcx,
index cd3ab100e55c23f71fbe172296d6fb335b14d703..6a2262aeaef9f10c5276324bd961ba44d2cae006 100644 (file)
@@ -24,7 +24,6 @@
 use syntax::{ast, ast_map, ast_util};
 
 use std::cell::RefCell;
-use collections::HashMap;
 use std::rc::Rc;
 
 //
@@ -127,7 +126,6 @@ fn variant_expr(variants: &[ast::P<ast::Variant>], id: ast::NodeId) -> Option<@E
             None => {}
         }
         let maps = astencode::Maps {
-            root_map: HashMap::new(),
             capture_map: RefCell::new(NodeMap::new())
         };
         let e = match csearch::maybe_get_item_ast(tcx, enum_def,
@@ -166,7 +164,6 @@ pub fn lookup_const_by_id(tcx: &ty::ctxt, def_id: ast::DefId)
             None => {}
         }
         let maps = astencode::Maps {
-            root_map: HashMap::new(),
             capture_map: RefCell::new(NodeMap::new())
         };
         let e = match csearch::maybe_get_item_ast(tcx, def_id,
index e6c885e56f176e47fc084fffb223df16309912af..02f9309bca2459f5aba154caf6618f77172aa993 100644 (file)
@@ -20,7 +20,7 @@
 use syntax::attr;
 use syntax::codemap::Span;
 use syntax::owned_slice::OwnedSlice;
-use syntax::print::pprust::expr_to_str;
+use syntax::print::pprust::{expr_to_str,path_to_str};
 use syntax::{visit,ast_util};
 use syntax::visit::Visitor;
 
@@ -63,9 +63,14 @@ fn visit_fn(&mut self, fk: &visit::FnKind, fd: &FnDecl,
     fn visit_ty(&mut self, t: &Ty, _: ()) {
         check_ty(self, t);
     }
+
     fn visit_item(&mut self, i: &Item, _: ()) {
         check_item(self, i);
     }
+
+    fn visit_pat(&mut self, p: &Pat, _: ()) {
+        check_pat(self, p);
+    }
 }
 
 pub fn check_crate(tcx: &ty::ctxt,
@@ -551,3 +556,38 @@ fn is_ReScope(r: ty::Region) -> bool {
         }
     }
 }
+
+// Ensure that `ty` has a statically known size (i.e., it has the `Sized` bound).
+fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: ~str, sp: Span) {
+    if !ty::type_is_sized(tcx, ty) {
+        tcx.sess.span_err(sp, format!("variable `{}` has dynamically sized type `{}`",
+                                      name, ty_to_str(tcx, ty)));
+    }
+}
+
+// Check that any variables in a pattern have types with statically known size.
+fn check_pat(cx: &mut Context, pat: &Pat) {
+    let var_name = match pat.node {
+        PatWild => Some("_".to_owned()),
+        PatIdent(_, ref path, _) => Some(path_to_str(path)),
+        _ => None
+    };
+
+    match var_name {
+        Some(name) => {
+            let types = cx.tcx.node_types.borrow();
+            let ty = types.find(&(pat.id as uint));
+            match ty {
+                Some(ty) => {
+                    debug!("kind: checking sized-ness of variable {}: {}",
+                           name, ty_to_str(cx.tcx, *ty));
+                    check_sized(cx.tcx, *ty, name, pat.span);
+                }
+                None => {} // extern fn args
+            }
+        }
+        None => {}
+    }
+
+    visit::walk_pat(cx, pat, ());
+}
index 05a225d8953fce281575459cf42eb0ea1b48ef17..51aafb90ac6569f73b66b359fb5cfc3761b338e7 100644 (file)
@@ -1638,6 +1638,9 @@ fn visit_foreign_item(&mut self, it: &ast::ForeignItem, _: ()) {
     fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
         self.with_lint_attrs(i.attrs.as_slice(), |cx| {
             check_attrs_usage(cx, i.attrs.as_slice());
+
+            cx.visit_ids(|v| v.visit_view_item(i, ()));
+
             visit::walk_view_item(cx, i, ());
         })
     }
index 53d3dec671301d1e9a6a218087a1f00fce757b2c..1e44e1ab7f967b0a335d30e51872c08a135fc047 100644 (file)
@@ -101,11 +101,6 @@ struct Foo { a: int, b: ~int }
 expressions that are moved.  It is more efficient therefore just to
 store those entries.
 
-Sometimes though we want to know the variables that are moved (in
-particular in the borrow checker). For these cases, the set
-`moved_variables_set` just collects the ids of variables that are
-moved.
-
 Finally, the `capture_map` maps from the node_id of a closure
 expression to an array of `CaptureVar` structs detailing which
 variables are captured and how (by ref, by copy, by move).
@@ -170,7 +165,6 @@ pub struct MoveMaps {
      * pub Note: The `moves_map` stores expression ids that are moves,
      * whereas this set stores the ids of the variables that are
      * moved at some point */
-    pub moved_variables_set: NodeSet,
     pub capture_map: CaptureMap
 }
 
@@ -206,7 +200,6 @@ pub fn compute_moves(tcx: &ty::ctxt, krate: &Crate) -> MoveMaps {
         tcx: tcx,
         move_maps: MoveMaps {
             moves_map: NodeSet::new(),
-            moved_variables_set: NodeSet::new(),
             capture_map: NodeMap::new()
         }
     };
@@ -326,19 +319,6 @@ pub fn use_expr(&mut self,
         debug!("comp_mode = {:?}", comp_mode);
 
         match expr.node {
-            ExprPath(..) => {
-                match comp_mode {
-                    Move => {
-                        let def = self.tcx.def_map.borrow().get_copy(&expr.id);
-                        let r = moved_variable_node_id_from_def(def);
-                        for &id in r.iter() {
-                            self.move_maps.moved_variables_set.insert(id);
-                        }
-                    }
-                    Read => {}
-                }
-            }
-
             ExprUnary(UnDeref, base) => {      // *base
                 if !self.use_overloaded_operator(expr, base, []) {
                     // Moving out of *base moves out of base.
@@ -475,6 +455,7 @@ fn has_dtor(tcx: &ty::ctxt, ty: ty::t) -> bool {
                 self.use_expr(base, Read);
             }
 
+            ExprPath(..) |
             ExprInlineAsm(..) |
             ExprBreak(..) |
             ExprAgain(..) |
index 4e2d8cf585f2cebca8af26699f4c6c1ea5485500..408c63114966b502cfdfd54c3318bf3eeca02f9e 100644 (file)
@@ -791,7 +791,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
                     }
                     Some(method) => {
                         debug!("(privacy checking) checking impl method");
-                        self.check_method(expr.span, method.origin, ident);
+                        self.check_method(expr.span, method.origin, ident.node);
                     }
                 }
             }
index ab345ecb243541d713fa9ff15794d9ddcf7fcce8..d429ead39d63f1cec6840639f5f5e6611a1b012b 100644 (file)
@@ -5083,7 +5083,7 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
                 debug!("(recording candidate traits for expr) recording \
                         traits for {}",
                        expr.id);
-                let traits = self.search_for_traits_containing_method(ident.name);
+                let traits = self.search_for_traits_containing_method(ident.node.name);
                 self.trait_map.insert(expr.id, traits);
             }
             _ => {
index 55f8b3d1fd22772a5e1800ca488f4a642147bcbc..ddda95c06cb252db96cea6b019399cfd481f8d33 100644 (file)
 use driver::session::FullDebugInfo;
 use lib::llvm::{llvm, ValueRef, BasicBlockRef};
 use middle::const_eval;
-use middle::borrowck::root_map_key;
 use middle::lang_items::{UniqStrEqFnLangItem, StrEqFnLangItem};
 use middle::pat_util::*;
 use middle::resolve::DefMap;
@@ -1156,14 +1155,6 @@ fn extend(idents: &mut Vec<ast::Ident> , field_pats: &[ast::FieldPat]) {
     }
 }
 
-fn pats_require_rooting(bcx: &Block, m: &[Match], col: uint) -> bool {
-    m.iter().any(|br| {
-        let pat_id = br.pats.get(col).id;
-        let key = root_map_key {id: pat_id, derefs: 0u };
-        bcx.ccx().maps.root_map.contains_key(&key)
-    })
-}
-
 // Macro for deciding whether any of the remaining matches fit a given kind of
 // pattern.  Note that, because the macro is well-typed, either ALL of the
 // matches should fit that sort of pattern or NONE (however, some of the
@@ -1551,10 +1542,6 @@ fn compile_submatch_continue<'a, 'b>(
         }
     }
 
-    // If we are not matching against an `@T`, we should not be
-    // required to root any values.
-    assert!(!pats_require_rooting(bcx, m, col));
-
     match collect_record_or_struct_fields(bcx, m, col) {
         Some(ref rec_fields) => {
             let pat_ty = node_id_type(bcx, pat_id);
index 27a97af610899e16be30e49895c29a9a15a6518f..0c7d36e0dbedf659fbbfeae312008f984349c7ab 100644 (file)
@@ -640,7 +640,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
                 }
             }
         }
-        ast_map::NodeMethod(method) => {
+        ast_map::NodeMethod(ref method) => {
             (method.ident,
              method.decl,
              &method.generics,
@@ -667,9 +667,9 @@ pub fn create_function_debug_context(cx: &CrateContext,
                         "create_function_debug_context: expected an expr_fn_block here")
             }
         }
-        ast_map::NodeTraitMethod(trait_method) => {
-            match *trait_method {
-                ast::Provided(method) => {
+        ast_map::NodeTraitMethod(ref trait_method) => {
+            match **trait_method {
+                ast::Provided(ref method) => {
                     (method.ident,
                      method.decl,
                      &method.generics,
index 3c1dfedcac6162bdd91cd8f9f46790294ae24ba9..9bb0375bf44d27b93a1cefc5c0e84194c810a966 100644 (file)
@@ -59,7 +59,6 @@
 use middle::trans::inline;
 use middle::trans::tvec;
 use middle::trans::type_of;
-use middle::trans::write_guard;
 use middle::ty::struct_fields;
 use middle::ty::{AutoBorrowObj, AutoDerefRef, AutoAddEnv, AutoObject, AutoUnsafe};
 use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef};
@@ -1676,8 +1675,6 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
                   derefs: uint)
                   -> DatumBlock<'a, Expr> {
     let ccx = bcx.ccx();
-    let bcx = write_guard::root_and_write_guard(&datum, bcx, expr.span,
-                                                expr.id, derefs);
 
     debug!("deref_once(expr={}, datum={}, derefs={})",
            expr.repr(bcx.tcx()),
index 7ac491edfeb2a82cf883b7d8ef8300beb56aafc4..f07adb1ed87c0b95a79cdcf5e5177c33477ddff9 100644 (file)
@@ -15,7 +15,6 @@
 pub mod controlflow;
 pub mod glue;
 pub mod datum;
-pub mod write_guard;
 pub mod callee;
 pub mod expr;
 pub mod common;
diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs
deleted file mode 100644 (file)
index 8f11482..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2012 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.
-
-//! Logic relating to rooting and write guards for managed values.
-//! This code is primarily for use by datum;
-//! it exists in its own module both to keep datum.rs bite-sized
-//! and for each in debugging (e.g., so you can use
-//! `RUST_LOG=rustc::middle::trans::write_guard`).
-
-
-use middle::borrowck::{RootInfo, root_map_key};
-use middle::trans::cleanup;
-use middle::trans::common::*;
-use middle::trans::datum::*;
-use syntax::codemap::Span;
-use syntax::ast;
-
-pub fn root_and_write_guard<'a, K:KindOps>(datum: &Datum<K>,
-                                           bcx: &'a Block<'a>,
-                                           span: Span,
-                                           expr_id: ast::NodeId,
-                                           derefs: uint) -> &'a Block<'a> {
-    let key = root_map_key { id: expr_id, derefs: derefs };
-    debug!("write_guard::root_and_write_guard(key={:?})", key);
-
-    // root the autoderef'd value, if necessary:
-    //
-    // (Note: root'd values are always boxes)
-    let ccx = bcx.ccx();
-    match ccx.maps.root_map.find(&key) {
-        None => bcx,
-        Some(&root_info) => root(datum, bcx, span, key, root_info)
-    }
-}
-
-fn root<'a, K:KindOps>(datum: &Datum<K>,
-                       bcx: &'a Block<'a>,
-                       _span: Span,
-                       root_key: root_map_key,
-                       root_info: RootInfo) -> &'a Block<'a> {
-    //! In some cases, borrowck will decide that an @T value must be
-    //! rooted for the program to be safe.  In that case, we will call
-    //! this function, which will stash a copy away until we exit the
-    //! scope `scope_id`.
-
-    debug!("write_guard::root(root_key={:?}, root_info={:?}, datum={:?})",
-           root_key, root_info, datum.to_str(bcx.ccx()));
-
-    // Root the datum. Note that we must zero this value,
-    // because sometimes we root on one path but not another.
-    // See e.g. #4904.
-    lvalue_scratch_datum(
-        bcx, datum.ty, "__write_guard", true,
-        cleanup::AstScope(root_info.scope), (),
-        |(), bcx, llval| datum.shallow_copy_and_take(bcx, llval)).bcx
-}
index 9a261689b3779815fe0632f8a939319f898b0cdc..ce35d1ab1debc72522e3917fc9d91cc6d4ae47e9 100644 (file)
@@ -1722,7 +1722,7 @@ fn check_method_argument_types(
                 }
                 _ => {
                     fcx.tcx().sess.span_bug(
-                        sp,
+                        callee_expr.span,
                         format!("method without bare fn type"));
                 }
             }
@@ -1936,7 +1936,7 @@ fn check_call(fcx: &FnCtxt,
     // Checks a method call.
     fn check_method_call(fcx: &FnCtxt,
                          expr: &ast::Expr,
-                         method_name: ast::Ident,
+                         method_name: ast::SpannedIdent,
                          args: &[@ast::Expr],
                          tps: &[ast::P<ast::Ty>]) {
         let rcvr = args[0];
@@ -1952,7 +1952,7 @@ fn check_method_call(fcx: &FnCtxt,
 
         let tps = tps.iter().map(|&ast_ty| fcx.to_ty(ast_ty)).collect::<Vec<_>>();
         let fn_ty = match method::lookup(fcx, expr, rcvr,
-                                         method_name.name,
+                                         method_name.node.name,
                                          expr_t, tps.as_slice(),
                                          DontDerefArgs,
                                          CheckTraitsAndInherentMethods,
@@ -1966,11 +1966,10 @@ fn check_method_call(fcx: &FnCtxt,
             None => {
                 debug!("(checking method call) failing expr is {}", expr.id);
 
-                fcx.type_error_message(expr.span,
+                fcx.type_error_message(method_name.span,
                   |actual| {
-                      format!("type `{}` does not implement any method in scope \
-                            named `{}`",
-                           actual, token::get_ident(method_name))
+                      format!("type `{}` does not implement any method in scope named `{}`",
+                              actual, token::get_ident(method_name.node))
                   },
                   expr_t,
                   None);
@@ -1982,7 +1981,7 @@ fn check_method_call(fcx: &FnCtxt,
         };
 
         // Call the generic checker.
-        let ret_ty = check_method_argument_types(fcx, expr.span,
+        let ret_ty = check_method_argument_types(fcx, method_name.span,
                                                  fn_ty, expr, args,
                                                  DontDerefArgs);
 
index b59da8910af8b4ff8d00f590c46f5168a9dabdd7..9f36e903e5886461048e926246456cefa9f26f4f 100644 (file)
@@ -1277,12 +1277,12 @@ fn link_region(rcx: &Rcx,
             }
             mc::cat_discr(cmt_base, _) |
             mc::cat_downcast(cmt_base) |
+            mc::cat_deref(cmt_base, _, mc::GcPtr(..)) |
             mc::cat_deref(cmt_base, _, mc::OwnedPtr) |
             mc::cat_interior(cmt_base, _) => {
                 // Interior or owned data requires its base to be valid
                 cmt_borrowed = cmt_base;
             }
-            mc::cat_deref(_, _, mc::GcPtr(..)) |
             mc::cat_deref(_, _, mc::UnsafePtr(..)) |
             mc::cat_static_item |
             mc::cat_copied_upvar(..) |
index bb9c6a87babda986c32e8fe24e58ffa165d9e88a..df102b8aadf3f455e2731c56d0a1e7a2f61cc2e1 100644 (file)
@@ -674,14 +674,16 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
         let parent = self.tcx.map.get_parent(scope_id);
         let parent_node = self.tcx.map.find(parent);
         let node_inner = match parent_node {
-            Some(node) => match node {
-                ast_map::NodeItem(item) => match item.node {
-                    ast::ItemFn(ref fn_decl, ref pur, _, ref gen, _) => {
-                        Some((fn_decl, gen, *pur, item.ident, None, item.span))
-                    },
-                    _ => None
-                },
-                ast_map::NodeMethod(m) => {
+            Some(ref node) => match *node {
+                ast_map::NodeItem(ref item) => {
+                    match item.node {
+                        ast::ItemFn(ref fn_decl, ref pur, _, ref gen, _) => {
+                            Some((fn_decl, gen, *pur, item.ident, None, item.span))
+                        },
+                        _ => None
+                    }
+                }
+                ast_map::NodeMethod(ref m) => {
                     Some((&m.decl, &m.generics, m.fn_style,
                           m.ident, Some(m.explicit_self.node), m.span))
                 },
index 3f1c99cffd640228e7948fb8735cf607ae4b6d8c..be05ccdfcb41209576d17ad5cc03afd6d22d20f7 100644 (file)
@@ -684,7 +684,8 @@ impl Clean<Type> for ast::Ty {
     fn clean(&self) -> Type {
         use syntax::ast::*;
         debug!("cleaning type `{:?}`", self);
-        let codemap = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess().codemap();
+        let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let codemap = ctxt.sess().codemap();
         debug!("span corresponds to `{}`", codemap.span_to_str(self.span));
         match self.node {
             TyNil => Unit,
@@ -866,7 +867,8 @@ pub struct Span {
 
 impl Clean<Span> for syntax::codemap::Span {
     fn clean(&self) -> Span {
-        let cm = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess().codemap();
+        let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let cm = ctxt.sess().codemap();
         let filename = cm.span_to_filename(*self);
         let lo = cm.lookup_char_pos(self.lo);
         let hi = cm.lookup_char_pos(self.hi);
@@ -1193,7 +1195,8 @@ trait ToSource {
 impl ToSource for syntax::codemap::Span {
     fn to_src(&self) -> ~str {
         debug!("converting span {:?} to snippet", self.clean());
-        let cm = local_data::get(super::ctxtkey, |x| x.unwrap().clone()).sess().codemap().clone();
+        let ctxt = local_data::get(super::ctxtkey, |x| x.unwrap().clone());
+        let cm = ctxt.sess().codemap().clone();
         let sn = match cm.span_to_snippet(*self) {
             Some(x) => x,
             None    => "".to_owned()
index c75f84de01e4462ffeb874d2ac8e644e47174781..dcbd0baf6f329b2ac24d2522ff447a81bd3fb9c1 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use std::cast;
-use libc::c_int;
 use std::rt::rtio::{Callback, RemoteCallback};
 use std::unstable::sync::Exclusive;
 
@@ -54,8 +53,7 @@ unsafe fn from_uv_handle<'a>(_: &'a *uvll::uv_async_t) -> &'a mut AsyncWatcher {
     }
 }
 
-extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
-    assert!(status == 0);
+extern fn async_cb(handle: *uvll::uv_async_t) {
     let payload: &mut Payload = unsafe {
         cast::transmute(uvll::get_data_for_uv_handle(handle))
     };
index cde5cfa97c1d751f86a84901c0305001ee3f3418..665d418ab2ab6e0fd1c718f7d990afbc1fb971d6 100644 (file)
@@ -12,7 +12,7 @@
 use std::c_str;
 use std::cast::transmute;
 use std::cast;
-use libc::{c_int, c_char, c_void, size_t, ssize_t};
+use libc::{c_int, c_char, c_void, ssize_t};
 use libc;
 use std::rt::task::BlockedTask;
 use std::io::{FileStat, IoError};
@@ -86,14 +86,12 @@ pub fn write(loop_: &Loop, fd: c_int, buf: &[u8], offset: i64)
             } else {
                 offset + written as i64
             };
+            let uvbuf = uvll::uv_buf_t {
+                base: buf.slice_from(written as uint).as_ptr(),
+                len: (buf.len() - written) as uvll::uv_buf_len_t,
+            };
             match execute(|req, cb| unsafe {
-                uvll::uv_fs_write(loop_.handle,
-                                  req,
-                                  fd,
-                                  buf.as_ptr().offset(written as int) as *c_void,
-                                  (buf.len() - written) as size_t,
-                                  offset,
-                                  cb)
+                uvll::uv_fs_write(loop_.handle, req, fd, &uvbuf, 1, offset, cb)
             }).map(|req| req.get_result()) {
                 Err(e) => return Err(e),
                 Ok(n) => { written += n as uint; }
@@ -106,9 +104,11 @@ pub fn read(loop_: &Loop, fd: c_int, buf: &mut [u8], offset: i64)
         -> Result<int, UvError>
     {
         execute(|req, cb| unsafe {
-            uvll::uv_fs_read(loop_.handle, req,
-                             fd, buf.as_ptr() as *c_void,
-                             buf.len() as size_t, offset, cb)
+            let uvbuf = uvll::uv_buf_t {
+                base: buf.as_ptr(),
+                len: buf.len() as uvll::uv_buf_len_t,
+            };
+            uvll::uv_fs_read(loop_.handle, req, fd, &uvbuf, 1, offset, cb)
         }).map(|req| {
             req.get_result() as int
         })
index 0de6e479a8f7aacb54414f2e8d75c8ae137096d3..4d7da29aa9a8345d6d6ca42f2edc31c9e750c9b8 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::cast;
-use libc::{c_int, c_void};
+use libc::c_void;
 
 use uvll;
 use super::{Loop, UvHandle};
@@ -46,8 +46,7 @@ pub fn onetime(loop_: &mut Loop, f: proc()) {
             assert_eq!(uvll::uv_idle_start(handle, onetime_cb), 0)
         }
 
-        extern fn onetime_cb(handle: *uvll::uv_idle_t, status: c_int) {
-            assert_eq!(status, 0);
+        extern fn onetime_cb(handle: *uvll::uv_idle_t) {
             unsafe {
                 let data = uvll::get_data_for_uv_handle(handle);
                 let f: ~proc() = cast::transmute(data);
@@ -82,8 +81,7 @@ impl UvHandle<uvll::uv_idle_t> for IdleWatcher {
     fn uv_handle(&self) -> *uvll::uv_idle_t { self.handle }
 }
 
-extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) {
-    assert_eq!(status, 0);
+extern fn idle_cb(handle: *uvll::uv_idle_t) {
     let idle: &mut IdleWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
     idle.callback.call();
 }
index 69d978b24334fec56c0ae1dea0e5970478e42f56..27a0691193980b308d23ac75ec31b125318770cc 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)
@@ -252,10 +255,9 @@ struct Ctx {
             n => Err(UvError(n))
         };
 
-        extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
+        extern fn timer_cb(handle: *uvll::uv_timer_t) {
             // Don't close the corresponding tcp request, just wake up the task
             // and let RAII take care of the pending watcher.
-            assert_eq!(status, 0);
             let cx: &mut Ctx = unsafe {
                 &mut *(uvll::get_data_for_uv_handle(handle) as *mut Ctx)
             };
@@ -459,7 +461,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 +516,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 +562,51 @@ 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) {
+            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 b6c7fbda8c836c2ba26417702741291c4c0b40ef..9e75991434f412f64dadef1d132aa911180c9296 100644 (file)
@@ -21,7 +21,7 @@
 #![allow(dead_code)]
 
 use std::cast;
-use libc::{c_void, c_int};
+use libc::c_void;
 use std::rt::task::BlockedTask;
 use std::unstable::mutex::NativeMutex;
 use std::sync::arc::UnsafeArc;
@@ -55,8 +55,7 @@ pub struct Queue {
     queue: UnsafeArc<State>,
 }
 
-extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
-    assert_eq!(status, 0);
+extern fn async_cb(handle: *uvll::uv_async_t) {
     let pool: &mut QueuePool = unsafe {
         cast::transmute(uvll::get_data_for_uv_handle(handle))
     };
index 3710d97827f2819fbd0ceaf4250fcdef60c494a3..5c34fd8cc12e85a5e04462892addd31b2656857d 100644 (file)
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use libc::c_int;
 use std::mem;
 use std::rt::rtio::RtioTimer;
 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 +33,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) {
@@ -134,9 +136,8 @@ fn period(&mut self, msecs: u64) -> Receiver<()> {
     }
 }
 
-extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
+extern fn timer_cb(handle: *uvll::uv_timer_t) {
     let _f = ForbidSwitch::new("timer callback can't switch");
-    assert_eq!(status, 0);
     let timer: &mut TimerWatcher = unsafe { UvHandle::from_uv_handle(&handle) };
 
     match timer.action.take_unwrap() {
index 95ecaa09a43ae473ddf3b2e49697f3b0dbf4e1ac..4f3e12b6974d592f98793f8843e09a3776802f42 100644 (file)
@@ -40,7 +40,7 @@ pub fn new(io: &mut UvIoFactory, fd: libc::c_int, readable: bool)
         // - https://github.com/joyent/libuv/issues/982
         // - https://github.com/joyent/libuv/issues/988
         let guess = unsafe { uvll::guess_handle(fd) };
-        if readable && guess != uvll::UV_TTY as libc::c_int {
+        if guess != uvll::UV_TTY as libc::c_int {
             return Err(UvError(uvll::EBADF));
         }
 
index 3769a1b8d6db42d3236f20ed64dd28137e77be88..3127a01d70e4698644fb7f9cc6e19623048f61a6 100644 (file)
@@ -23,7 +23,7 @@
 use libc;
 use std::path::Path;
 use std::rt::rtio;
-use std::rt::rtio::IoFactory;
+use std::rt::rtio::{IoFactory, EventLoop};
 use ai = std::io::net::addrinfo;
 
 #[cfg(test)] use std::unstable::run_in_bare_thread;
@@ -69,14 +69,20 @@ fn drop(&mut self) {
         // the loop is free'd (use-after-free). We also must free the uv handle
         // after the loop has been closed because during the closing of the loop
         // the handle is required to be used apparently.
+        //
+        // Lastly, after we've closed the pool of handles we pump the event loop
+        // one last time to run any closing callbacks to make sure the loop
+        // shuts down cleanly.
         let handle = self.uvio.handle_pool.get_ref().handle();
         drop(self.uvio.handle_pool.take());
+        self.run();
+
         self.uvio.loop_.close();
         unsafe { uvll::free_handle(handle) }
     }
 }
 
-impl rtio::EventLoop for UvEventLoop {
+impl EventLoop for UvEventLoop {
     fn run(&mut self) {
         self.uvio.loop_.run();
     }
@@ -110,7 +116,6 @@ fn has_active_io(&self) -> bool {
 
 #[test]
 fn test_callback_run_once() {
-    use std::rt::rtio::EventLoop;
     run_in_bare_thread(proc() {
         let mut event_loop = UvEventLoop::new();
         let mut count = 0;
index 04bc53004d04c1e8e4b2708b18418113bc69f817..57f4bd9d7eb13c34e15db63d2d3ab7a37ab255ec 100644 (file)
@@ -212,8 +212,7 @@ pub fn is_dir(&self) -> bool {
     }
 }
 
-pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t,
-                                    status: c_int);
+pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t);
 pub type uv_alloc_cb = extern "C" fn(stream: *uv_stream_t,
                                      suggested_size: size_t,
                                      buf: *mut uv_buf_t);
@@ -230,14 +229,12 @@ pub fn is_dir(&self) -> bool {
 pub type uv_close_cb = extern "C" fn(handle: *uv_handle_t);
 pub type uv_walk_cb = extern "C" fn(handle: *uv_handle_t,
                                     arg: *c_void);
-pub type uv_async_cb = extern "C" fn(handle: *uv_async_t,
-                                     status: c_int);
+pub type uv_async_cb = extern "C" fn(handle: *uv_async_t);
 pub type uv_connect_cb = extern "C" fn(handle: *uv_connect_t,
                                        status: c_int);
 pub type uv_connection_cb = extern "C" fn(handle: *uv_connection_t,
                                           status: c_int);
-pub type uv_timer_cb = extern "C" fn(handle: *uv_timer_t,
-                                     status: c_int);
+pub type uv_timer_cb = extern "C" fn(handle: *uv_timer_t);
 pub type uv_write_cb = extern "C" fn(handle: *uv_write_t,
                                      status: c_int);
 pub type uv_getaddrinfo_cb = extern "C" fn(req: *uv_getaddrinfo_t,
@@ -597,10 +594,12 @@ pub fn uv_fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
                       flags: c_int, mode: c_int, cb: uv_fs_cb) -> c_int;
     pub fn uv_fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
                         cb: uv_fs_cb) -> c_int;
-    pub fn uv_fs_write(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
-                       len: size_t, offset: i64, cb: uv_fs_cb) -> c_int;
-    pub fn uv_fs_read(l: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
-                      len: size_t, offset: i64, cb: uv_fs_cb) -> c_int;
+    pub fn uv_fs_write(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
+                       bufs: *uv_buf_t, nbufs: c_uint,
+                       offset: i64, cb: uv_fs_cb) -> c_int;
+    pub fn uv_fs_read(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
+                      bufs: *uv_buf_t, nbufs: c_uint,
+                      offset: i64, cb: uv_fs_cb) -> c_int;
     pub fn uv_fs_close(l: *uv_loop_t, req: *uv_fs_t, fd: c_int,
                        cb: uv_fs_cb) -> c_int;
     pub fn uv_fs_stat(l: *uv_loop_t, req: *uv_fs_t, path: *c_char,
index 794c4ee62ff78cebd4fde9b1255ebad3b633ea1d..eae13735809515951740c3932ef82d6909380603 100644 (file)
@@ -364,7 +364,7 @@ mod tests {
     use option::{Some, None};
     use str::{Str,StrSlice};
     use strbuf::StrBuf;
-    use slice::{Vector, ImmutableVector, OwnedVector};
+    use slice::{Vector, ImmutableVector};
     use self::test::Bencher;
 
     use super::super::Hash;
index 6bc32d0ed7b56c0a2c4c547835a52ef4e600fe7e..a9c493c284dd344787de21971bf0bcb47c60833e 100644 (file)
@@ -491,7 +491,8 @@ pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
 
 /// Returns an iterator which will recursively walk the directory structure
 /// rooted at `path`. The path given will not be iterated over, and this will
-/// perform iteration in a top-down order.
+/// perform iteration in some top-down order.  The contents of unreadable
+/// subdirectories are ignored.
 pub fn walk_dir(path: &Path) -> IoResult<Directories> {
     Ok(Directories { stack: try!(readdir(path)) })
 }
@@ -503,7 +504,7 @@ pub struct Directories {
 
 impl Iterator<Path> for Directories {
     fn next(&mut self) -> Option<Path> {
-        match self.stack.shift() {
+        match self.stack.pop() {
             Some(path) => {
                 if path.is_dir() {
                     match readdir(&path) {
@@ -970,6 +971,32 @@ pub fn tmpdir() -> TempDir {
         check!(rmdir(dir));
     })
 
+    iotest!(fn file_test_walk_dir() {
+        let tmpdir = tmpdir();
+        let dir = &tmpdir.join("walk_dir");
+        check!(mkdir(dir, io::UserRWX));
+
+        let dir1 = &dir.join("01/02/03");
+        check!(mkdir_recursive(dir1, io::UserRWX));
+        check!(File::create(&dir1.join("04")));
+
+        let dir2 = &dir.join("11/12/13");
+        check!(mkdir_recursive(dir2, io::UserRWX));
+        check!(File::create(&dir2.join("14")));
+
+        let mut files = check!(walk_dir(dir));
+        let mut cur = [0u8, .. 2];
+        for f in files {
+            let stem = f.filestem_str().unwrap();
+            let root = stem[0] - ('0' as u8);
+            let name = stem[1] - ('0' as u8);
+            assert!(cur[root as uint] < name);
+            cur[root as uint] = name;
+        }
+
+        check!(rmdir_recursive(dir));
+    })
+
     iotest!(fn recursive_mkdir() {
         let tmpdir = tmpdir();
         let dir = tmpdir.join("d1/d2");
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 bf31f36d22d2575da3cc62e36eff6d4fb9577ad3..6df549dbc791b8e149b6f46814a7b4b1cb007d19 100644 (file)
@@ -64,26 +64,23 @@ mod cmath {
     }
 }
 
-// FIXME(#11621): These constants should be deprecated once CTFE is implemented
-// in favour of calling their respective functions in `Bounded` and `Float`.
-
 pub static RADIX: uint = 2u;
 
-pub static MANTISSA_DIGITS: uint = 53u;
-pub static DIGITS: uint = 15u;
+pub static MANTISSA_DIGITS: uint = 24u;
+pub static DIGITS: uint = 6u;
 
-pub static EPSILON: f64 = 2.220446e-16_f64;
+pub static EPSILON: f32 = 1.19209290e-07_f32;
 
-// FIXME (#1433): this is wrong, replace with hexadecimal (%a) statics
-// below.
-pub static MIN_VALUE: f64 = 2.225074e-308_f64;
-pub static MAX_VALUE: f64 = 1.797693e+308_f64;
+/// Minimum normalized f32 value
+pub static MIN_VALUE: f32 = 1.17549435e-38_f32;
+/// Maximum f32 value
+pub static MAX_VALUE: f32 = 3.40282347e+38_f32;
 
-pub static MIN_EXP: uint = -1021u;
-pub static MAX_EXP: uint = 1024u;
+pub static MIN_EXP: int = -125;
+pub static MAX_EXP: int = 128;
 
-pub static MIN_10_EXP: int = -307;
-pub static MAX_10_EXP: int = 308;
+pub static MIN_10_EXP: int = -37;
+pub static MAX_10_EXP: int = 38;
 
 pub static NAN: f32 = 0.0_f32/0.0_f32;
 pub static INFINITY: f32 = 1.0_f32/0.0_f32;
@@ -91,8 +88,7 @@ mod cmath {
 
 /// Various useful constants.
 pub mod consts {
-    // FIXME (requires Issue #1433 to fix): replace with mathematical
-    // staticants from cmath.
+    // FIXME: replace with mathematical constants from cmath.
 
     // FIXME(#11621): These constants should be deprecated once CTFE is
     // implemented in favour of calling their respective functions in `Float`.
@@ -100,12 +96,24 @@ pub mod consts {
     /// Archimedes' constant
     pub static PI: f32 = 3.14159265358979323846264338327950288_f32;
 
+    /// pi * 2.0
+    pub static PI_2: f32 = 6.28318530717958647692528676655900576_f32;
+
     /// pi/2.0
     pub static FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
 
+    /// pi/3.0
+    pub static FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32;
+
     /// pi/4.0
     pub static FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32;
 
+    /// pi/6.0
+    pub static FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32;
+
+    /// pi/8.0
+    pub static FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32;
+
     /// 1.0/pi
     pub static FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
 
@@ -251,24 +259,25 @@ fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
 }
 
 impl Bounded for f32 {
+    // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE
     #[inline]
-    fn min_value() -> f32 { 1.17549435e-38 }
+    fn min_value() -> f32 { -MAX_VALUE }
 
     #[inline]
-    fn max_value() -> f32 { 3.40282347e+38 }
+    fn max_value() -> f32 { MAX_VALUE }
 }
 
 impl Primitive for f32 {}
 
 impl Float for f32 {
     #[inline]
-    fn nan() -> f32 { 0.0 / 0.0 }
+    fn nan() -> f32 { NAN }
 
     #[inline]
-    fn infinity() -> f32 { 1.0 / 0.0 }
+    fn infinity() -> f32 { INFINITY }
 
     #[inline]
-    fn neg_infinity() -> f32 { -1.0 / 0.0 }
+    fn neg_infinity() -> f32 { NEG_INFINITY }
 
     #[inline]
     fn neg_zero() -> f32 { -0.0 }
@@ -313,25 +322,25 @@ fn classify(self) -> FPCategory {
     }
 
     #[inline]
-    fn mantissa_digits(_: Option<f32>) -> uint { 24 }
+    fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
 
     #[inline]
-    fn digits(_: Option<f32>) -> uint { 6 }
+    fn digits(_: Option<f32>) -> uint { DIGITS }
 
     #[inline]
-    fn epsilon() -> f32 { 1.19209290e-07 }
+    fn epsilon() -> f32 { EPSILON }
 
     #[inline]
-    fn min_exp(_: Option<f32>) -> int { -125 }
+    fn min_exp(_: Option<f32>) -> int { MIN_EXP }
 
     #[inline]
-    fn max_exp(_: Option<f32>) -> int { 128 }
+    fn max_exp(_: Option<f32>) -> int { MAX_EXP }
 
     #[inline]
-    fn min_10_exp(_: Option<f32>) -> int { -37 }
+    fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
 
     #[inline]
-    fn max_10_exp(_: Option<f32>) -> int { 38 }
+    fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
 
     /// Constructs a floating point number by multiplying `x` by 2 raised to the
     /// power of `exp`
@@ -442,11 +451,11 @@ fn powf(self, n: f32) -> f32 {
 
     /// sqrt(2.0)
     #[inline]
-    fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
+    fn sqrt2() -> f32 { consts::SQRT2 }
 
     /// 1.0 / sqrt(2.0)
     #[inline]
-    fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
+    fn frac_1_sqrt2() -> f32 { consts::FRAC_1_SQRT2 }
 
     #[inline]
     fn sqrt(self) -> f32 {
@@ -468,43 +477,43 @@ fn hypot(self, other: f32) -> f32 {
 
     /// Archimedes' constant
     #[inline]
-    fn pi() -> f32 { 3.14159265358979323846264338327950288 }
+    fn pi() -> f32 { consts::PI }
 
     /// 2.0 * pi
     #[inline]
-    fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
+    fn two_pi() -> f32 { consts::PI_2 }
 
     /// pi / 2.0
     #[inline]
-    fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
+    fn frac_pi_2() -> f32 { consts::FRAC_PI_2 }
 
     /// pi / 3.0
     #[inline]
-    fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
+    fn frac_pi_3() -> f32 { consts::FRAC_PI_3 }
 
     /// pi / 4.0
     #[inline]
-    fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
+    fn frac_pi_4() -> f32 { consts::FRAC_PI_4 }
 
     /// pi / 6.0
     #[inline]
-    fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
+    fn frac_pi_6() -> f32 { consts::FRAC_PI_6 }
 
     /// pi / 8.0
     #[inline]
-    fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
+    fn frac_pi_8() -> f32 { consts::FRAC_PI_8 }
 
     /// 1 .0/ pi
     #[inline]
-    fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
+    fn frac_1_pi() -> f32 { consts::FRAC_1_PI }
 
     /// 2.0 / pi
     #[inline]
-    fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
+    fn frac_2_pi() -> f32 { consts::FRAC_2_PI }
 
     /// 2.0 / sqrt(pi)
     #[inline]
-    fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
+    fn frac_2_sqrtpi() -> f32 { consts::FRAC_2_SQRTPI }
 
     #[inline]
     fn sin(self) -> f32 {
@@ -549,23 +558,23 @@ fn sin_cos(self) -> (f32, f32) {
 
     /// Euler's number
     #[inline]
-    fn e() -> f32 { 2.71828182845904523536028747135266250 }
+    fn e() -> f32 { consts::E }
 
     /// log2(e)
     #[inline]
-    fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
+    fn log2_e() -> f32 { consts::LOG2_E }
 
     /// log10(e)
     #[inline]
-    fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
+    fn log10_e() -> f32 { consts::LOG10_E }
 
     /// ln(2.0)
     #[inline]
-    fn ln_2() -> f32 { 0.693147180559945309417232121458176568 }
+    fn ln_2() -> f32 { consts::LN_2 }
 
     /// ln(10.0)
     #[inline]
-    fn ln_10() -> f32 { 2.30258509299404568401799145468436421 }
+    fn ln_10() -> f32 { consts::LN_10 }
 
     /// Returns the exponential of the number
     #[inline]
index 39eba0825fc3c351c77c8e2d81471d1bda069497..63ddb88f8dc2ad0f2879ad8ae1891c88e5a176dc 100644 (file)
@@ -73,8 +73,6 @@ mod cmath {
     }
 }
 
-// FIXME (#1433): obtain these in a different way
-
 // FIXME(#11621): These constants should be deprecated once CTFE is implemented
 // in favour of calling their respective functions in `Bounded` and `Float`.
 
@@ -85,7 +83,9 @@ mod cmath {
 
 pub static EPSILON: f64 = 2.2204460492503131e-16_f64;
 
+/// Minimum normalized f64 value
 pub static MIN_VALUE: f64 = 2.2250738585072014e-308_f64;
+/// Maximum f64 value
 pub static MAX_VALUE: f64 = 1.7976931348623157e+308_f64;
 
 pub static MIN_EXP: int = -1021;
@@ -100,12 +100,9 @@ mod cmath {
 
 pub static NEG_INFINITY: f64 = -1.0_f64/0.0_f64;
 
-// FIXME (#1999): add is_normal, is_subnormal, and fpclassify
-
 /// Various useful constants.
 pub mod consts {
-    // FIXME (requires Issue #1433 to fix): replace with mathematical
-    // constants from cmath.
+    // FIXME: replace with mathematical constants from cmath.
 
     // FIXME(#11621): These constants should be deprecated once CTFE is
     // implemented in favour of calling their respective functions in `Float`.
@@ -113,12 +110,24 @@ pub mod consts {
     /// Archimedes' constant
     pub static PI: f64 = 3.14159265358979323846264338327950288_f64;
 
+    /// pi * 2.0
+    pub static PI_2: f64 = 6.28318530717958647692528676655900576_f64;
+
     /// pi/2.0
     pub static FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
 
+    /// pi/3.0
+    pub static FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64;
+
     /// pi/4.0
     pub static FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64;
 
+    /// pi/6.0
+    pub static FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64;
+
+    /// pi/8.0
+    pub static FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64;
+
     /// 1.0/pi
     pub static FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
 
@@ -258,24 +267,25 @@ fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
 }
 
 impl Bounded for f64 {
+    // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE
     #[inline]
-    fn min_value() -> f64 { 2.2250738585072014e-308 }
+    fn min_value() -> f64 { -MAX_VALUE }
 
     #[inline]
-    fn max_value() -> f64 { 1.7976931348623157e+308 }
+    fn max_value() -> f64 { MAX_VALUE }
 }
 
 impl Primitive for f64 {}
 
 impl Float for f64 {
     #[inline]
-    fn nan() -> f64 { 0.0 / 0.0 }
+    fn nan() -> f64 { NAN }
 
     #[inline]
-    fn infinity() -> f64 { 1.0 / 0.0 }
+    fn infinity() -> f64 { INFINITY }
 
     #[inline]
-    fn neg_infinity() -> f64 { -1.0 / 0.0 }
+    fn neg_infinity() -> f64 { NEG_INFINITY }
 
     #[inline]
     fn neg_zero() -> f64 { -0.0 }
@@ -450,11 +460,11 @@ fn powi(self, n: i32) -> f64 {
 
     /// sqrt(2.0)
     #[inline]
-    fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 }
+    fn sqrt2() -> f64 { consts::SQRT2 }
 
     /// 1.0 / sqrt(2.0)
     #[inline]
-    fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
+    fn frac_1_sqrt2() -> f64 { consts::FRAC_1_SQRT2 }
 
     #[inline]
     fn sqrt(self) -> f64 {
@@ -476,43 +486,43 @@ fn hypot(self, other: f64) -> f64 {
 
     /// Archimedes' constant
     #[inline]
-    fn pi() -> f64 { 3.14159265358979323846264338327950288 }
+    fn pi() -> f64 { consts::PI }
 
     /// 2.0 * pi
     #[inline]
-    fn two_pi() -> f64 { 6.28318530717958647692528676655900576 }
+    fn two_pi() -> f64 { consts::PI_2 }
 
     /// pi / 2.0
     #[inline]
-    fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 }
+    fn frac_pi_2() -> f64 { consts::FRAC_PI_2 }
 
     /// pi / 3.0
     #[inline]
-    fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 }
+    fn frac_pi_3() -> f64 { consts::FRAC_PI_3 }
 
     /// pi / 4.0
     #[inline]
-    fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 }
+    fn frac_pi_4() -> f64 { consts::FRAC_PI_4 }
 
     /// pi / 6.0
     #[inline]
-    fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 }
+    fn frac_pi_6() -> f64 { consts::FRAC_PI_6 }
 
     /// pi / 8.0
     #[inline]
-    fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 }
+    fn frac_pi_8() -> f64 { consts::FRAC_PI_8 }
 
     /// 1.0 / pi
     #[inline]
-    fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 }
+    fn frac_1_pi() -> f64 { consts::FRAC_1_PI }
 
     /// 2.0 / pi
     #[inline]
-    fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 }
+    fn frac_2_pi() -> f64 { consts::FRAC_2_PI }
 
     /// 2.0 / sqrt(pi)
     #[inline]
-    fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
+    fn frac_2_sqrtpi() -> f64 { consts::FRAC_2_SQRTPI }
 
     #[inline]
     fn sin(self) -> f64 {
@@ -557,23 +567,23 @@ fn sin_cos(self) -> (f64, f64) {
 
     /// Euler's number
     #[inline]
-    fn e() -> f64 { 2.71828182845904523536028747135266250 }
+    fn e() -> f64 { consts::E }
 
     /// log2(e)
     #[inline]
-    fn log2_e() -> f64 { 1.44269504088896340735992468100189214 }
+    fn log2_e() -> f64 { consts::LOG2_E }
 
     /// log10(e)
     #[inline]
-    fn log10_e() -> f64 { 0.434294481903251827651128918916605082 }
+    fn log10_e() -> f64 { consts::LOG10_E }
 
     /// ln(2.0)
     #[inline]
-    fn ln_2() -> f64 { 0.693147180559945309417232121458176568 }
+    fn ln_2() -> f64 { consts::LN_2 }
 
     /// ln(10.0)
     #[inline]
-    fn ln_10() -> f64 { 2.30258509299404568401799145468436421 }
+    fn ln_10() -> f64 { consts::LN_10 }
 
     /// Returns the exponential of the number
     #[inline]
index c498892e76cb4942d1e8e6279087b630c00fc302..dccca82dc79abac4359c0bf1457aa252bee61df8 100644 (file)
@@ -358,9 +358,9 @@ pub trait Float: Signed + Primitive {
 
     /// Returns the number of binary digits of mantissa that this type supports.
     fn mantissa_digits(unused_self: Option<Self>) -> uint;
-    /// Returns the number of binary digits of exponent that this type supports.
+    /// Returns the number of base-10 digits of precision that this type supports.
     fn digits(unused_self: Option<Self>) -> uint;
-    /// Returns the smallest positive number that this type can represent.
+    /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
     fn epsilon() -> Self;
     /// Returns the minimum binary exponent that this type can represent.
     fn min_exp(unused_self: Option<Self>) -> int;
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 8b9b8a7498b2db766daffc76a19824ebffb16926..824d9e5ec925580be4d7ed65ab2a8de8890a6544 100644 (file)
@@ -67,9 +67,9 @@ mod imp {
     use clone::Clone;
     use option::{Option, Some, None};
     use iter::Iterator;
-    use str::StrSlice;
     use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use mem;
+    #[cfg(not(test))] use str::StrSlice;
     #[cfg(not(test))] use ptr::RawPtr;
 
     static mut global_args_ptr: uint = 0;
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 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 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 116411c9e05102dd5de552a4dde4d5cde5e65b5b..ccb25239f6ce494097e2e1a8e785cdf13c0ce177 100644 (file)
@@ -440,6 +440,7 @@ pub enum Decl_ {
 
 #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
 pub struct Arm {
+    pub attrs: Vec<Attribute>,
     pub pats: Vec<@Pat>,
     pub guard: Option<@Expr>,
     pub body: @Expr,
@@ -480,7 +481,7 @@ pub enum Expr_ {
     ExprBox(@Expr, @Expr),
     ExprVec(Vec<@Expr>),
     ExprCall(@Expr, Vec<@Expr>),
-    ExprMethodCall(Ident, Vec<P<Ty>>, Vec<@Expr>),
+    ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<@Expr>),
     ExprTup(Vec<@Expr>),
     ExprBinary(BinOp, @Expr, @Expr),
     ExprUnary(UnOp, @Expr),
index 7a167237d3e5db38f8a8d1adcbef41dd24d58835..865c3be4ae6469c1a5ee0b00b621d1498a8d4a95 100644 (file)
@@ -363,14 +363,15 @@ fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -
     }
 
     pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
-        let attrs = match self.get(id) {
-            NodeItem(i) => Some(i.attrs.as_slice()),
-            NodeForeignItem(fi) => Some(fi.attrs.as_slice()),
-            NodeTraitMethod(tm) => match *tm {
+        let node = self.get(id);
+        let attrs = match node {
+            NodeItem(ref i) => Some(i.attrs.as_slice()),
+            NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()),
+            NodeTraitMethod(ref tm) => match **tm {
                 Required(ref type_m) => Some(type_m.attrs.as_slice()),
-                Provided(m) => Some(m.attrs.as_slice())
+                Provided(ref m) => Some(m.attrs.as_slice())
             },
-            NodeMethod(m) => Some(m.attrs.as_slice()),
+            NodeMethod(ref m) => Some(m.attrs.as_slice()),
             NodeVariant(ref v) => Some(v.node.attrs.as_slice()),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
index adb97af7490433bcd4f185d0721442d5a0611139..c80c4dc3a22cd8b82ab31b8a639c95456cde912e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -396,6 +396,13 @@ fn visit_mod(&mut self,
     }
 
     fn visit_view_item(&mut self, view_item: &ViewItem, env: ()) {
+        if !self.pass_through_items {
+            if self.visited_outermost {
+                return;
+            } else {
+                self.visited_outermost = true;
+            }
+        }
         match view_item.node {
             ViewItemExternCrate(_, _, node_id) => {
                 self.operation.visit_id(node_id)
@@ -417,7 +424,8 @@ fn visit_view_item(&mut self, view_item: &ViewItem, env: ()) {
                 }
             }
         }
-        visit::walk_view_item(self, view_item, env)
+        visit::walk_view_item(self, view_item, env);
+        self.visited_outermost = false;
     }
 
     fn visit_foreign_item(&mut self, foreign_item: &ForeignItem, env: ()) {
index e1174ea6cc434283c7a7e023ee74ed262c800ecf..1a160cb33aa768ca9c5c289c2aadd03531e78625 100644 (file)
@@ -12,7 +12,7 @@
 use ast::{P, Ident};
 use ast;
 use ast_util;
-use codemap::{Span, respan, DUMMY_SP};
+use codemap::{Span, respan, Spanned, DUMMY_SP};
 use ext::base::ExtCtxt;
 use ext::quote::rt::*;
 use fold::Folder;
@@ -548,8 +548,9 @@ fn expr_method_call(&self, span: Span,
                         expr: @ast::Expr,
                         ident: ast::Ident,
                         mut args: Vec<@ast::Expr> ) -> @ast::Expr {
+        let id = Spanned { node: ident, span: span };
         args.unshift(expr);
-        self.expr(span, ast::ExprMethodCall(ident, Vec::new(), args))
+        self.expr(span, ast::ExprMethodCall(id, Vec::new(), args))
     }
     fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
         self.expr(b.span, ast::ExprBlock(b))
@@ -726,6 +727,7 @@ fn pat_struct(&self, span: Span,
 
     fn arm(&self, _span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm {
         ast::Arm {
+            attrs: vec!(),
             pats: pats,
             guard: None,
             body: expr
index e0b493cd8d9c0d4371e84dd50cca9223dfcb8258..510241588228ce105ba5e86abda2d487220db2ce 100644 (file)
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                              span: Span,
                              mitem: @MetaItem,
                              item: @Item,
                              push: |@Item|) {
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -32,7 +35,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                 explicit_self: borrowed_explicit_self(),
                 args: Vec::new(),
                 ret_ty: Self,
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|c, s, sub| {
                     cs_clone("Clone", c, s, sub)
index 35b7e7c1a666e772cb9f249b107579a8911eabca..92b3788c247443c53791a8eecbb6e8480ac52d09 100644 (file)
@@ -13,6 +13,7 @@
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 pub fn expand_deriving_eq(cx: &mut ExtCtxt,
                           span: Span,
@@ -31,20 +32,22 @@ fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
     }
 
     macro_rules! md (
-        ($name:expr, $f:ident) => {
+        ($name:expr, $f:ident) => { {
+            let inline = cx.meta_word(span, InternedString::new("inline"));
+            let attrs = vec!(cx.attribute(span, inline));
             MethodDef {
                 name: $name,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
                 ret_ty: Literal(Path::new(vec!("bool"))),
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     $f(a, b, c)
                 })
             }
-        }
+        } }
     );
 
     let trait_def = TraitDef {
index afe2d3dae6a71e63a0b4c3cee718e2bec920dea9..dd2f90cfa5fae9ac21880ad8a78513c6567d063d 100644 (file)
@@ -14,6 +14,7 @@
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 pub fn expand_deriving_ord(cx: &mut ExtCtxt,
                            span: Span,
@@ -21,20 +22,22 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
                            item: @Item,
                            push: |@Item|) {
     macro_rules! md (
-        ($name:expr, $op:expr, $equal:expr) => {
+        ($name:expr, $op:expr, $equal:expr) => { {
+            let inline = cx.meta_word(span, InternedString::new("inline"));
+            let attrs = vec!(cx.attribute(span, inline));
             MethodDef {
                 name: $name,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
                 ret_ty: Literal(Path::new(vec!("bool"))),
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|cx, span, substr| {
                     cs_op($op, $equal, cx, span, substr)
                 })
             }
-        }
+        } }
     );
 
     let trait_def = TraitDef {
index d161f9668505fcccd0d0df6563d91492f06492fa..b76caccffecc6095b168fcd4474987124f94bc51 100644 (file)
@@ -13,6 +13,7 @@
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
                                span: Span,
@@ -33,6 +34,11 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @E
                        substr)
     }
 
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let hidden = cx.meta_word(span, InternedString::new("hidden"));
+    let doc = cx.meta_list(span, InternedString::new("doc"), vec!(hidden));
+    let attrs = vec!(cx.attribute(span, inline),
+                     cx.attribute(span, doc));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -46,7 +52,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @E
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(),
                 ret_ty: nil_ty(),
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     cs_total_eq_assert(a, b, c)
index 69c413890e902fa3cf449ab3132d7d6d024fffeb..3ca4f9e28626380da776cee61b04e8c3a0d70cf3 100644 (file)
@@ -14,6 +14,7 @@
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 use std::cmp::{Ordering, Equal, Less, Greater};
 
@@ -22,6 +23,8 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
                                 mitem: @MetaItem,
                                 item: @Item,
                                 push: |@Item|) {
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -35,7 +38,7 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
                 ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     cs_cmp(a, b, c)
index 6d6cdc55d4028825eeff1d001cacb9fb65290576..062f198425b28d0ab7289608e18c26c5063e13ef 100644 (file)
@@ -50,7 +50,7 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
                             Borrowed(None, MutMutable))),
                 ret_ty: Literal(Path::new_(vec!("std", "result", "Result"), None,
                                           vec!(~Self, ~Literal(Path::new_local("__E"))), true)),
-                inline: false,
+                attributes: Vec::new(),
                 const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     decodable_substructure(a, b, c)
index 633674eff5c18438e010c723dca5d10803a1c83a..c225906ed2babafcf00398b5b991b8423cd1fcfc 100644 (file)
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 pub fn expand_deriving_default(cx: &mut ExtCtxt,
                             span: Span,
                             mitem: @MetaItem,
                             item: @Item,
                             push: |@Item|) {
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -32,7 +35,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
                 explicit_self: None,
                 args: Vec::new(),
                 ret_ty: Self,
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     default_substructure(a, b, c)
index acdef8c864509e47851416f1b5a648fb8703edeb..ec3d4e0078bc6c5c0037088705bff066048a5c97 100644 (file)
@@ -121,7 +121,7 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                            vec!(~Tuple(Vec::new()),
                                                 ~Literal(Path::new_local("__E"))),
                                            true)),
-                inline: false,
+                attributes: Vec::new(),
                 const_nonmatching: true,
                 combine_substructure: combine_substructure(|a, b, c| {
                     encodable_substructure(a, b, c)
index 673745b41e865ec36219401b9dbbff193a12c572..bf886e51885d595452e097938196238139b55c55 100644 (file)
@@ -229,8 +229,7 @@ pub struct MethodDef<'a> {
     /// Return type
     pub ret_ty: Ty<'a>,
 
-    /// Whether to mark this as #[inline]
-    pub inline: bool,
+    pub attributes: Vec<ast::Attribute>,
 
     /// if the value of the nonmatching enums is independent of the
     /// actual enum variants, i.e. can use _ => .. match.
@@ -612,23 +611,10 @@ fn create_method(&self,
         let fn_decl = cx.fn_decl(args, ret_type);
         let body_block = cx.block_expr(body);
 
-        let attrs = if self.inline {
-            vec!(
-                cx
-                      .attribute(trait_.span,
-                                 cx
-                                       .meta_word(trait_.span,
-                                                  InternedString::new(
-                                                      "inline")))
-            )
-        } else {
-            Vec::new()
-        };
-
         // Create the method.
         @ast::Method {
             ident: method_ident,
-            attrs: attrs,
+            attrs: self.attributes.clone(),
             generics: fn_generics,
             explicit_self: explicit_self,
             fn_style: ast::NormalFn,
@@ -822,26 +808,25 @@ fn build_enum_match(&self,
                                 "no self match on an enum in \
                                 generic `deriving`");
             }
+
+            // `ref` inside let matches is buggy. Causes havoc wih rusc.
+            // let (variant_index, ref self_vec) = matches_so_far[0];
+            let (variant, self_vec) = match matches_so_far.get(0) {
+                &(_, v, ref s) => (v, s)
+            };
+
             // we currently have a vec of vecs, where each
             // subvec is the fields of one of the arguments,
             // but if the variants all match, we want this as
             // vec of tuples, where each tuple represents a
             // field.
 
-            let substructure;
-
             // most arms don't have matching variants, so do a
             // quick check to see if they match (even though
             // this means iterating twice) instead of being
             // optimistic and doing a pile of allocations etc.
-            match matching {
+            let substructure = match matching {
                 Some(variant_index) => {
-                    // `ref` inside let matches is buggy. Causes havoc wih rusc.
-                    // let (variant_index, ref self_vec) = matches_so_far[0];
-                    let (variant, self_vec) = match matches_so_far.get(0) {
-                        &(_, v, ref s) => (v, s)
-                    };
-
                     let mut enum_matching_fields = Vec::from_elem(self_vec.len(), Vec::new());
 
                     for triple in matches_so_far.tail().iter() {
@@ -864,12 +849,12 @@ fn build_enum_match(&self,
                             other: (*other).clone()
                         }
                     }).collect();
-                    substructure = EnumMatching(variant_index, variant, field_tuples);
+                    EnumMatching(variant_index, variant, field_tuples)
                 }
                 None => {
-                    substructure = EnumNonMatching(matches_so_far.as_slice());
+                    EnumNonMatching(matches_so_far.as_slice())
                 }
-            }
+            };
             self.call_substructure_method(cx, trait_, type_ident,
                                           self_args, nonself_args,
                                           &substructure)
index 9e160b0e35dfc8e292558032a8fc8fe436ff9936..d367ae61e0b8f3e86d62e417821d0607620110eb 100644 (file)
@@ -14,6 +14,7 @@
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                             span: Span,
@@ -34,6 +35,8 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
          LifetimeBounds::empty(),
          Path::new(vec!("std", "hash", "sip", "SipState")))
     };
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let attrs = vec!(cx.attribute(span, inline));
     let hash_trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -47,7 +50,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(Ptr(~Literal(args), Borrowed(None, MutMutable))),
                 ret_ty: nil_ty(),
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     hash_substructure(a, b, c)
index e42a3c67e34ea7201dd86aa0dd917acf80ab49b1..9978a2edce9c120144c5fcbaf05c435e186d6541 100644 (file)
@@ -21,6 +21,8 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                       mitem: @MetaItem,
                                       item: @Item,
                                       push: |@Item|) {
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -38,8 +40,8 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                            None,
                                            vec!(~Self),
                                            true)),
-                // liable to cause code-bloat
-                inline: true,
+                // #[inline] liable to cause code-bloat
+                attributes: attrs.clone(),
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|c, s, sub| {
                     cs_from("i64", c, s, sub)
@@ -55,8 +57,8 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                            None,
                                            vec!(~Self),
                                            true)),
-                // liable to cause code-bloat
-                inline: true,
+                // #[inline] liable to cause code-bloat
+                attributes: attrs,
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|c, s, sub| {
                     cs_from("u64", c, s, sub)
@@ -110,6 +112,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
 
                         // arm for `_ if $guard => $body`
                         let arm = ast::Arm {
+                            attrs: vec!(),
                             pats: vec!(cx.pat_wild(span)),
                             guard: Some(guard),
                             body: body,
@@ -129,6 +132,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
 
             // arm for `_ => None`
             let arm = ast::Arm {
+                attrs: vec!(),
                 pats: vec!(cx.pat_wild(trait_span)),
                 guard: None,
                 body: cx.expr_none(trait_span),
index 09c3abf42b8cd9920ff54a96f64a5a94e00dd7ca..23877dd29ea79d6c55e909cb7309e8ea33e2416d 100644 (file)
@@ -41,7 +41,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                         Borrowed(None, ast::MutMutable))
                 ),
                 ret_ty: Self,
-                inline: false,
+                attributes: Vec::new(),
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     rand_substructure(a, b, c)
index 7098d0dd6efea4218051b6f8e678d938288eb3d9..b9725361538d1fbc9500d63f640b07711ab9cab1 100644 (file)
@@ -42,7 +42,7 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(fmtr),
                 ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
-                inline: false,
+                attributes: Vec::new(),
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     show_substructure(a, b, c)
index 0aeeabcaeabb0d25a96dd49ecfe2cdd559b0a3b8..449851dd3ea5913aecc03654a5d5f5f55958c801 100644 (file)
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
+use parse::token::InternedString;
 
 pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                             span: Span,
                             mitem: @MetaItem,
                             item: @Item,
                             push: |@Item|) {
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -32,7 +35,7 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                 explicit_self: None,
                 args: Vec::new(),
                 ret_ty: Self,
-                inline: true,
+                attributes: attrs.clone(),
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|a, b, c| {
                     zero_substructure(a, b, c)
@@ -44,7 +47,7 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                 explicit_self: borrowed_explicit_self(),
                 args: Vec::new(),
                 ret_ty: Literal(Path::new(vec!("bool"))),
-                inline: true,
+                attributes: attrs,
                 const_nonmatching: false,
                 combine_substructure: combine_substructure(|cx, span, substr| {
                     cs_and(|cx, span, _, _| cx.span_bug(span,
index 04b289b9fca4676ec589adec4f5f44ce21ce79c1..ae82a07601baf27182376555bff002b7b30495cf 100644 (file)
@@ -119,6 +119,7 @@ fn fold_stmt(&mut self, s: &Stmt) -> SmallVector<@Stmt> {
 
     fn fold_arm(&mut self, a: &Arm) -> Arm {
         Arm {
+            attrs: a.attrs.iter().map(|x| fold_attribute_(*x, self)).collect(),
             pats: a.pats.iter().map(|x| self.fold_pat(*x)).collect(),
             guard: a.guard.map(|x| self.fold_expr(x)),
             body: self.fold_expr(a.body),
@@ -797,7 +798,7 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
         }
         ExprMethodCall(i, ref tps, ref args) => {
             ExprMethodCall(
-                folder.fold_ident(i),
+                respan(i.span, folder.fold_ident(i.node)),
                 tps.iter().map(|&x| folder.fold_ty(x)).collect(),
                 args.iter().map(|&x| folder.fold_expr(x)).collect())
         }
index 8808312bed75951e3060fe78c72bea5245571c78..974077956d1c744fcab415bca23577bfc6975978 100644 (file)
@@ -1646,7 +1646,11 @@ pub fn mk_call(&mut self, f: @Expr, args: Vec<@Expr> ) -> ast::Expr_ {
         ExprCall(f, args)
     }
 
-    fn mk_method_call(&mut self, ident: Ident, tps: Vec<P<Ty>> , args: Vec<@Expr> ) -> ast::Expr_ {
+    fn mk_method_call(&mut self,
+                      ident: ast::SpannedIdent,
+                      tps: Vec<P<Ty>>,
+                      args: Vec<@Expr>)
+                      -> ast::Expr_ {
         ExprMethodCall(ident, tps, args)
     }
 
@@ -1919,6 +1923,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
             if self.eat(&token::DOT) {
                 match self.token {
                   token::IDENT(i, _) => {
+                    let dot = self.last_span.hi;
                     hi = self.span.hi;
                     self.bump();
                     let (_, tys) = if self.eat(&token::MOD_SEP) {
@@ -1940,7 +1945,8 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
                             hi = self.last_span.hi;
 
                             es.unshift(e);
-                            let nd = self.mk_method_call(i, tys, es);
+                            let id = spanned(dot, hi, i);
+                            let nd = self.mk_method_call(id, tys, es);
                             e = self.mk_expr(lo, hi, nd);
                         }
                         _ => {
@@ -2539,6 +2545,7 @@ fn parse_match_expr(&mut self) -> @Expr {
         self.commit_expr_expecting(discriminant, token::LBRACE);
         let mut arms: Vec<Arm> = Vec::new();
         while self.token != token::RBRACE {
+            let attrs = self.parse_outer_attributes();
             let pats = self.parse_pats();
             let mut guard = None;
             if self.eat_keyword(keywords::If) {
@@ -2557,7 +2564,12 @@ fn parse_match_expr(&mut self) -> @Expr {
                 self.eat(&token::COMMA);
             }
 
-            arms.push(ast::Arm { pats: pats, guard: guard, body: expr });
+            arms.push(ast::Arm {
+                attrs: attrs,
+                pats: pats,
+                guard: guard,
+                body: expr
+            });
         }
         let hi = self.span.hi;
         self.bump();
index f768bf22ce0ceb190d5cbbc5c7f2e6bedc8828dc..9d3f7cbc69a89b07a12291bd6f8373a649cb36cf 100644 (file)
@@ -1208,7 +1208,7 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 let base_args = args.slice_from(1);
                 try!(self.print_expr(*args.get(0)));
                 try!(word(&mut self.s, "."));
-                try!(self.print_ident(ident));
+                try!(self.print_ident(ident.node));
                 if tys.len() > 0u {
                     try!(word(&mut self.s, "::<"));
                     try!(self.commasep(Inconsistent, tys.as_slice(),
@@ -1286,9 +1286,14 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 try!(self.bopen());
                 let len = arms.len();
                 for (i, arm) in arms.iter().enumerate() {
-                    try!(space(&mut self.s));
+                    // I have no idea why this check is necessary, but here it
+                    // is :(
+                    if arm.attrs.is_empty() {
+                        try!(space(&mut self.s));
+                    }
                     try!(self.cbox(indent_unit));
                     try!(self.ibox(0u));
+                    try!(self.print_outer_attributes(arm.attrs.as_slice()));
                     let mut first = true;
                     for p in arm.pats.iter() {
                         if first {
index 758b7532acc20bafa0558dcdddf0ff7c561ab2f4..6a1b7b4d073769bdc7cb69b171ff194a512daf63 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 {
@@ -257,7 +257,26 @@ pub struct TestOpts {
     pub ratchet_noise_percent: Option<f64>,
     pub save_metrics: Option<Path>,
     pub test_shard: Option<(uint,uint)>,
-    pub logfile: Option<Path>
+    pub logfile: Option<Path>,
+    pub nocapture: bool,
+}
+
+impl TestOpts {
+    #[cfg(test)]
+    fn new() -> TestOpts {
+        TestOpts {
+            filter: None,
+            run_ignored: false,
+            run_tests: false,
+            run_benchmarks: false,
+            ratchet_metrics: None,
+            ratchet_noise_percent: None,
+            save_metrics: None,
+            test_shard: None,
+            logfile: None,
+            nocapture: false,
+        }
+    }
 }
 
 /// Result of parsing the options.
@@ -280,7 +299,9 @@ fn optgroups() -> Vec<getopts::OptGroup> {
       getopts::optopt("", "logfile", "Write logs to the specified file instead \
                           of stdout", "PATH"),
       getopts::optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite",
-                     "A.B"))
+                     "A.B"),
+      getopts::optflag("", "nocapture", "don't capture stdout/stderr of each \
+                                         task, allow printing directly"))
 }
 
 fn usage(binary: &str, helpstr: &str) {
@@ -295,6 +316,10 @@ fn usage(binary: &str, helpstr: &str) {
 By default, all tests are run in parallel. This can be altered with the
 RUST_TEST_TASKS environment variable when running tests (set it to 1).
 
+All tests have their standard output and standard error captured by default.
+This can be overridden with the --nocapture flag or the RUST_TEST_NOCAPTURE=1
+environment variable. Logging is not captured by default.
+
 Test Attributes:
 
     #[test]        - Indicates a function is a test to be run. This function
@@ -351,6 +376,11 @@ pub fn parse_opts(args: &[~str]) -> Option<OptRes> {
     let test_shard = matches.opt_str("test-shard");
     let test_shard = opt_shard(test_shard);
 
+    let mut nocapture = matches.opt_present("nocapture");
+    if !nocapture {
+        nocapture = os::getenv("RUST_TEST_NOCAPTURE").is_some();
+    }
+
     let test_opts = TestOpts {
         filter: filter,
         run_ignored: run_ignored,
@@ -360,7 +390,8 @@ pub fn parse_opts(args: &[~str]) -> Option<OptRes> {
         ratchet_noise_percent: ratchet_noise_percent,
         save_metrics: save_metrics,
         test_shard: test_shard,
-        logfile: logfile
+        logfile: logfile,
+        nocapture: nocapture,
     };
 
     Some(Ok(test_opts))
@@ -843,7 +874,7 @@ fn run_tests(opts: &TestOpts,
                 // that hang forever.
                 try!(callback(TeWait(test.desc.clone(), test.testfn.padding())));
             }
-            run_test(!opts.run_tests, test, tx.clone());
+            run_test(opts, !opts.run_tests, test, tx.clone());
             pending += 1;
         }
 
@@ -859,7 +890,7 @@ fn run_tests(opts: &TestOpts,
     // (this includes metric fns)
     for b in filtered_benchs_and_metrics.move_iter() {
         try!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
-        run_test(!opts.run_benchmarks, b, tx.clone());
+        run_test(opts, !opts.run_benchmarks, b, tx.clone());
         let (test, result, stdout) = rx.recv();
         try!(callback(TeResult(test, result, stdout)));
     }
@@ -941,7 +972,8 @@ fn filter(test: TestDescAndFn) -> Option<TestDescAndFn> {
     }
 }
 
-pub fn run_test(force_ignore: bool,
+pub fn run_test(opts: &TestOpts,
+                force_ignore: bool,
                 test: TestDescAndFn,
                 monitor_ch: Sender<MonitorMsg>) {
 
@@ -955,18 +987,23 @@ pub fn run_test(force_ignore: bool,
     #[allow(deprecated_owned_vector)]
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: Sender<MonitorMsg>,
+                      nocapture: bool,
                       testfn: proc():Send) {
         spawn(proc() {
             let (tx, rx) = channel();
             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(),
             });
-            task.opts.stdout = Some(~stdout as ~Writer:Send);
-            task.opts.stderr = Some(~stderr as ~Writer:Send);
+            if nocapture {
+                drop((stdout, stderr));
+            } else {
+                task.opts.stdout = Some(~stdout as ~Writer:Send);
+                task.opts.stderr = Some(~stderr as ~Writer:Send);
+            }
             let result_future = task.future_result();
             task.spawn(testfn);
 
@@ -1000,8 +1037,9 @@ fn run_test_inner(desc: TestDesc,
             monitor_ch.send((desc, TrMetrics(mm), Vec::new()));
             return;
         }
-        DynTestFn(f) => run_test_inner(desc, monitor_ch, f),
-        StaticTestFn(f) => run_test_inner(desc, monitor_ch, proc() f())
+        DynTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, f),
+        StaticTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture,
+                                          proc() f())
     }
 }
 
@@ -1320,7 +1358,7 @@ pub fn do_not_run_ignored_tests() {
             testfn: DynTestFn(proc() f()),
         };
         let (tx, rx) = channel();
-        run_test(false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx);
         let (_, res, _) = rx.recv();
         assert!(res != TrOk);
     }
@@ -1337,7 +1375,7 @@ fn f() { }
             testfn: DynTestFn(proc() f()),
         };
         let (tx, rx) = channel();
-        run_test(false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx);
         let (_, res, _) = rx.recv();
         assert!(res == TrIgnored);
     }
@@ -1354,7 +1392,7 @@ fn test_should_fail() {
             testfn: DynTestFn(proc() f()),
         };
         let (tx, rx) = channel();
-        run_test(false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx);
         let (_, res, _) = rx.recv();
         assert!(res == TrOk);
     }
@@ -1371,7 +1409,7 @@ fn f() { }
             testfn: DynTestFn(proc() f()),
         };
         let (tx, rx) = channel();
-        run_test(false, desc, tx);
+        run_test(&TestOpts::new(), false, desc, tx);
         let (_, res, _) = rx.recv();
         assert!(res == TrFailed);
     }
@@ -1401,17 +1439,9 @@ pub fn filter_for_ignored_option() {
         // When we run ignored tests the test filter should filter out all the
         // unignored tests and flip the ignore flag on the rest to false
 
-        let opts = TestOpts {
-            filter: None,
-            run_ignored: true,
-            logfile: None,
-            run_tests: true,
-            run_benchmarks: false,
-            ratchet_noise_percent: None,
-            ratchet_metrics: None,
-            save_metrics: None,
-            test_shard: None
-        };
+        let mut opts = TestOpts::new();
+        opts.run_tests = true;
+        opts.run_ignored = true;
 
         let tests = vec!(
             TestDescAndFn {
@@ -1439,17 +1469,8 @@ pub fn filter_for_ignored_option() {
 
     #[test]
     pub fn sort_tests() {
-        let opts = TestOpts {
-            filter: None,
-            run_ignored: false,
-            logfile: None,
-            run_tests: true,
-            run_benchmarks: false,
-            ratchet_noise_percent: None,
-            ratchet_metrics: None,
-            save_metrics: None,
-            test_shard: None
-        };
+        let mut opts = TestOpts::new();
+        opts.run_tests = true;
 
         let names =
             vec!("sha1::test".to_owned(), "int::test_to_str".to_owned(), "int::test_pow".to_owned(),
index 800b56fe6af21ffd8e56aee8cf12dd758f5bbdf1..43495892ded622de51eba7362c5ffae1ed50c9cc 160000 (submodule)
--- a/src/libuv
+++ b/src/libuv
@@ -1 +1 @@
-Subproject commit 800b56fe6af21ffd8e56aee8cf12dd758f5bbdf1
+Subproject commit 43495892ded622de51eba7362c5ffae1ed50c9cc
index 961455b9093bec909c45d1a1bd83f99b09b3b9f4..8bd7aa54751753bb0bb72e540016f2858e5c19ca 100644 (file)
@@ -1,2 +1,2 @@
 # Change the contents of this file to force a full rebuild of libuv
-2014-02-16
+2014-04-18
index 32bac73debfb9609bc0d228a226e4c69ef0671e8..021dda497655039d165990077012ed929f4fcf06 100644 (file)
@@ -75,7 +75,7 @@ LLVMRustCreateTargetMachine(const char *triple,
     const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
                                                                  Error);
     if (TheTarget == NULL) {
-        LLVMRustError = Error.c_str();
+        LLVMRustSetLastError(Error.c_str());
         return NULL;
     }
 
@@ -178,7 +178,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
   raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
 #endif
   if (ErrorInfo != "") {
-    LLVMRustError = ErrorInfo.c_str();
+    LLVMRustSetLastError(ErrorInfo.c_str());
     return false;
   }
   formatted_raw_ostream FOS(OS);
index 3fe1b1380da01498eedcbeda9fbf8db3628d82b4..ec33b750358bbb857f963157322136a7d8234cbb 100644 (file)
@@ -23,18 +23,28 @@ using namespace llvm;
 using namespace llvm::sys;
 using namespace llvm::object;
 
-const char *LLVMRustError;
+static char *LastError;
 
 extern "C" LLVMMemoryBufferRef
 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
   LLVMMemoryBufferRef MemBuf = NULL;
-  LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
-    const_cast<char **>(&LLVMRustError));
+  char *err = NULL;
+  LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf, &err);
+  if (err != NULL) {
+    LLVMRustSetLastError(err);
+  }
   return MemBuf;
 }
 
-extern "C" const char *LLVMRustGetLastError(void) {
-  return LLVMRustError;
+extern "C" char *LLVMRustGetLastError(void) {
+  char *ret = LastError;
+  LastError = NULL;
+  return ret;
+}
+
+void LLVMRustSetLastError(const char *err) {
+  free((void*) LastError);
+  LastError = strdup(err);
 }
 
 extern "C" void
@@ -609,14 +619,14 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
     ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
     if (!Src) {
-        LLVMRustError = Src.getError().message().c_str();
+        LLVMRustSetLastError(Src.getError().message().c_str());
         delete buf;
         return false;
     }
 
     std::string Err;
     if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
-        LLVMRustError = Err.c_str();
+        LLVMRustSetLastError(Err.c_str());
         return false;
     }
     return true;
@@ -629,13 +639,13 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     std::string Err;
     Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
     if (!Src) {
-        LLVMRustError = Err.c_str();
+        LLVMRustSetLastError(Err.c_str());
         delete buf;
         return false;
     }
 
     if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
-        LLVMRustError = Err.c_str();
+        LLVMRustSetLastError(Err.c_str());
         return false;
     }
     return true;
@@ -648,12 +658,12 @@ LLVMRustOpenArchive(char *path) {
     std::unique_ptr<MemoryBuffer> buf;
     error_code err = MemoryBuffer::getFile(path, buf);
     if (err) {
-        LLVMRustError = err.message().c_str();
+        LLVMRustSetLastError(err.message().c_str());
         return NULL;
     }
     Archive *ret = new Archive(buf.release(), err);
     if (err) {
-        LLVMRustError = err.message().c_str();
+        LLVMRustSetLastError(err.message().c_str());
         return NULL;
     }
     return ret;
@@ -664,12 +674,12 @@ LLVMRustOpenArchive(char *path) {
     OwningPtr<MemoryBuffer> buf;
     error_code err = MemoryBuffer::getFile(path, buf);
     if (err) {
-        LLVMRustError = err.message().c_str();
+        LLVMRustSetLastError(err.message().c_str());
         return NULL;
     }
     Archive *ret = new Archive(buf.take(), err);
     if (err) {
-        LLVMRustError = err.message().c_str();
+        LLVMRustSetLastError(err.message().c_str());
         return NULL;
     }
     return ret;
index 42c60e72baba7e0c3aab7dd0f99ec54139daac63..5722eea48d7d83e56c9f27fcc888c0707ba70152 100644 (file)
@@ -68,4 +68,4 @@
 #include <unistd.h>
 #endif
 
-extern const char* LLVMRustError;
+void LLVMRustSetLastError(const char*);
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-managed-pointer-deref-scope.rs b/src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs
new file mode 100644 (file)
index 0000000..4695360
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+// Verify that managed pointers scope is treated like ownoed pointers.
+// regresion test for #11586
+
+#![feature(managed_boxes)]
+
+fn foo<'a>(x: &'a @int) -> &'a int {
+    match x {
+        &ref y => {
+            &**y // Do not expect an error here
+        }
+    }
+}
+
+fn bar() {
+    let a = 3;
+    let mut y = &a;
+    if true {
+        let x = @3;
+        y = &*x; //~ ERROR `*x` does not live long enough
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/borrowck-preserve-box-in-field.rs b/src/test/compile-fail/borrowck-preserve-box-in-field.rs
new file mode 100644 (file)
index 0000000..ff13845
--- /dev/null
@@ -0,0 +1,39 @@
+// ignore-pretty
+
+// Copyright 2012-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.
+
+// exec-env:RUST_POISON_ON_FREE=1
+
+#![feature(managed_boxes)]
+
+fn borrow(x: &int, f: |x: &int|) {
+    let before = *x;
+    f(x);
+    let after = *x;
+    assert_eq!(before, after);
+}
+
+struct F { f: ~int }
+
+pub fn main() {
+    let mut x = @F {f: ~3};
+    borrow(x.f, |b_x| {
+    //~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
+        assert_eq!(*b_x, 3);
+        assert_eq!(&(*x.f) as *int, &(*b_x) as *int);
+        //~^ NOTE borrow occurs due to use of `x` in closure
+        x = @F {f: ~4};
+
+        println!("&*b_x = {:p}", &(*b_x));
+        assert_eq!(*b_x, 3);
+        assert!(&(*x.f) as *int != &(*b_x) as *int);
+    })
+}
diff --git a/src/test/compile-fail/borrowck-preserve-box-in-uniq.rs b/src/test/compile-fail/borrowck-preserve-box-in-uniq.rs
new file mode 100644 (file)
index 0000000..b06eb0d
--- /dev/null
@@ -0,0 +1,39 @@
+// ignore-pretty
+
+// Copyright 2012-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.
+
+// exec-env:RUST_POISON_ON_FREE=1
+
+#![feature(managed_boxes)]
+
+fn borrow(x: &int, f: |x: &int|) {
+    let before = *x;
+    f(x);
+    let after = *x;
+    assert_eq!(before, after);
+}
+
+struct F { f: ~int }
+
+pub fn main() {
+    let mut x = ~@F{f: ~3};
+    borrow(x.f, |b_x| {
+    //~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
+        assert_eq!(*b_x, 3);
+        assert_eq!(&(*x.f) as *int, &(*b_x) as *int);
+        //~^ NOTE  borrow occurs due to use of `x` in closure
+        *x = @F{f: ~4};
+
+        println!("&*b_x = {:p}", &(*b_x));
+        assert_eq!(*b_x, 3);
+        assert!(&(*x.f) as *int != &(*b_x) as *int);
+    })
+}
diff --git a/src/test/compile-fail/borrowck-preserve-box.rs b/src/test/compile-fail/borrowck-preserve-box.rs
new file mode 100644 (file)
index 0000000..1a920c7
--- /dev/null
@@ -0,0 +1,37 @@
+// ignore-pretty
+
+// Copyright 2012-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.
+
+// exec-env:RUST_POISON_ON_FREE=1
+
+#![feature(managed_boxes)]
+
+fn borrow(x: &int, f: |x: &int|) {
+    let before = *x;
+    f(x);
+    let after = *x;
+    assert_eq!(before, after);
+}
+
+pub fn main() {
+    let mut x = @3;
+    borrow(x, |b_x| {
+    //~^ ERROR cannot borrow `x` as mutable because `*x` is also borrowed as immutable
+        assert_eq!(*b_x, 3);
+        assert_eq!(&(*x) as *int, &(*b_x) as *int);
+        //~^ NOTE borrow occurs due to use of `x` in closure
+        x = @22;
+
+        println!("&*b_x = {:p}", &(*b_x));
+        assert_eq!(*b_x, 3);
+        assert!(&(*x) as *int != &(*b_x) as *int);
+    })
+}
diff --git a/src/test/compile-fail/borrowck-preserve-cond-box.rs b/src/test/compile-fail/borrowck-preserve-cond-box.rs
new file mode 100644 (file)
index 0000000..7000e23
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2012 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.
+
+// exec-env:RUST_POISON_ON_FREE=1
+
+#![feature(managed_boxes)]
+
+fn testfn(cond: bool) {
+    let mut x = @3;
+    let mut y = @4;
+
+    // borrow x and y
+    let r_x = &*x;
+    let r_y = &*y;
+    let mut r = r_x;
+    let mut exp = 3;
+
+    if cond {
+        r = r_y;
+        exp = 4;
+    }
+
+    println!("*r = {}, exp = {}", *r, exp);
+    assert_eq!(*r, exp);
+
+    x = @5; //~ERROR cannot assign to `x` because it is borrowed
+    y = @6; //~ERROR cannot assign to `y` because it is borrowed
+
+    println!("*r = {}, exp = {}", *r, exp);
+    assert_eq!(*r, exp);
+    assert_eq!(x, @5);
+    assert_eq!(y, @6);
+}
+
+pub fn main() {
+    testfn(true);
+    testfn(false);
+}
diff --git a/src/test/compile-fail/borrowck-preserve-expl-deref.rs b/src/test/compile-fail/borrowck-preserve-expl-deref.rs
new file mode 100644 (file)
index 0000000..aeabf6d
--- /dev/null
@@ -0,0 +1,39 @@
+// ignore-pretty
+
+// Copyright 2012-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.
+
+// exec-env:RUST_POISON_ON_FREE=1
+
+#![feature(managed_boxes)]
+
+fn borrow(x: &int, f: |x: &int|) {
+    let before = *x;
+    f(x);
+    let after = *x;
+    assert_eq!(before, after);
+}
+
+struct F { f: ~int }
+
+pub fn main() {
+    let mut x = @F {f: ~3};
+    borrow((*x).f, |b_x| {
+    //~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
+        assert_eq!(*b_x, 3);
+        assert_eq!(&(*x.f) as *int, &(*b_x) as *int);
+        //~^ NOTE borrow occurs due to use of `x` in closure
+        x = @F {f: ~4};
+
+        println!("&*b_x = {:p}", &(*b_x));
+        assert_eq!(*b_x, 3);
+        assert!(&(*x.f) as *int != &(*b_x) as *int);
+    })
+}
diff --git a/src/test/compile-fail/lint-directives-on-use-items-issue-10534.rs b/src/test/compile-fail/lint-directives-on-use-items-issue-10534.rs
new file mode 100644 (file)
index 0000000..e920bfd
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+#![deny(unused_imports)]
+
+// The aim of this test is to ensure that deny/allow/warn directives
+// are applied to individual "use" statements instead of silently
+// ignored.
+
+#[allow(dead_code)]
+mod a { pub static x: int = 3; pub static y: int = 4; }
+
+mod b {
+    use a::x; //~ ERROR: unused import
+    #[allow(unused_imports)]
+    use a::y; // no error here
+}
+
+#[allow(unused_imports)]
+mod c {
+    use a::x;
+    #[deny(unused_imports)]
+    use a::y; //~ ERROR: unused import
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/method-call-err-msg.rs b/src/test/compile-fail/method-call-err-msg.rs
new file mode 100644 (file)
index 0000000..3610a0e
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2012-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.
+
+// Test that parameter cardinality or missing method error gets span exactly.
+
+pub struct Foo;
+impl Foo {
+    fn zero(self) -> Foo { self }
+    fn one(self, _: int) -> Foo { self }
+    fn two(self, _: int, _: int) -> Foo { self }
+}
+
+fn main() {
+    let x = Foo;
+    x.zero(0)   //~ ERROR this function takes 0 parameters but 1 parameter was supplied
+     .one()     //~ ERROR this function takes 1 parameter but 0 parameters were supplied
+     .two(0);   //~ ERROR this function takes 2 parameters but 1 parameter was supplied
+
+    let y = Foo;
+    y.zero()
+     .take()    //~ ERROR type `Foo` does not implement any method in scope named `take`
+     .one(0);
+}
diff --git a/src/test/compile-fail/regions-appearance-constraint.rs b/src/test/compile-fail/regions-appearance-constraint.rs
new file mode 100644 (file)
index 0000000..68bbebb
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2012 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.
+
+// Test no-special rooting is used for managed boxes
+
+#![feature(managed_boxes)]
+
+fn testfn(cond: bool) {
+    let mut x = @3;
+    let mut y = @4;
+
+    let mut a = &*x;
+
+    let mut exp = 3;
+    if cond {
+        a = &*y;
+
+        exp = 4;
+    }
+
+    x = @5; //~ERROR cannot assign to `x` because it is borrowed
+    y = @6; //~ERROR cannot assign to `y` because it is borrowed
+    assert_eq!(*a, exp);
+    assert_eq!(x, @5);
+    assert_eq!(y, @6);
+}
+
+pub fn main() {}
index b069a35ad7a262b414bcf987a30371e62f141400..1508349344c9a2125d71ae123fa3820793ef9811 100644 (file)
@@ -20,7 +20,7 @@ fn x_coord<'r>(p: &'r point) -> &'r int {
 }
 
 fn foo(p: @point) -> &int {
-    let xc = x_coord(p); //~ ERROR cannot root
+    let xc = x_coord(p); //~ ERROR `*p` does not live long enough
     assert_eq!(*xc, 3);
     return xc;
 }
index 9be8a5fef4dee3822e176e5cb8f8886b436a0c94..3cd70ce6c8a31511a141abbc80ac3c7aac6de492 100644 (file)
@@ -19,7 +19,7 @@ fn foo(cond: || -> bool, make_box: || -> @int) {
 
         // Here we complain because the resulting region
         // of this borrow is the fn body as a whole.
-        y = borrow(x); //~ ERROR cannot root
+        y = borrow(x); //~ ERROR `*x` does not live long enough
 
         assert_eq!(*x, *y);
         if cond() { break; }
diff --git a/src/test/compile-fail/struct-field-assignability.rs b/src/test/compile-fail/struct-field-assignability.rs
new file mode 100644 (file)
index 0000000..68a1726
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+#![feature(managed_boxes)]
+
+struct Foo<'a> {
+    x: &'a int
+}
+
+pub fn main() {
+    let f = Foo { x: @3 }; //~ ERROR borrowed value does not live long enough
+    assert_eq!(*f.x, 3);
+}
index 9608b7e6b202335e34cc72f99221770ea9296919..614b8e3a5ab67904e60ff1acaea0882b0bddca40 100644 (file)
@@ -9,18 +9,7 @@
 // except according to those terms.
 #![feature(struct_variant)]
 
-// Test `type` types not allowed in fields or local variables.
-
-/*trait T for type {}
-
-fn f5<type X>(x: &X) {
-    let _: X; // ERROR local variable with dynamically sized type X
-    let _: (int, (X, int)); // ERROR local variable with dynamically sized type (int,(X,int))
-}
-fn f6<type X: T>(x: &X) {
-    let _: X; // ERROR local variable with dynamically sized type X
-    let _: (int, (X, int)); // ERROR local variable with dynamically sized type (int,(X,int))
-}*/
+// Test `type` types not allowed in fields.
 
 struct S1<type X> {
     f1: X, //~ ERROR type `f1` is dynamically sized. dynamically sized types may only appear as the
diff --git a/src/test/compile-fail/unsized6.rs b/src/test/compile-fail/unsized6.rs
new file mode 100644 (file)
index 0000000..a763373
--- /dev/null
@@ -0,0 +1,43 @@
+// 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.
+
+// Test `type` local variables.
+
+trait T for type {}
+
+fn f1<type X>(x: &X) {
+    let _: X; //~ERROR variable `_` has dynamically sized type `X`
+    let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
+    let y: X; //~ERROR variable `y` has dynamically sized type `X`
+    let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
+}
+fn f2<type X: T>(x: &X) {
+    let _: X; //~ERROR variable `_` has dynamically sized type `X`
+    let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
+    let y: X; //~ERROR variable `y` has dynamically sized type `X`
+    let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
+}
+
+fn f3<type X>(x1: ~X, x2: ~X, x3: ~X) {
+    let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
+    let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
+    let (y, z) = (*x3, 4); //~ERROR variable `y` has dynamically sized type `X`
+}
+fn f4<type X: T>(x1: ~X, x2: ~X, x3: ~X) {
+    let y: X = *x1;         //~ERROR variable `y` has dynamically sized type `X`
+    let y = *x2;            //~ERROR variable `y` has dynamically sized type `X`
+    let (y, z) = (*x3, 4); //~ERROR variable `y` has dynamically sized type `X`
+}
+
+fn g1<type X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g2<type X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+
+pub fn main() {
+}
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()
 }
diff --git a/src/test/run-make/error-writing-dependencies/Makefile b/src/test/run-make/error-writing-dependencies/Makefile
new file mode 100644 (file)
index 0000000..9f91618
--- /dev/null
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+all:
+       # Let's get a nice error message
+       $(RUSTC) foo.rs --dep-info foo/bar/baz 2>&1 | \
+               grep "error writing dependencies"
+       # Make sure the filename shows up
+       $(RUSTC) foo.rs --dep-info foo/bar/baz 2>&1 | grep "baz"
diff --git a/src/test/run-make/error-writing-dependencies/foo.rs b/src/test/run-make/error-writing-dependencies/foo.rs
new file mode 100644 (file)
index 0000000..8ae3d07
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+fn main() {}
diff --git a/src/test/run-make/weird-output-filenames/Makefile b/src/test/run-make/weird-output-filenames/Makefile
new file mode 100644 (file)
index 0000000..9d852bc
--- /dev/null
@@ -0,0 +1,9 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs -o $(TMPDIR)/.foo
+       rm $(TMPDIR)/.foo
+       $(RUSTC) foo.rs -o $(TMPDIR)/.foo.bar
+       rm $(TMPDIR)/.foo.bar
+       $(RUSTC) foo.rs -o $(TMPDIR)/+foo+bar
+       rm $(TMPDIR)/+foo+bar
diff --git a/src/test/run-make/weird-output-filenames/foo.rs b/src/test/run-make/weird-output-filenames/foo.rs
new file mode 100644 (file)
index 0000000..8ae3d07
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+fn main() {}
diff --git a/src/test/run-pass/borrowck-preserve-box-in-field.rs b/src/test/run-pass/borrowck-preserve-box-in-field.rs
deleted file mode 100644 (file)
index f05b8c6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// ignore-pretty
-
-// Copyright 2012-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.
-
-// exec-env:RUST_POISON_ON_FREE=1
-
-#![feature(managed_boxes)]
-
-fn borrow(x: &int, f: |x: &int|) {
-    let before = *x;
-    f(x);
-    let after = *x;
-    assert_eq!(before, after);
-}
-
-struct F { f: ~int }
-
-pub fn main() {
-    let mut x = @F {f: ~3};
-    borrow(x.f, |b_x| {
-        assert_eq!(*b_x, 3);
-        assert_eq!(&(*x.f) as *int, &(*b_x) as *int);
-        x = @F {f: ~4};
-
-        println!("&*b_x = {:p}", &(*b_x));
-        assert_eq!(*b_x, 3);
-        assert!(&(*x.f) as *int != &(*b_x) as *int);
-    })
-}
diff --git a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs
deleted file mode 100644 (file)
index 0896d4d..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// ignore-pretty
-
-// Copyright 2012-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.
-
-// exec-env:RUST_POISON_ON_FREE=1
-
-#![feature(managed_boxes)]
-
-fn borrow(x: &int, f: |x: &int|) {
-    let before = *x;
-    f(x);
-    let after = *x;
-    assert_eq!(before, after);
-}
-
-struct F { f: ~int }
-
-pub fn main() {
-    let mut x = ~@F{f: ~3};
-    borrow(x.f, |b_x| {
-        assert_eq!(*b_x, 3);
-        assert_eq!(&(*x.f) as *int, &(*b_x) as *int);
-        *x = @F{f: ~4};
-
-        println!("&*b_x = {:p}", &(*b_x));
-        assert_eq!(*b_x, 3);
-        assert!(&(*x.f) as *int != &(*b_x) as *int);
-    })
-}
diff --git a/src/test/run-pass/borrowck-preserve-box.rs b/src/test/run-pass/borrowck-preserve-box.rs
deleted file mode 100644 (file)
index cfb9a4b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// ignore-pretty
-
-// Copyright 2012-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.
-
-// exec-env:RUST_POISON_ON_FREE=1
-
-#![feature(managed_boxes)]
-
-fn borrow(x: &int, f: |x: &int|) {
-    let before = *x;
-    f(x);
-    let after = *x;
-    assert_eq!(before, after);
-}
-
-pub fn main() {
-    let mut x = @3;
-    borrow(x, |b_x| {
-        assert_eq!(*b_x, 3);
-        assert_eq!(&(*x) as *int, &(*b_x) as *int);
-        x = @22;
-
-        println!("&*b_x = {:p}", &(*b_x));
-        assert_eq!(*b_x, 3);
-        assert!(&(*x) as *int != &(*b_x) as *int);
-    })
-}
diff --git a/src/test/run-pass/borrowck-preserve-cond-box.rs b/src/test/run-pass/borrowck-preserve-cond-box.rs
deleted file mode 100644 (file)
index 52ea474..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 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.
-
-// exec-env:RUST_POISON_ON_FREE=1
-
-#![feature(managed_boxes)]
-
-fn testfn(cond: bool) {
-    let mut x = @3;
-    let mut y = @4;
-
-    // borrow x and y
-    let r_x = &*x;
-    let r_y = &*y;
-    let mut r = r_x;
-    let mut exp = 3;
-
-    if cond {
-        r = r_y;
-        exp = 4;
-    }
-
-    println!("*r = {}, exp = {}", *r, exp);
-    assert_eq!(*r, exp);
-
-    x = @5;
-    y = @6;
-
-    println!("*r = {}, exp = {}", *r, exp);
-    assert_eq!(*r, exp);
-    assert_eq!(x, @5);
-    assert_eq!(y, @6);
-}
-
-pub fn main() {
-    testfn(true);
-    testfn(false);
-}
diff --git a/src/test/run-pass/borrowck-preserve-expl-deref.rs b/src/test/run-pass/borrowck-preserve-expl-deref.rs
deleted file mode 100644 (file)
index 749c806..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// ignore-pretty
-
-// Copyright 2012-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.
-
-// exec-env:RUST_POISON_ON_FREE=1
-
-#![feature(managed_boxes)]
-
-fn borrow(x: &int, f: |x: &int|) {
-    let before = *x;
-    f(x);
-    let after = *x;
-    assert_eq!(before, after);
-}
-
-struct F { f: ~int }
-
-pub fn main() {
-    let mut x = @F {f: ~3};
-    borrow((*x).f, |b_x| {
-        assert_eq!(*b_x, 3);
-        assert_eq!(&(*x.f) as *int, &(*b_x) as *int);
-        x = @F {f: ~4};
-
-        println!("&*b_x = {:p}", &(*b_x));
-        assert_eq!(*b_x, 3);
-        assert!(&(*x.f) as *int != &(*b_x) as *int);
-    })
-}
diff --git a/src/test/run-pass/cfg-match-arm.rs b/src/test/run-pass/cfg-match-arm.rs
new file mode 100644 (file)
index 0000000..9858b80
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+
+enum Foo {
+    Bar,
+    Baz,
+}
+
+fn foo(f: Foo) {
+    match f {
+        Bar => {},
+        #[cfg(not(asdfa))]
+        Baz => {},
+        #[cfg(afsd)]
+        Basdfwe => {}
+    }
+}
+
+pub fn main() {}
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);
 }
diff --git a/src/test/run-pass/regions-appearance-constraint.rs b/src/test/run-pass/regions-appearance-constraint.rs
deleted file mode 100644 (file)
index a65a878..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012 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.
-
-/* Tests conditional rooting of the box y */
-
-#![feature(managed_boxes)]
-
-fn testfn(cond: bool) {
-    let mut x = @3;
-    let mut y = @4;
-
-    let mut a = &*x;
-
-    let mut exp = 3;
-    if cond {
-        a = &*y;
-
-        exp = 4;
-    }
-
-    x = @5;
-    y = @6;
-    assert_eq!(*a, exp);
-    assert_eq!(x, @5);
-    assert_eq!(y, @6);
-}
-
-pub fn main() {
-}
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() ());
 }
diff --git a/src/test/run-pass/struct-field-assignability.rs b/src/test/run-pass/struct-field-assignability.rs
deleted file mode 100644 (file)
index 3469936..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.
-
-#![feature(managed_boxes)]
-
-struct Foo<'a> {
-    x: &'a int
-}
-
-pub fn main() {
-    let f = Foo { x: @3 };
-    assert_eq!(*f.x, 3);
-}
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 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");