From: bors Date: Fri, 25 Apr 2014 01:26:15 +0000 (-0700) Subject: auto merge of #13711 : alexcrichton/rust/snapshots, r=brson X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=07598fc8cc7049594afee14528bda4019d8dda14;hp=568736182b39d0ee9ad59a4e08f537173624b192;p=rust.git auto merge of #13711 : alexcrichton/rust/snapshots, r=brson These are the first successful snapshots after the LLVM upgrade, built with LLVM that requires C++11 --- diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index cae6c2b656d..2e287135dc2 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -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, } } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index dd246cf6114..9ce81c5bae5 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -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!(); } diff --git a/src/etc/vim/indent/rust.vim b/src/etc/vim/indent/rust.vim index f7ac357b23a..54094a74119 100644 --- a/src/etc/vim/indent/rust.vim +++ b/src/etc/vim/indent/rust.vim @@ -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. diff --git a/src/libfourcc/lib.rs b/src/libfourcc/lib.rs index 50cdd6cedc2..fe0b6bcfd0f 100644 --- a/src/libfourcc/lib.rs +++ b/src/libfourcc/lib.rs @@ -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 { diff --git a/src/libnative/io/c_win32.rs b/src/libnative/io/c_win32.rs index 8d75a673914..dbbb39b3b7b 100644 --- a/src/libnative/io/c_win32.rs +++ b/src/libnative/io/c_win32.rs @@ -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, diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs index be597761b1a..93ec23e32ad 100644 --- a/src/libnative/io/net.rs +++ b/src/libnative/io/net.rs @@ -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, } impl TcpListener { @@ -477,7 +480,7 @@ pub fn bind(addr: ip::SocketAddr) -> IoResult { 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 { } } - 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 { 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 { 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 { + 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 { } } } + + 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) { + self.deadline = match timeout { + None => 0, + Some(t) => ::io::timer::now() + t, + }; + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libnative/io/timer_win32.rs b/src/libnative/io/timer_win32.rs index a15898feb92..588ec367d81 100644 --- a/src/libnative/io/timer_win32.rs +++ b/src/libnative/io/timer_win32.rs @@ -89,6 +89,17 @@ fn helper(input: libc::HANDLE, messages: Receiver) { } } +// 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_helper::boot(helper); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index b7842936af3..f8ed6bdce95 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -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, } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 95ee250e24c..e4ace2a2b95 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -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; } diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 888a8f6bd8d..8dcc97c936c 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -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::P { }) } +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()); } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 0c9aa60b4a1..8ffba905773 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -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. diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 08133a8b69e..7f3757c478c 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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, } diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index a27fe5cec22..4c17ddbb31f 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -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) -> R { //! Main routine. Walks down `cmt` until we find the "guarantor". @@ -90,29 +87,10 @@ fn check(&self, cmt: &mc::cmt, discr_scope: Option) -> 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) -> 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) -> 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 diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index de4ce84fb0a..4d0249a3011 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -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 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) { diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 3de64f15191..1af0e48c46d 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -21,11 +21,10 @@ 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, + + // 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, + loaned_paths_imm: Cell, + stable_paths: Cell, + guaranteed_paths: Cell, } pub type BckResult = Result; @@ -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; - /////////////////////////////////////////////////////////////////////////// // 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, diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index cd3ab100e55..6a2262aeaef 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -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], 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, diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index e6c885e56f1..02f9309bca2 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -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, ()); +} diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 05a225d8953..51aafb90ac6 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -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, ()); }) } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 53d3dec6713..1e44e1ab7f9 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -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(..) | diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 4e2d8cf585f..408c6311496 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -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); } } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index ab345ecb243..d429ead39d6 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -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); } _ => { diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 55f8b3d1fd2..ddda95c06cb 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -198,7 +198,6 @@ 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 , 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); diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 27a97af6108..0c7d36e0dbe 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -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, diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 3c1dfedcac6..9bb0375bf44 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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()), diff --git a/src/librustc/middle/trans/mod.rs b/src/librustc/middle/trans/mod.rs index 7ac491edfeb..f07adb1ed87 100644 --- a/src/librustc/middle/trans/mod.rs +++ b/src/librustc/middle/trans/mod.rs @@ -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 index 8f114827bfd..00000000000 --- a/src/librustc/middle/trans/write_guard.rs +++ /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 or the MIT license -// , 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, - 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, - 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 -} diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 9a261689b37..ce35d1ab1de 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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]) { 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::>(); 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); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index b59da8910af..9f36e903e58 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -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(..) | diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index bb9c6a87bab..df102b8aadf 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -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)) }, diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index 3f1c99cffd6..be05ccdfcb4 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -684,7 +684,8 @@ impl Clean 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 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() diff --git a/src/librustuv/async.rs b/src/librustuv/async.rs index c75f84de01e..dcbd0baf6f3 100644 --- a/src/librustuv/async.rs +++ b/src/librustuv/async.rs @@ -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)) }; diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs index cde5cfa97c1..665d418ab2a 100644 --- a/src/librustuv/file.rs +++ b/src/librustuv/file.rs @@ -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 { 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 }) diff --git a/src/librustuv/idle.rs b/src/librustuv/idle.rs index 0de6e479a8f..4d7da29aa9a 100644 --- a/src/librustuv/idle.rs +++ b/src/librustuv/idle.rs @@ -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 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(); } diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs index 69d978b2433..27a06911939 100644 --- a/src/librustuv/net.rs +++ b/src/librustuv/net.rs @@ -174,6 +174,9 @@ pub struct TcpListener { pub struct TcpAcceptor { listener: ~TcpListener, + timer: Option, + timeout_tx: Option>, + timeout_rx: Option>, } // 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 { 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 { 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) { + // 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(()); + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/librustuv/queue.rs b/src/librustuv/queue.rs index b6c7fbda8c8..9e75991434f 100644 --- a/src/librustuv/queue.rs +++ b/src/librustuv/queue.rs @@ -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, } -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)) }; diff --git a/src/librustuv/timer.rs b/src/librustuv/timer.rs index 3710d97827f..5c34fd8cc12 100644 --- a/src/librustuv/timer.rs +++ b/src/librustuv/timer.rs @@ -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::, 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() { diff --git a/src/librustuv/tty.rs b/src/librustuv/tty.rs index 95ecaa09a43..4f3e12b6974 100644 --- a/src/librustuv/tty.rs +++ b/src/librustuv/tty.rs @@ -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)); } diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index 3769a1b8d6d..3127a01d70e 100644 --- a/src/librustuv/uvio.rs +++ b/src/librustuv/uvio.rs @@ -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; diff --git a/src/librustuv/uvll.rs b/src/librustuv/uvll.rs index 04bc53004d0..57f4bd9d7eb 100644 --- a/src/librustuv/uvll.rs +++ b/src/librustuv/uvll.rs @@ -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, diff --git a/src/libstd/hash/sip.rs b/src/libstd/hash/sip.rs index 794c4ee62ff..eae13735809 100644 --- a/src/libstd/hash/sip.rs +++ b/src/libstd/hash/sip.rs @@ -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; diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index 6bc32d0ed7b..a9c493c284d 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -491,7 +491,8 @@ pub fn readdir(path: &Path) -> IoResult> { /// 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 { Ok(Directories { stack: try!(readdir(path)) }) } @@ -503,7 +504,7 @@ pub struct Directories { impl Iterator for Directories { fn next(&mut self) -> Option { - 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"); diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs index 4f1e6bd7418..0619c89aac1 100644 --- a/src/libstd/io/net/tcp.rs +++ b/src/libstd/io/net/tcp.rs @@ -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) { self.obj.set_timeout(ms); } +} + impl Acceptor for TcpAcceptor { fn accept(&mut self) -> IoResult { self.obj.accept().map(TcpStream::new) @@ -191,6 +241,7 @@ fn accept(&mut self) -> IoResult { } #[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(); + }) } diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index bf31f36d22d..6df549dbc79 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -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) -> uint { 24 } + fn mantissa_digits(_: Option) -> uint { MANTISSA_DIGITS } #[inline] - fn digits(_: Option) -> uint { 6 } + fn digits(_: Option) -> uint { DIGITS } #[inline] - fn epsilon() -> f32 { 1.19209290e-07 } + fn epsilon() -> f32 { EPSILON } #[inline] - fn min_exp(_: Option) -> int { -125 } + fn min_exp(_: Option) -> int { MIN_EXP } #[inline] - fn max_exp(_: Option) -> int { 128 } + fn max_exp(_: Option) -> int { MAX_EXP } #[inline] - fn min_10_exp(_: Option) -> int { -37 } + fn min_10_exp(_: Option) -> int { MIN_10_EXP } #[inline] - fn max_10_exp(_: Option) -> int { 38 } + fn max_10_exp(_: Option) -> 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] diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 39eba0825fc..63ddb88f8dc 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -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] diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index c498892e76c..dccca82dc79 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -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) -> 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) -> 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) -> int; diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index ff6e494b948..5673929d5a1 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -192,7 +192,7 @@ fn clone(&self) -> Weak { } } -#[allow(missing_doc)] +#[doc(hidden)] trait RcBoxPtr { fn inner<'a>(&'a self) -> &'a RcBox; diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index 8b9b8a7498b..824d9e5ec92 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -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; diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs index 0f3fc9c21ce..5dd14834669 100644 --- a/src/libstd/rt/rtio.rs +++ b/src/libstd/rt/rtio.rs @@ -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); } pub trait RtioTcpStream : RtioSocket { diff --git a/src/libstd/task.rs b/src/libstd/task.rs index 610df320fa5..f8b3d25033c 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -91,19 +91,17 @@ pub struct TaskBuilder { nocopy: Option, } -/** - * 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(f: proc():Send -> T) -> Result { - /*! - * 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] diff --git a/src/libsync/lock.rs b/src/libsync/lock.rs index 911cd1d2eb1..930b3009042 100644 --- a/src/libsync/lock.rs +++ b/src/libsync/lock.rs @@ -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(); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 116411c9e05..ccb25239f6c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -440,6 +440,7 @@ pub enum Decl_ { #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] pub struct Arm { + pub attrs: Vec, 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>, Vec<@Expr>), + ExprMethodCall(SpannedIdent, Vec>, Vec<@Expr>), ExprTup(Vec<@Expr>), ExprBinary(BinOp, @Expr, @Expr), ExprUnary(UnOp, @Expr), diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 7a167237d3e..865c3be4ae6 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -363,14 +363,15 @@ fn with_path_next(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) - } pub fn with_attrs(&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. diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index adb97af7490..c80c4dc3a22 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -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: ()) { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index e1174ea6cc4..1a160cb33aa 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -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::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 diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index e0b493cd8d9..51024158822 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -13,12 +13,15 @@ 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) diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 35b7e7c1a66..92b3788c247 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -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 { diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index afe2d3dae6a..dd2f90cfa5f 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -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 { diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index d161f966850..b76caccffec 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 69c413890e9..3ca4f9e2862 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 6d6cdc55d40..062f198425b 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index 633674eff5c..c225906ed2b 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -13,12 +13,15 @@ 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) diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index acdef8c8645..ec3d4e0078b 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 673745b41e8..bf886e51885 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -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, /// 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) diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index 9e160b0e35d..d367ae61e0b 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index e42a3c67e34..9978a2edce9 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -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), diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 09c3abf42b8..23877dd29ea 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 7098d0dd6ef..b9725361538 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 0aeeabcaeab..449851dd3ea 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -13,12 +13,15 @@ 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, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 04b289b9fca..ae82a07601b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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(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()) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8808312bed7..974077956d1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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> , args: Vec<@Expr> ) -> ast::Expr_ { + fn mk_method_call(&mut self, + ident: ast::SpannedIdent, + tps: Vec>, + 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 = 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(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f768bf22ce0..9d3f7cbc69a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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 { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 758b7532acc..6a1b7b4d073 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -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, pub save_metrics: Option, pub test_shard: Option<(uint,uint)>, - pub logfile: Option + pub logfile: Option, + 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::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 { 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 { 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 { } } -pub fn run_test(force_ignore: bool, +pub fn run_test(opts: &TestOpts, + force_ignore: bool, test: TestDescAndFn, monitor_ch: Sender) { @@ -955,18 +987,23 @@ pub fn run_test(force_ignore: bool, #[allow(deprecated_owned_vector)] fn run_test_inner(desc: TestDesc, monitor_ch: Sender, + 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(), diff --git a/src/libuv b/src/libuv index 800b56fe6af..43495892ded 160000 --- a/src/libuv +++ b/src/libuv @@ -1 +1 @@ -Subproject commit 800b56fe6af21ffd8e56aee8cf12dd758f5bbdf1 +Subproject commit 43495892ded622de51eba7362c5ffae1ed50c9cc diff --git a/src/rt/libuv-auto-clean-trigger b/src/rt/libuv-auto-clean-trigger index 961455b9093..8bd7aa54751 100644 --- a/src/rt/libuv-auto-clean-trigger +++ b/src/rt/libuv-auto-clean-trigger @@ -1,2 +1,2 @@ # Change the contents of this file to force a full rebuild of libuv -2014-02-16 +2014-04-18 diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 32bac73debf..021dda49765 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -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); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 3fe1b1380da..ec33b750358 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -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(&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 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 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 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; diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 42c60e72bab..5722eea48d7 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -68,4 +68,4 @@ #include #endif -extern const char* LLVMRustError; +void LLVMRustSetLastError(const char*); diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index b99d778c399..5a42d2e3c59 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -23,6 +23,7 @@ use std::comm; use std::os; use std::task; +use std::task::TaskBuilder; use std::uint; fn move_out(_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) { diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index af8a89cc597..741cc4be4fa 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -18,6 +18,7 @@ use std::os; use std::task; +use std::task::TaskBuilder; use std::uint; fn move_out(_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) { diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 39384ce275a..0819b71853a 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -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 index 00000000000..4695360a688 --- /dev/null +++ b/src/test/compile-fail/borrowck-managed-pointer-deref-scope.rs @@ -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 or the MIT license +// , 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 index 00000000000..ff138451e93 --- /dev/null +++ b/src/test/compile-fail/borrowck-preserve-box-in-field.rs @@ -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 or the MIT license +// , 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 index 00000000000..b06eb0d6ba2 --- /dev/null +++ b/src/test/compile-fail/borrowck-preserve-box-in-uniq.rs @@ -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 or the MIT license +// , 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 index 00000000000..1a920c7871e --- /dev/null +++ b/src/test/compile-fail/borrowck-preserve-box.rs @@ -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 or the MIT license +// , 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 index 00000000000..7000e2351dd --- /dev/null +++ b/src/test/compile-fail/borrowck-preserve-cond-box.rs @@ -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 or the MIT license +// , 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 index 00000000000..aeabf6d9f8b --- /dev/null +++ b/src/test/compile-fail/borrowck-preserve-expl-deref.rs @@ -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 or the MIT license +// , 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 index 00000000000..e920bfd412d --- /dev/null +++ b/src/test/compile-fail/lint-directives-on-use-items-issue-10534.rs @@ -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 or the MIT license +// , 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 index 00000000000..3610a0e2e9d --- /dev/null +++ b/src/test/compile-fail/method-call-err-msg.rs @@ -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 or the MIT license +// , 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 index 00000000000..68bbebb8cb0 --- /dev/null +++ b/src/test/compile-fail/regions-appearance-constraint.rs @@ -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 or the MIT license +// , 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() {} diff --git a/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs b/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs index b069a35ad7a..1508349344c 100644 --- a/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs +++ b/src/test/compile-fail/regions-infer-borrow-scope-too-big.rs @@ -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; } diff --git a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs index 9be8a5fef4d..3cd70ce6c8a 100644 --- a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs +++ b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs @@ -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 index 00000000000..68a17266106 --- /dev/null +++ b/src/test/compile-fail/struct-field-assignability.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/compile-fail/unsized5.rs b/src/test/compile-fail/unsized5.rs index 9608b7e6b20..614b8e3a5ab 100644 --- a/src/test/compile-fail/unsized5.rs +++ b/src/test/compile-fail/unsized5.rs @@ -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(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(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 { 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 index 00000000000..a763373e364 --- /dev/null +++ b/src/test/compile-fail/unsized6.rs @@ -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 or the MIT license +// , 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(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(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(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(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(x: X) {} //~ERROR variable `x` has dynamically sized type `X` +fn g2(x: X) {} //~ERROR variable `x` has dynamically sized type `X` + +pub fn main() { +} diff --git a/src/test/run-fail/fail-task-name-owned.rs b/src/test/run-fail/fail-task-name-owned.rs index 23ceead0cb0..f30af563aa6 100644 --- a/src/test/run-fail/fail-task-name-owned.rs +++ b/src/test/run-fail/fail-task-name-owned.rs @@ -10,10 +10,10 @@ // 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() diff --git a/src/test/run-fail/fail-task-name-send-str.rs b/src/test/run-fail/fail-task-name-send-str.rs index c21c6c42f6f..d99c805323f 100644 --- a/src/test/run-fail/fail-task-name-send-str.rs +++ b/src/test/run-fail/fail-task-name-send-str.rs @@ -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() diff --git a/src/test/run-fail/fail-task-name-static.rs b/src/test/run-fail/fail-task-name-static.rs index 516f9b2e1d7..e0c98c5744e 100644 --- a/src/test/run-fail/fail-task-name-static.rs +++ b/src/test/run-fail/fail-task-name-static.rs @@ -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 index 00000000000..9f91618bda4 --- /dev/null +++ b/src/test/run-make/error-writing-dependencies/Makefile @@ -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 index 00000000000..8ae3d072362 --- /dev/null +++ b/src/test/run-make/error-writing-dependencies/foo.rs @@ -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 or the MIT license +// , 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 index 00000000000..9d852bce6f6 --- /dev/null +++ b/src/test/run-make/weird-output-filenames/Makefile @@ -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 index 00000000000..8ae3d072362 --- /dev/null +++ b/src/test/run-make/weird-output-filenames/foo.rs @@ -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 or the MIT license +// , 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 index f05b8c67d77..00000000000 --- a/src/test/run-pass/borrowck-preserve-box-in-field.rs +++ /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 or the MIT license -// , 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 index 0896d4de625..00000000000 --- a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs +++ /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 or the MIT license -// , 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 index cfb9a4b91df..00000000000 --- a/src/test/run-pass/borrowck-preserve-box.rs +++ /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 or the MIT license -// , 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 index 52ea474dbf5..00000000000 --- a/src/test/run-pass/borrowck-preserve-cond-box.rs +++ /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 or the MIT license -// , 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 index 749c8063950..00000000000 --- a/src/test/run-pass/borrowck-preserve-expl-deref.rs +++ /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 or the MIT license -// , 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 index 00000000000..9858b804b7b --- /dev/null +++ b/src/test/run-pass/cfg-match-arm.rs @@ -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 or the MIT license +// , 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() {} diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index c8735e79e50..f1217be3484 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -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 index a65a878b3c7..00000000000 --- a/src/test/run-pass/regions-appearance-constraint.rs +++ /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 or the MIT license -// , 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() { -} diff --git a/src/test/run-pass/spawning-with-debug.rs b/src/test/run-pass/spawning-with-debug.rs index df6bf767b9d..c8918fda9e7 100644 --- a/src/test/run-pass/spawning-with-debug.rs +++ b/src/test/run-pass/spawning-with-debug.rs @@ -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 index 3469936c05b..00000000000 --- a/src/test/run-pass/struct-field-assignability.rs +++ /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 or the MIT license -// , 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); -} diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs index 275c99f99a9..a78bbefed44 100644 --- a/src/test/run-pass/task-comm-12.rs +++ b/src/test/run-pass/task-comm-12.rs @@ -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) diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index c2f6fe580fc..3fb91b67c9d 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -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; diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs index 009b013353c..188d8288b09 100644 --- a/src/test/run-pass/task-comm-9.rs +++ b/src/test/run-pass/task-comm-9.rs @@ -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); diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 063ffed3151..0c38abb20fc 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -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) { diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index bd44bdd51cd..2662a6c6568 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -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"); diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index 14ba368bdfa..8c5504725bb 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -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");