diff options
Diffstat (limited to 'src')
147 files changed, 715 insertions, 321 deletions
diff --git a/src/libextra/comm.rs b/src/libextra/comm.rs index 4a3801827a2..5cc5c140fd5 100644 --- a/src/libextra/comm.rs +++ b/src/libextra/comm.rs @@ -136,7 +136,7 @@ pub fn rendezvous<T: Send>() -> (SyncPort<T>, SyncChan<T>) { #[cfg(test)] mod test { use comm::{DuplexStream, rendezvous}; - use std::rt::test::run_in_newsched_task; + use std::rt::test::run_in_uv_task; use std::task::spawn_unlinked; @@ -165,7 +165,7 @@ mod test { #[test] fn recv_a_lot() { // Rendezvous streams should be able to handle any number of messages being sent - do run_in_newsched_task { + do run_in_uv_task { let (port, chan) = rendezvous(); do spawn { do 1000000.times { chan.send(()) } diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index ea5c05e9ec8..36a49de8778 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -230,12 +230,15 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt, // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: - let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex)); - this.guarantee_valid(ex.id, - ex.span, - base_cmt, - LoanMutability::from_ast_mutability(mutbl), - scope_r); + let expr_ty = ty::expr_ty(tcx, ex); + if !ty::type_is_bot(expr_ty) { + let scope_r = ty_region(tcx, ex.span, expr_ty); + this.guarantee_valid(ex.id, + ex.span, + base_cmt, + LoanMutability::from_ast_mutability(mutbl), + scope_r); + } visit::walk_expr(this, ex, ()); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 47c1cf0064d..74f9e2114e1 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -288,37 +288,6 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef, return c; } } -pub fn umax(cx: @mut Block, a: ValueRef, b: ValueRef) -> ValueRef { - let _icx = push_ctxt("umax"); - let cond = ICmp(cx, lib::llvm::IntULT, a, b); - return Select(cx, cond, b, a); -} - -pub fn umin(cx: @mut Block, a: ValueRef, b: ValueRef) -> ValueRef { - let _icx = push_ctxt("umin"); - let cond = ICmp(cx, lib::llvm::IntULT, a, b); - return Select(cx, cond, a, b); -} - -// Given a pointer p, returns a pointer sz(p) (i.e., inc'd by sz bytes). -// The type of the returned pointer is always i8*. If you care about the -// return type, use bump_ptr(). -pub fn ptr_offs(bcx: @mut Block, base: ValueRef, sz: ValueRef) -> ValueRef { - let _icx = push_ctxt("ptr_offs"); - let raw = PointerCast(bcx, base, Type::i8p()); - InBoundsGEP(bcx, raw, [sz]) -} - -// Increment a pointer by a given amount and then cast it to be a pointer -// to a given type. -pub fn bump_ptr(bcx: @mut Block, t: ty::t, base: ValueRef, sz: ValueRef) -> - ValueRef { - let _icx = push_ctxt("bump_ptr"); - let ccx = bcx.ccx(); - let bumped = ptr_offs(bcx, base, sz); - let typ = type_of(ccx, t).ptr_to(); - PointerCast(bcx, bumped, typ) -} // Returns a pointer to the body for the box. The box may be an opaque // box. The result will be casted to the type of body_t, if it is statically @@ -434,10 +403,6 @@ pub fn malloc_general(bcx: @mut Block, t: ty::t, heap: heap) -> MallocResult { assert!(heap != heap_exchange); malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty)) } -pub fn malloc_boxed(bcx: @mut Block, t: ty::t) - -> MallocResult { - malloc_general(bcx, t, heap_managed) -} pub fn heap_for_unique(bcx: @mut Block, t: ty::t) -> heap { if ty::type_contents(bcx.tcx(), t).contains_managed() { diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 8803d39b0c6..376d178f8f7 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -47,6 +47,13 @@ impl<T> Clone for *T { } } +impl<T> Clone for *mut T { + #[inline] + fn clone(&self) -> *mut T { + *self + } +} + /// Return the first offset `i` such that `f(buf[i]) == true`. #[inline] pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint { diff --git a/src/libstd/rt/basic.rs b/src/libstd/rt/basic.rs new file mode 100644 index 00000000000..86d3f8a52ba --- /dev/null +++ b/src/libstd/rt/basic.rs @@ -0,0 +1,256 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This is a basic event loop implementation not meant for any "real purposes" +//! other than testing the scheduler and proving that it's possible to have a +//! pluggable event loop. + +use prelude::*; + +use cast; +use rt::rtio::{EventLoop, IoFactory, RemoteCallback, PausibleIdleCallback}; +use unstable::sync::Exclusive; +use util; + +/// This is the only exported function from this module. +pub fn event_loop() -> ~EventLoop { + ~BasicLoop::new() as ~EventLoop +} + +struct BasicLoop { + work: ~[~fn()], // pending work + idle: Option<*BasicPausible>, // only one is allowed + remotes: ~[(uint, ~fn())], + next_remote: uint, + messages: Exclusive<~[Message]> +} + +enum Message { RunRemote(uint), RemoveRemote(uint) } + +struct Time { + sec: u64, + nsec: u64, +} + +impl Ord for Time { + fn lt(&self, other: &Time) -> bool { + self.sec < other.sec || self.nsec < other.nsec + } +} + +impl BasicLoop { + fn new() -> BasicLoop { + BasicLoop { + work: ~[], + idle: None, + next_remote: 0, + remotes: ~[], + messages: Exclusive::new(~[]), + } + } + + /// Process everything in the work queue (continually) + fn work(&mut self) { + while self.work.len() > 0 { + for work in util::replace(&mut self.work, ~[]).move_iter() { + work(); + } + } + } + + fn remote_work(&mut self) { + let messages = unsafe { + do self.messages.with |messages| { + if messages.len() > 0 { + Some(util::replace(messages, ~[])) + } else { + None + } + } + }; + let messages = match messages { + Some(m) => m, None => return + }; + for message in messages.iter() { + self.message(*message); + } + } + + fn message(&mut self, message: Message) { + match message { + RunRemote(i) => { + match self.remotes.iter().find(|& &(id, _)| id == i) { + Some(&(_, ref f)) => (*f)(), + None => unreachable!() + } + } + RemoveRemote(i) => { + match self.remotes.iter().position(|&(id, _)| id == i) { + Some(i) => { self.remotes.remove(i); } + None => unreachable!() + } + } + } + } + + /// Run the idle callback if one is registered + fn idle(&mut self) { + unsafe { + match self.idle { + Some(idle) => { + if (*idle).active { + (*(*idle).work.get_ref())(); + } + } + None => {} + } + } + } + + fn has_idle(&self) -> bool { + unsafe { self.idle.is_some() && (**self.idle.get_ref()).active } + } +} + +impl EventLoop for BasicLoop { + fn run(&mut self) { + // Not exactly efficient, but it gets the job done. + while self.remotes.len() > 0 || self.work.len() > 0 || self.has_idle() { + + self.work(); + self.remote_work(); + + if self.has_idle() { + self.idle(); + continue + } + + unsafe { + // We block here if we have no messages to process and we may + // receive a message at a later date + do self.messages.hold_and_wait |messages| { + self.remotes.len() > 0 && + messages.len() == 0 && + self.work.len() == 0 + } + } + } + } + + fn callback(&mut self, f: ~fn()) { + self.work.push(f); + } + + // XXX: Seems like a really weird requirement to have an event loop provide. + fn pausible_idle_callback(&mut self) -> ~PausibleIdleCallback { + let callback = ~BasicPausible::new(self); + rtassert!(self.idle.is_none()); + unsafe { + let cb_ptr: &*BasicPausible = cast::transmute(&callback); + self.idle = Some(*cb_ptr); + } + return callback as ~PausibleIdleCallback; + } + + fn remote_callback(&mut self, f: ~fn()) -> ~RemoteCallback { + let id = self.next_remote; + self.next_remote += 1; + self.remotes.push((id, f)); + ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback + } + + /// This has no bindings for local I/O + fn io<'a>(&'a mut self, _: &fn(&'a mut IoFactory)) {} +} + +struct BasicRemote { + queue: Exclusive<~[Message]>, + id: uint, +} + +impl BasicRemote { + fn new(queue: Exclusive<~[Message]>, id: uint) -> BasicRemote { + BasicRemote { queue: queue, id: id } + } +} + +impl RemoteCallback for BasicRemote { + fn fire(&mut self) { + unsafe { + do self.queue.hold_and_signal |queue| { + queue.push(RunRemote(self.id)); + } + } + } +} + +impl Drop for BasicRemote { + fn drop(&mut self) { + unsafe { + do self.queue.hold_and_signal |queue| { + queue.push(RemoveRemote(self.id)); + } + } + } +} + +struct BasicPausible { + eloop: *mut BasicLoop, + work: Option<~fn()>, + active: bool, +} + +impl BasicPausible { + fn new(eloop: &mut BasicLoop) -> BasicPausible { + BasicPausible { + active: false, + work: None, + eloop: eloop, + } + } +} + +impl PausibleIdleCallback for BasicPausible { + fn start(&mut self, f: ~fn()) { + rtassert!(!self.active && self.work.is_none()); + self.active = true; + self.work = Some(f); + } + fn pause(&mut self) { + self.active = false; + } + fn resume(&mut self) { + self.active = true; + } + fn close(&mut self) { + self.active = false; + self.work = None; + } +} + +impl Drop for BasicPausible { + fn drop(&mut self) { + unsafe { + (*self.eloop).idle = None; + } + } +} + +fn time() -> Time { + #[fixed_stack_segment]; #[inline(never)]; + extern { + fn get_time(sec: &mut i64, nsec: &mut i32); + } + let mut sec = 0; + let mut nsec = 0; + unsafe { get_time(&mut sec, &mut nsec) } + + Time { sec: sec as u64, nsec: nsec as u64 } +} diff --git a/src/libstd/rt/io/buffered.rs b/src/libstd/rt/io/buffered.rs index 9dcb35c806f..47c8dbd35c6 100644 --- a/src/libstd/rt/io/buffered.rs +++ b/src/libstd/rt/io/buffered.rs @@ -221,17 +221,48 @@ impl<W: Writer> Writer for BufferedWriter<W> { } impl<W: Writer> Decorator<W> for BufferedWriter<W> { - fn inner(self) -> W { - self.inner - } + fn inner(self) -> W { self.inner } + fn inner_ref<'a>(&'a self) -> &'a W { &self.inner } + fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { &mut self.inner } +} - fn inner_ref<'a>(&'a self) -> &'a W { - &self.inner +/// Wraps a Writer and buffers output to it, flushing whenever a newline (0xa, +/// '\n') is detected. +/// +/// Note that this structure does NOT flush the output when dropped. +pub struct LineBufferedWriter<W> { + priv inner: BufferedWriter<W>, +} + +impl<W: Writer> LineBufferedWriter<W> { + /// Creates a new `LineBufferedWriter` + pub fn new(inner: W) -> LineBufferedWriter<W> { + // Lines typically aren't that long, don't use a giant buffer + LineBufferedWriter { + inner: BufferedWriter::with_capacity(1024, inner) + } } +} - fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { - &mut self.inner +impl<W: Writer> Writer for LineBufferedWriter<W> { + fn write(&mut self, buf: &[u8]) { + match buf.iter().position(|&b| b == '\n' as u8) { + Some(i) => { + self.inner.write(buf.slice_to(i + 1)); + self.inner.flush(); + self.inner.write(buf.slice_from(i + 1)); + } + None => self.inner.write(buf), + } } + + fn flush(&mut self) { self.inner.flush() } +} + +impl<W: Writer> Decorator<W> for LineBufferedWriter<W> { + fn inner(self) -> W { self.inner.inner() } + fn inner_ref<'a>(&'a self) -> &'a W { self.inner.inner_ref() } + fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { self.inner.inner_mut_ref() } } struct InternalBufferedWriter<W>(BufferedWriter<W>); @@ -413,4 +444,19 @@ mod test { assert_eq!(reader.read_until(8), Some(~[0])); assert_eq!(reader.read_until(9), None); } + + #[test] + fn test_line_buffer() { + let mut writer = LineBufferedWriter::new(MemWriter::new()); + writer.write([0]); + assert_eq!(*writer.inner_ref().inner_ref(), ~[]); + writer.write([1]); + assert_eq!(*writer.inner_ref().inner_ref(), ~[]); + writer.flush(); + assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1]); + writer.write([0, '\n' as u8, 1]); + assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8]); + writer.flush(); + assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8, 1]); + } } diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs index 758c9779165..decf801d592 100644 --- a/src/libstd/rt/io/mod.rs +++ b/src/libstd/rt/io/mod.rs @@ -606,6 +606,13 @@ pub fn standard_error(kind: IoErrorKind) -> IoError { detail: None } } + IoUnavailable => { + IoError { + kind: IoUnavailable, + desc: "I/O is unavailable", + detail: None + } + } _ => fail!() } } diff --git a/src/libstd/rt/io/stdio.rs b/src/libstd/rt/io/stdio.rs index b922e6400cc..3f34d32b350 100644 --- a/src/libstd/rt/io/stdio.rs +++ b/src/libstd/rt/io/stdio.rs @@ -30,6 +30,7 @@ use fmt; use libc; use option::{Option, Some, None}; use result::{Ok, Err}; +use rt::io::buffered::{LineBufferedWriter, BufferedWriter}; use rt::rtio::{IoFactory, RtioTTY, RtioFileStream, with_local_io, CloseAsynchronously}; use super::{Reader, Writer, io_error, IoError, OtherIoError}; @@ -111,37 +112,78 @@ pub fn stderr() -> StdWriter { do src(libc::STDERR_FILENO, false) |src| { StdWriter { inner: src } } } +/// Executes a closure with the local task's handle on stdout. By default, this +/// stream is a buffering stream, so the handled yielded to the given closure +/// can be used to flush the stdout stream (if necessary). The buffering used is +/// line-buffering when stdout is attached to a terminal, and a fixed sized +/// buffer if it is not attached to a terminal. +/// +/// Note that handles generated via the `stdout()` function all output to the +/// same stream, and output among all task may be interleaved as a result of +/// this. This is provided to have access to the default stream for `print` and +/// `println` (and the related macros) for this task. +/// +/// Also note that logging macros do not use this stream. Using the logging +/// macros will emit output to stderr. +pub fn with_task_stdout(f: &fn(&mut Writer)) { + use rt::local::Local; + use rt::task::Task; + + unsafe { + // Logging may require scheduling operations, so we can't remove the + // task from TLS right now, hence the unsafe borrow. Sad. + let task: *mut Task = Local::unsafe_borrow(); + + match (*task).stdout_handle { + Some(ref mut handle) => f(*handle), + None => { + let handle = stdout(); + let mut handle = if handle.isatty() { + ~LineBufferedWriter::new(handle) as ~Writer + } else { + // The default capacity is very large, 64k, but this is just + // a stdout stream, and possibly per task, so let's not make + // this too expensive. + ~BufferedWriter::with_capacity(4096, handle) as ~Writer + }; + f(handle); + (*task).stdout_handle = Some(handle); + } + } + } +} + /// Prints a string to the stdout of the current process. No newline is emitted /// after the string is printed. pub fn print(s: &str) { - // XXX: need to see if not caching stdin() is the cause of performance - // issues, it should be possible to cache a stdout handle in each Task - // and then re-use that across calls to print/println. Note that the - // resolution of this comment will affect all of the prints below as - // well. - stdout().write(s.as_bytes()); + do with_task_stdout |io| { + io.write(s.as_bytes()); + } } /// Prints a string as a line. to the stdout of the current process. A literal /// `\n` character is printed to the console after the string. pub fn println(s: &str) { - let mut out = stdout(); - out.write(s.as_bytes()); - out.write(['\n' as u8]); + do with_task_stdout |io| { + io.write(s.as_bytes()); + io.write(['\n' as u8]); + } } /// Similar to `print`, but takes a `fmt::Arguments` structure to be compatible /// with the `format_args!` macro. pub fn print_args(fmt: &fmt::Arguments) { - let mut out = stdout(); - fmt::write(&mut out as &mut Writer, fmt); + do with_task_stdout |io| { + fmt::write(io, fmt); + } } /// Similar to `println`, but takes a `fmt::Arguments` structure to be /// compatible with the `format_args!` macro. pub fn println_args(fmt: &fmt::Arguments) { - let mut out = stdout(); - fmt::writeln(&mut out as &mut Writer, fmt); + do with_task_stdout |io| { + fmt::writeln(io, fmt); + } } /// Representation of a reader of a standard input stream diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs index 31650ede700..cb66d6f6199 100644 --- a/src/libstd/rt/logging.rs +++ b/src/libstd/rt/logging.rs @@ -13,6 +13,8 @@ use from_str::from_str; use libc::exit; use option::{Some, None, Option}; use rt::io; +use rt::io::stdio::StdWriter; +use rt::io::buffered::LineBufferedWriter; use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map}; use str::StrSlice; use u32; @@ -170,7 +172,7 @@ pub trait Logger { /// This logger emits output to the stderr of the process, and contains a lazily /// initialized event-loop driven handle to the stream. pub struct StdErrLogger { - priv handle: Option<io::stdio::StdWriter>, + priv handle: Option<LineBufferedWriter<StdWriter>>, } impl StdErrLogger { @@ -181,7 +183,7 @@ impl Logger for StdErrLogger { fn log(&mut self, args: &fmt::Arguments) { // First time logging? Get a handle to the stderr of this process. if self.handle.is_none() { - self.handle = Some(io::stderr()); + self.handle = Some(LineBufferedWriter::new(io::stderr())); } fmt::writeln(self.handle.get_mut_ref() as &mut io::Writer, args); } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 66d7a6bf488..5113c28aa08 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -102,6 +102,9 @@ pub mod shouldnt_be_public { // Internal macros used by the runtime. mod macros; +/// Basic implementation of an EventLoop, provides no I/O interfaces +mod basic; + /// The global (exchange) heap. pub mod global_heap; diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs index 66a0676a2f4..29f728a5e0c 100644 --- a/src/libstd/rt/rtio.rs +++ b/src/libstd/rt/rtio.rs @@ -28,7 +28,6 @@ pub trait EventLoop { fn run(&mut self); fn callback(&mut self, ~fn()); fn pausible_idle_callback(&mut self) -> ~PausibleIdleCallback; - fn callback_ms(&mut self, ms: u64, ~fn()); fn remote_callback(&mut self, ~fn()) -> ~RemoteCallback; /// The asynchronous I/O services. Not all event loops may provide one diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 6e661884616..9965380d9dc 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -62,8 +62,6 @@ pub struct Scheduler { /// no longer try to go to sleep, but exit instead. no_sleep: bool, stack_pool: StackPool, - /// The event loop used to drive the scheduler and perform I/O - event_loop: ~EventLoop, /// The scheduler runs on a special task. When it is not running /// it is stored here instead of the work queue. priv sched_task: Option<~Task>, @@ -85,7 +83,17 @@ pub struct Scheduler { priv yield_check_count: uint, /// A flag to tell the scheduler loop it needs to do some stealing /// in order to introduce randomness as part of a yield - priv steal_for_yield: bool + priv steal_for_yield: bool, + + // n.b. currently destructors of an object are run in top-to-bottom in order + // of field declaration. Due to its nature, the pausible idle callback + // must have some sort of handle to the event loop, so it needs to get + // destroyed before the event loop itself. For this reason, we destroy + // the event loop last to ensure that any unsafe references to it are + // destroyed before it's actually destroyed. + + /// The event loop used to drive the scheduler and perform I/O + event_loop: ~EventLoop, } /// An indication of how hard to work on a given operation, the difference @@ -330,6 +338,12 @@ impl Scheduler { this.process_task(task, Scheduler::resume_task_immediately_cl); return None; } + Some(RunOnce(task)) => { + // bypass the process_task logic to force running this task once + // on this home scheduler. This is often used for I/O (homing). + Scheduler::resume_task_immediately_cl(this, task); + return None; + } Some(Wake) => { this.sleepy = false; Local::put(this); @@ -789,7 +803,8 @@ pub enum SchedMessage { Wake, Shutdown, PinnedTask(~Task), - TaskFromFriend(~Task) + TaskFromFriend(~Task), + RunOnce(~Task), } pub struct SchedHandle { @@ -905,7 +920,7 @@ mod test { use cell::Cell; use rt::thread::Thread; use rt::task::{Task, Sched}; - use rt::rtio::EventLoop; + use rt::basic; use rt::util; use option::{Some}; @@ -1005,7 +1020,6 @@ mod test { #[test] fn test_schedule_home_states() { - use rt::uv::uvio::UvEventLoop; use rt::sleeper_list::SleeperList; use rt::work_queue::WorkQueue; use rt::sched::Shutdown; @@ -1021,7 +1035,7 @@ mod test { // Our normal scheduler let mut normal_sched = ~Scheduler::new( - ~UvEventLoop::new() as ~EventLoop, + basic::event_loop(), normal_queue, queues.clone(), sleepers.clone()); @@ -1032,7 +1046,7 @@ mod test { // Our special scheduler let mut special_sched = ~Scheduler::new_special( - ~UvEventLoop::new() as ~EventLoop, + basic::event_loop(), special_queue.clone(), queues.clone(), sleepers.clone(), @@ -1137,22 +1151,15 @@ mod test { #[test] fn test_io_callback() { + use rt::io::timer; + // This is a regression test that when there are no schedulable tasks // in the work queue, but we are performing I/O, that once we do put // something in the work queue again the scheduler picks it up and doesn't // exit before emptying the work queue - do run_in_newsched_task { + do run_in_uv_task { do spawntask { - let sched: ~Scheduler = Local::take(); - do sched.deschedule_running_task_and_then |sched, task| { - let task = Cell::new(task); - do sched.event_loop.callback_ms(10) { - rtdebug!("in callback"); - let mut sched: ~Scheduler = Local::take(); - sched.enqueue_blocked_task(task.take()); - Local::put(sched); - } - } + timer::sleep(10); } } } @@ -1192,7 +1199,6 @@ mod test { use rt::work_queue::WorkQueue; use rt::sleeper_list::SleeperList; use rt::stack::StackPool; - use rt::uv::uvio::UvEventLoop; use rt::sched::{Shutdown, TaskFromFriend}; use util; @@ -1203,7 +1209,7 @@ mod test { let queues = ~[queue.clone()]; let mut sched = ~Scheduler::new( - ~UvEventLoop::new() as ~EventLoop, + basic::event_loop(), queue, queues.clone(), sleepers.clone()); diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 1ea68bb52d7..f82eb929a39 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -23,6 +23,7 @@ use option::{Option, Some, None}; use rt::borrowck; use rt::borrowck::BorrowRecord; use rt::env; +use rt::io::Writer; use rt::kill::Death; use rt::local::Local; use rt::logging::StdErrLogger; @@ -56,7 +57,8 @@ pub struct Task { sched: Option<~Scheduler>, task_type: TaskType, // Dynamic borrowck debugging info - borrow_list: Option<~[BorrowRecord]> + borrow_list: Option<~[BorrowRecord]>, + stdout_handle: Option<~Writer>, } pub enum TaskType { @@ -141,7 +143,8 @@ impl Task { name: None, sched: None, task_type: SchedTask, - borrow_list: None + borrow_list: None, + stdout_handle: None, } } @@ -175,7 +178,8 @@ impl Task { coroutine: Some(Coroutine::new(stack_pool, stack_size, start)), sched: None, task_type: GreenTask(Some(home)), - borrow_list: None + borrow_list: None, + stdout_handle: None, } } @@ -198,7 +202,8 @@ impl Task { coroutine: Some(Coroutine::new(stack_pool, stack_size, start)), sched: None, task_type: GreenTask(Some(home)), - borrow_list: None + borrow_list: None, + stdout_handle: None, } } @@ -234,6 +239,7 @@ impl Task { // Run the task main function, then do some cleanup. do f.finally { + // First, destroy task-local storage. This may run user dtors. // // FIXME #8302: Dear diary. I'm so tired and confused. @@ -257,6 +263,17 @@ impl Task { // Destroy remaining boxes. Also may run user dtors. unsafe { cleanup::annihilate(); } + + // Finally flush and destroy any output handles which the task + // owns. There are no boxes here, and no user destructors should + // run after this any more. + match self.stdout_handle.take() { + Some(handle) => { + let mut handle = handle; + handle.flush(); + } + None => {} + } } } @@ -331,7 +348,7 @@ impl Task { impl Drop for Task { fn drop(&mut self) { rtdebug!("called drop for a task: {}", borrow::to_uint(self)); - rtassert!(self.destroyed) + rtassert!(self.destroyed); } } @@ -637,7 +654,7 @@ mod test { #[test] fn rng() { - do run_in_newsched_task() { + do run_in_uv_task() { use rand::{rng, Rng}; let mut r = rng(); let _ = r.next_u32(); @@ -646,7 +663,7 @@ mod test { #[test] fn logging() { - do run_in_newsched_task() { + do run_in_uv_task() { info!("here i am. logging in a newsched task"); } } diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs index c238b1dfba1..e4bbfe0a5a3 100644 --- a/src/libstd/rt/test.rs +++ b/src/libstd/rt/test.rs @@ -21,6 +21,7 @@ use iter::{Iterator, range}; use super::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr}; use vec::{OwnedVector, MutableVector, ImmutableVector}; use path::GenericPath; +use rt::basic; use rt::sched::Scheduler; use rt::rtio::EventLoop; use unstable::{run_in_bare_thread}; @@ -48,6 +49,28 @@ pub fn new_test_uv_sched() -> Scheduler { } +pub fn new_test_sched() -> Scheduler { + + let queue = WorkQueue::new(); + let queues = ~[queue.clone()]; + + let mut sched = Scheduler::new(basic::event_loop(), + queue, + queues, + SleeperList::new()); + + // Don't wait for the Shutdown message + sched.no_sleep = true; + return sched; +} + +pub fn run_in_uv_task(f: ~fn()) { + let f = Cell::new(f); + do run_in_bare_thread { + run_in_uv_task_core(f.take()); + } +} + pub fn run_in_newsched_task(f: ~fn()) { let f = Cell::new(f); do run_in_bare_thread { @@ -55,7 +78,7 @@ pub fn run_in_newsched_task(f: ~fn()) { } } -pub fn run_in_newsched_task_core(f: ~fn()) { +pub fn run_in_uv_task_core(f: ~fn()) { use rt::sched::Shutdown; @@ -72,6 +95,23 @@ pub fn run_in_newsched_task_core(f: ~fn()) { sched.bootstrap(task); } +pub fn run_in_newsched_task_core(f: ~fn()) { + + use rt::sched::Shutdown; + + let mut sched = ~new_test_sched(); + let exit_handle = Cell::new(sched.make_handle()); + + let on_exit: ~fn(bool) = |exit_status| { + exit_handle.take().send(Shutdown); + rtassert!(exit_status); + }; + let mut task = ~Task::new_root(&mut sched.stack_pool, None, f); + task.death.on_exit = Some(on_exit); + + sched.bootstrap(task); +} + #[cfg(target_os="macos")] #[allow(non_camel_case_types)] mod darwin_fd_limit { @@ -310,7 +350,7 @@ pub fn spawntask_thread(f: ~fn()) -> Thread { /// Get a ~Task for testing purposes other than actually scheduling it. pub fn with_test_task(blk: ~fn(~Task) -> ~Task) { do run_in_bare_thread { - let mut sched = ~new_test_uv_sched(); + let mut sched = ~new_test_sched(); let task = blk(~Task::new_root(&mut sched.stack_pool, None, ||{})); cleanup_task(task); } diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs index 29370c484eb..dc202ecc174 100644 --- a/src/libstd/rt/uv/uvio.rs +++ b/src/libstd/rt/uv/uvio.rs @@ -29,7 +29,7 @@ use rt::local::Local; use rt::rtio::*; use rt::sched::{Scheduler, SchedHandle}; use rt::tube::Tube; -use rt::task::SchedHome; +use rt::task::Task; use rt::uv::*; use rt::uv::idle::IdleWatcher; use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr}; @@ -59,50 +59,56 @@ trait HomingIO { fn home<'r>(&'r mut self) -> &'r mut SchedHandle; - /* XXX This will move pinned tasks to do IO on the proper scheduler - * and then move them back to their home. - */ - fn go_to_IO_home(&mut self) -> SchedHome { - use rt::sched::PinnedTask; + /// This function will move tasks to run on their home I/O scheduler. Note + /// that this function does *not* pin the task to the I/O scheduler, but + /// rather it simply moves it to running on the I/O scheduler. + fn go_to_IO_home(&mut self) -> uint { + use rt::sched::RunOnce; - do task::unkillable { // FIXME(#8674) - let mut old = None; - { - let ptr = &mut old; + let current_sched_id = do Local::borrow |sched: &mut Scheduler| { + sched.sched_id() + }; + + // Only need to invoke a context switch if we're not on the right + // scheduler. + if current_sched_id != self.home().sched_id { + do task::unkillable { // FIXME(#8674) let scheduler: ~Scheduler = Local::take(); do scheduler.deschedule_running_task_and_then |_, task| { /* FIXME(#8674) if the task was already killed then wake - * will return None. In that case, the home pointer will never be set. + * will return None. In that case, the home pointer will + * never be set. * - * RESOLUTION IDEA: Since the task is dead, we should just abort the IO action. + * RESOLUTION IDEA: Since the task is dead, we should + * just abort the IO action. */ - do task.wake().map |mut task| { - *ptr = Some(task.take_unwrap_home()); - self.home().send(PinnedTask(task)); + do task.wake().map |task| { + self.home().send(RunOnce(task)); }; } } - old.expect("No old home because task had already been killed.") } + + self.home().sched_id } - // XXX dummy self param - fn restore_original_home(_dummy_self: Option<Self>, old: SchedHome) { - use rt::sched::TaskFromFriend; + // XXX: dummy self parameter + fn restore_original_home(_: Option<Self>, io_home: uint) { + // It would truly be a sad day if we had moved off the home I/O + // scheduler while we were doing I/O. + assert_eq!(Local::borrow(|sched: &mut Scheduler| sched.sched_id()), + io_home); - let old = Cell::new(old); - do task::unkillable { // FIXME(#8674) - let scheduler: ~Scheduler = Local::take(); - do scheduler.deschedule_running_task_and_then |scheduler, task| { - /* FIXME(#8674) if the task was already killed then wake - * will return None. In that case, the home pointer will never be restored. - * - * RESOLUTION IDEA: Since the task is dead, we should just abort the IO action. - */ - do task.wake().map |mut task| { - task.give_home(old.take()); - scheduler.make_handle().send(TaskFromFriend(task)); - }; + // If we were a homed task, then we must send ourselves back to the + // original scheduler. Otherwise, we can just return and keep running + if !Task::on_appropriate_sched() { + do task::unkillable { // FIXME(#8674) + let scheduler: ~Scheduler = Local::take(); + do scheduler.deschedule_running_task_and_then |_, task| { + do task.wake().map |task| { + Scheduler::run_task(task); + }; + } } } } @@ -110,7 +116,7 @@ trait HomingIO { fn home_for_io<A>(&mut self, io: &fn(&mut Self) -> A) -> A { let home = self.go_to_IO_home(); let a = io(self); // do IO - HomingIO::restore_original_home(None::<Self> /* XXX dummy self */, home); + HomingIO::restore_original_home(None::<Self>, home); a // return the result of the IO } @@ -118,7 +124,7 @@ trait HomingIO { let mut this = self; let home = this.go_to_IO_home(); let a = io(this); // do IO - HomingIO::restore_original_home(None::<Self> /* XXX dummy self */, home); + HomingIO::restore_original_home(None::<Self>, home); a // return the result of the IO } @@ -128,7 +134,7 @@ trait HomingIO { let scheduler: ~Scheduler = Local::take(); io_sched(self, scheduler) // do IO and scheduling action }; - HomingIO::restore_original_home(None::<Self> /* XXX dummy self */, home); + HomingIO::restore_original_home(None::<Self>, home); a // return result of IO } } @@ -222,15 +228,6 @@ impl EventLoop for UvEventLoop { } as ~PausibleIdleCallback } - fn callback_ms(&mut self, ms: u64, f: ~fn()) { - let mut timer = TimerWatcher::new(self.uvio.uv_loop()); - do timer.start(ms, 0) |timer, status| { - assert!(status.is_none()); - timer.close(||()); - f(); - } - } - fn remote_callback(&mut self, f: ~fn()) -> ~RemoteCallback { ~UvRemoteCallback::new(self.uvio.uv_loop(), f) as ~RemoteCallback } @@ -1791,7 +1788,7 @@ impl RtioTTY for UvTTY { } fn isatty(&self) -> bool { - unsafe { uvll::guess_handle(self.fd) == uvll::UV_TTY } + unsafe { uvll::guess_handle(self.fd) == uvll::UV_TTY as c_int } } } diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs index 75e6a0c6ca5..18e95c8966e 100644 --- a/src/libstd/rt/uv/uvll.rs +++ b/src/libstd/rt/uv/uvll.rs @@ -977,7 +977,8 @@ pub unsafe fn tty_get_winsize(tty: *uv_tty_t, width: *c_int, #[fixed_stack_segment]; #[inline(never)]; rust_uv_tty_get_winsize(tty, width, height) } -pub unsafe fn guess_handle(fd: c_int) -> uv_handle_type { +// FIXME(#9613) this should return uv_handle_type, not a c_int +pub unsafe fn guess_handle(fd: c_int) -> c_int { #[fixed_stack_segment]; #[inline(never)]; rust_uv_guess_handle(fd) } @@ -1148,7 +1149,7 @@ extern { fn rust_uv_tty_set_mode(tty: *uv_tty_t, mode: c_int) -> c_int; fn rust_uv_tty_get_winsize(tty: *uv_tty_t, width: *c_int, height: *c_int) -> c_int; - fn rust_uv_guess_handle(fd: c_int) -> uv_handle_type; + fn rust_uv_guess_handle(fd: c_int) -> c_int; // XXX: see comments in addrinfo.rs // These should all really be constants... diff --git a/src/libstd/select.rs b/src/libstd/select.rs index 62a09984794..75b09187f04 100644 --- a/src/libstd/select.rs +++ b/src/libstd/select.rs @@ -183,7 +183,7 @@ mod test { #[test] fn select_one() { - do run_in_newsched_task { select_helper(1, [0]) } + do run_in_uv_task { select_helper(1, [0]) } } #[test] @@ -191,14 +191,14 @@ mod test { // NB. I would like to have a test that tests the first one that is // ready is the one that's returned, but that can't be reliably tested // with the randomized behaviour of optimistic_check. - do run_in_newsched_task { select_helper(2, [1]) } - do run_in_newsched_task { select_helper(2, [0]) } - do run_in_newsched_task { select_helper(2, [1,0]) } + do run_in_uv_task { select_helper(2, [1]) } + do run_in_uv_task { select_helper(2, [0]) } + do run_in_uv_task { select_helper(2, [1,0]) } } #[test] fn select_a_lot() { - do run_in_newsched_task { select_helper(12, [7,8,9]) } + do run_in_uv_task { select_helper(12, [7,8,9]) } } #[test] @@ -208,7 +208,7 @@ mod test { // Sends 10 buffered packets, and uses select to retrieve them all. // Puts the port in a different spot in the vector each time. - do run_in_newsched_task { + do run_in_uv_task { let (ports, _) = unzip(range(0u, 10).map(|_| stream::<int>())); let (port, chan) = stream(); do 10.times { chan.send(31337); } @@ -229,7 +229,7 @@ mod test { #[test] fn select_unkillable() { - do run_in_newsched_task { + do run_in_uv_task { do task::unkillable { select_helper(2, [1]) } } } @@ -242,7 +242,7 @@ mod test { select_blocking_helper(false); fn select_blocking_helper(killable: bool) { - do run_in_newsched_task { + do run_in_uv_task { let (p1,_c) = oneshot(); let (p2,c2) = oneshot(); let mut ports = [p1,p2]; @@ -287,7 +287,7 @@ mod test { fn select_racing_senders_helper(killable: bool, send_on_chans: ~[uint]) { use rt::test::spawntask_random; - do run_in_newsched_task { + do run_in_uv_task { // A bit of stress, since ordinarily this is just smoke and mirrors. do 4.times { let send_on_chans = send_on_chans.clone(); @@ -318,7 +318,7 @@ mod test { #[test] fn select_killed() { - do run_in_newsched_task { + do run_in_uv_task { let (success_p, success_c) = oneshot::<bool>(); let success_c = Cell::new(success_c); do task::try { diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index 30c99c62885..b72d6773ec5 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -645,7 +645,7 @@ fn test_kill_unkillable_task() { // CPU, *after* the spawner is already switched-back-to (and passes the // killed check at the start of its timeslice). As far as I know, it's not // possible to make this race deterministic, or even more likely to happen. - do run_in_newsched_task { + do run_in_uv_task { do task::try { do task::spawn { fail!(); @@ -662,7 +662,7 @@ fn test_kill_rekillable_task() { // Tests that when a kill signal is received, 'rekillable' and // 'unkillable' unwind correctly in conjunction with each other. - do run_in_newsched_task { + do run_in_uv_task { do task::try { do task::unkillable { do task::rekillable { @@ -730,8 +730,8 @@ fn block_forever() { let (po, _ch) = stream::<()>(); po.recv(); } #[ignore(reason = "linked failure")] #[test] fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let (po, ch) = stream(); let ch = SharedChan::new(ch); do spawn_unlinked { @@ -749,16 +749,16 @@ fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port #[ignore(reason = "linked failure")] #[test] fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { do spawn_unlinked { fail!(); } } } #[ignore(reason = "linked failure")] #[test] fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { do spawn_supervised { fail!(); } // Give child a chance to fail-but-not-kill-us. do 16.times { task::deschedule(); } @@ -767,8 +767,8 @@ fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails #[ignore(reason = "linked failure")] #[test] fn test_spawn_unlinked_sup_fail_down() { - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { do spawn_supervised { block_forever(); } fail!(); // Shouldn't leave a child hanging around. @@ -780,8 +780,8 @@ fn test_spawn_unlinked_sup_fail_down() { #[ignore(reason = "linked failure")] #[test] fn test_spawn_linked_sup_fail_up() { // child fails; parent fails - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // Unidirectional "parenting" shouldn't override bidirectional linked. // We have to cheat with opts - the interface doesn't support them because @@ -801,8 +801,8 @@ fn test_spawn_linked_sup_fail_up() { // child fails; parent fails #[ignore(reason = "linked failure")] #[test] fn test_spawn_linked_sup_fail_down() { // parent fails; child fails - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // We have to cheat with opts - the interface doesn't support them because // they don't make sense (redundant with task().supervised()). @@ -818,8 +818,8 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails #[ignore(reason = "linked failure")] #[test] fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // Default options are to spawn linked & unsupervised. do spawn { fail!(); } @@ -831,8 +831,8 @@ fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails #[ignore(reason = "linked failure")] #[test] fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // Default options are to spawn linked & unsupervised. do spawn { block_forever(); } @@ -844,8 +844,8 @@ fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails #[ignore(reason = "linked failure")] #[test] fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // Make sure the above test is the same as this one. let mut builder = task(); @@ -863,8 +863,8 @@ fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails #[ignore(reason = "linked failure")] #[test] fn test_spawn_failure_propagate_grandchild() { - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // Middle task exits; does grandparent's failure propagate across the gap? do spawn_supervised { @@ -880,8 +880,8 @@ fn test_spawn_failure_propagate_grandchild() { #[ignore(reason = "linked failure")] #[test] fn test_spawn_failure_propagate_secondborn() { - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // First-born child exits; does parent's failure propagate to sibling? do spawn_supervised { @@ -897,8 +897,8 @@ fn test_spawn_failure_propagate_secondborn() { #[ignore(reason = "linked failure")] #[test] fn test_spawn_failure_propagate_nephew_or_niece() { - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // Our sibling exits; does our failure propagate to sibling's child? do spawn { // linked @@ -914,8 +914,8 @@ fn test_spawn_failure_propagate_nephew_or_niece() { #[ignore(reason = "linked failure")] #[test] fn test_spawn_linked_sup_propagate_sibling() { - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result: Result<(),()> = do try { // Middle sibling exits - does eldest's failure propagate to youngest? do spawn { // linked @@ -930,9 +930,9 @@ fn test_spawn_linked_sup_propagate_sibling() { #[test] fn test_unnamed_task() { - use rt::test::run_in_newsched_task; + use rt::test::run_in_uv_task; - do run_in_newsched_task { + do run_in_uv_task { do spawn { do with_task_name |name| { assert!(name.is_none()); @@ -943,9 +943,9 @@ fn test_unnamed_task() { #[test] fn test_owned_named_task() { - use rt::test::run_in_newsched_task; + use rt::test::run_in_uv_task; - do run_in_newsched_task { + do run_in_uv_task { let mut t = task(); t.name(~"ada lovelace"); do t.spawn { @@ -958,9 +958,9 @@ fn test_owned_named_task() { #[test] fn test_static_named_task() { - use rt::test::run_in_newsched_task; + use rt::test::run_in_uv_task; - do run_in_newsched_task { + do run_in_uv_task { let mut t = task(); t.name("ada lovelace"); do t.spawn { @@ -973,9 +973,9 @@ fn test_static_named_task() { #[test] fn test_send_named_task() { - use rt::test::run_in_newsched_task; + use rt::test::run_in_uv_task; - do run_in_newsched_task { + do run_in_uv_task { let mut t = task(); t.name("ada lovelace".into_send_str()); do t.spawn { @@ -1326,9 +1326,9 @@ fn test_child_doesnt_ref_parent() { #[test] fn test_simple_newsched_spawn() { - use rt::test::run_in_newsched_task; + use rt::test::run_in_uv_task; - do run_in_newsched_task { + do run_in_uv_task { spawn(||()) } } @@ -1336,8 +1336,8 @@ fn test_simple_newsched_spawn() { #[ignore(reason = "linked failure")] #[test] fn test_spawn_watched() { - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result = do try { let mut t = task(); t.unlinked(); @@ -1359,8 +1359,8 @@ fn test_spawn_watched() { #[ignore(reason = "linked failure")] #[test] fn test_indestructible() { - use rt::test::run_in_newsched_task; - do run_in_newsched_task { + use rt::test::run_in_uv_task; + do run_in_uv_task { let result = do try { let mut t = task(); t.watched(); diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index 9d15dd031e0..2b036c318ba 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -334,6 +334,23 @@ impl LittleLock { } } } + + pub unsafe fn signal(&self) { + rust_signal_little_lock(self.l); + } + + pub unsafe fn lock_and_wait(&self, f: &fn() -> bool) { + do atomically { + rust_lock_little_lock(self.l); + do (|| { + if f() { + rust_wait_little_lock(self.l); + } + }).finally { + rust_unlock_little_lock(self.l); + } + } + } } struct ExData<T> { @@ -402,6 +419,34 @@ impl<T:Send> Exclusive<T> { } } + #[inline] + pub unsafe fn hold_and_signal(&self, f: &fn(x: &mut T)) { + let rec = self.x.get(); + do (*rec).lock.lock { + if (*rec).failed { + fail!("Poisoned Exclusive::new - another task failed inside!"); + } + (*rec).failed = true; + f(&mut (*rec).data); + (*rec).failed = false; + (*rec).lock.signal(); + } + } + + #[inline] + pub unsafe fn hold_and_wait(&self, f: &fn(x: &T) -> bool) { + let rec = self.x.get(); + do (*rec).lock.lock_and_wait { + if (*rec).failed { + fail!("Poisoned Exclusive::new - another task failed inside!"); + } + (*rec).failed = true; + let result = f(&(*rec).data); + (*rec).failed = false; + result + } + } + pub fn unwrap(self) -> T { let Exclusive { x: x } = self; // Someday we might need to unkillably unwrap an Exclusive, but not today. @@ -415,6 +460,8 @@ externfn!(fn rust_create_little_lock() -> rust_little_lock) externfn!(fn rust_destroy_little_lock(lock: rust_little_lock)) externfn!(fn rust_lock_little_lock(lock: rust_little_lock)) externfn!(fn rust_unlock_little_lock(lock: rust_little_lock)) +externfn!(fn rust_signal_little_lock(lock: rust_little_lock)) +externfn!(fn rust_wait_little_lock(lock: rust_little_lock)) #[cfg(test)] mod tests { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 77020537661..a8eec52943e 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -377,6 +377,16 @@ rust_unlock_little_lock(lock_and_signal *lock) { lock->unlock(); } +extern "C" void +rust_wait_little_lock(lock_and_signal *lock) { + lock->wait(); +} + +extern "C" void +rust_signal_little_lock(lock_and_signal *lock) { + lock->signal(); +} + typedef void(startfn)(void*, void*); class raw_thread: public rust_thread { diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 0cbbb58d02c..c59dacab889 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -659,7 +659,7 @@ rust_uv_tty_get_winsize(uv_tty_t *tty, int *width, int *height) { return uv_tty_get_winsize(tty, width, height); } -extern "C" uv_handle_type +extern "C" int rust_uv_guess_handle(int fd) { return uv_guess_handle(fd); } diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 269da8e7882..06f4c0006f1 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -128,6 +128,8 @@ rust_create_little_lock rust_destroy_little_lock rust_lock_little_lock rust_unlock_little_lock +rust_signal_little_lock +rust_wait_little_lock tdefl_compress_mem_to_heap tinfl_decompress_mem_to_heap rust_uv_ip4_port diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index b3c3fa4db6f..84426edf3bf 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/bad-bang-ann-3.rs b/src/test/compile-fail/bad-bang-ann-3.rs index 9e73bbe1406..d899459b70a 100644 --- a/src/test/compile-fail/bad-bang-ann-3.rs +++ b/src/test/compile-fail/bad-bang-ann-3.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/bad-bang-ann.rs b/src/test/compile-fail/bad-bang-ann.rs index 2ffb5dd2906..829253bde18 100644 --- a/src/test/compile-fail/bad-bang-ann.rs +++ b/src/test/compile-fail/bad-bang-ann.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/bogus-tag.rs b/src/test/compile-fail/bogus-tag.rs index 63d12b72cc6..1bd40ce24bc 100644 --- a/src/test/compile-fail/bogus-tag.rs +++ b/src/test/compile-fail/bogus-tag.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/capture1.rs b/src/test/compile-fail/capture1.rs index 706edd0a112..7d590ca49dd 100644 --- a/src/test/compile-fail/capture1.rs +++ b/src/test/compile-fail/capture1.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/dead-code-ret.rs b/src/test/compile-fail/dead-code-ret.rs index b6976b2c355..1d59406d1bc 100644 --- a/src/test/compile-fail/dead-code-ret.rs +++ b/src/test/compile-fail/dead-code-ret.rs @@ -3,7 +3,6 @@ // xfail'd because the lint pass doesn't know to ignore standard library // stuff. -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/fail-simple.rs b/src/test/compile-fail/fail-simple.rs index 7def16770a7..19c1aa1ba20 100644 --- a/src/test/compile-fail/fail-simple.rs +++ b/src/test/compile-fail/fail-simple.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/foreign-unsafe-fn-called.rs b/src/test/compile-fail/foreign-unsafe-fn-called.rs index 38c1a32b12e..88fe9cd44a3 100644 --- a/src/test/compile-fail/foreign-unsafe-fn-called.rs +++ b/src/test/compile-fail/foreign-unsafe-fn-called.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/infinite-tag-type-recursion.rs b/src/test/compile-fail/infinite-tag-type-recursion.rs index 0974668f19d..8a73e70572e 100644 --- a/src/test/compile-fail/infinite-tag-type-recursion.rs +++ b/src/test/compile-fail/infinite-tag-type-recursion.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/infinite-vec-type-recursion.rs b/src/test/compile-fail/infinite-vec-type-recursion.rs index a307f9f26d5..9f9fd43fcdf 100644 --- a/src/test/compile-fail/infinite-vec-type-recursion.rs +++ b/src/test/compile-fail/infinite-vec-type-recursion.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/liveness-bad-bang-2.rs b/src/test/compile-fail/liveness-bad-bang-2.rs index 5399127fcb6..eeb07c71e9b 100644 --- a/src/test/compile-fail/liveness-bad-bang-2.rs +++ b/src/test/compile-fail/liveness-bad-bang-2.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/liveness-forgot-ret.rs b/src/test/compile-fail/liveness-forgot-ret.rs index 288743e4d4d..305cbcad738 100644 --- a/src/test/compile-fail/liveness-forgot-ret.rs +++ b/src/test/compile-fail/liveness-forgot-ret.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/liveness-init-in-fru.rs b/src/test/compile-fail/liveness-init-in-fru.rs index 96b3c2453c5..97fc2b4d44c 100644 --- a/src/test/compile-fail/liveness-init-in-fru.rs +++ b/src/test/compile-fail/liveness-init-in-fru.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/multiline-comment-line-tracking.rs b/src/test/compile-fail/multiline-comment-line-tracking.rs index 6bf3661ad14..11abe672745 100644 --- a/src/test/compile-fail/multiline-comment-line-tracking.rs +++ b/src/test/compile-fail/multiline-comment-line-tracking.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. @@ -9,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:9:3 +// error-pattern:18:3 /* 1 * 2 * 3 */ fn main() { - %; // parse error on line 9, but is reported on line 6 instead. + %; // parse error on line 18, but is reported on line 6 instead. } diff --git a/src/test/compile-fail/non-exhaustive-match-nested.rs b/src/test/compile-fail/non-exhaustive-match-nested.rs index b87b3c5245a..102772f79d5 100644 --- a/src/test/compile-fail/non-exhaustive-match-nested.rs +++ b/src/test/compile-fail/non-exhaustive-match-nested.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/not-a-pred.rs b/src/test/compile-fail/not-a-pred.rs index 47b2794d132..2e16c58eaad 100644 --- a/src/test/compile-fail/not-a-pred.rs +++ b/src/test/compile-fail/not-a-pred.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/pattern-tyvar-2.rs b/src/test/compile-fail/pattern-tyvar-2.rs index 537d095d2d7..c6bc752b0cc 100644 --- a/src/test/compile-fail/pattern-tyvar-2.rs +++ b/src/test/compile-fail/pattern-tyvar-2.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/pattern-tyvar.rs b/src/test/compile-fail/pattern-tyvar.rs index b81e4ea92d0..b3e907f913f 100644 --- a/src/test/compile-fail/pattern-tyvar.rs +++ b/src/test/compile-fail/pattern-tyvar.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/type-shadow.rs b/src/test/compile-fail/type-shadow.rs index c4a412f64c8..50c8cf99d3c 100644 --- a/src/test/compile-fail/type-shadow.rs +++ b/src/test/compile-fail/type-shadow.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/unbalanced-doublequote.rs b/src/test/compile-fail/unbalanced-doublequote.rs index a2b0c3a9eb3..789cc886217 100644 --- a/src/test/compile-fail/unbalanced-doublequote.rs +++ b/src/test/compile-fail/unbalanced-doublequote.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs b/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs index a6a1dd3b334..a9480c60886 100644 --- a/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs +++ b/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/unsafe-fn-autoderef.rs b/src/test/compile-fail/unsafe-fn-autoderef.rs index 82efd579518..4572e084f66 100644 --- a/src/test/compile-fail/unsafe-fn-autoderef.rs +++ b/src/test/compile-fail/unsafe-fn-autoderef.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/unsafe-fn-called-from-safe.rs b/src/test/compile-fail/unsafe-fn-called-from-safe.rs index 2ea0f5a4ec9..15bcad95cb2 100644 --- a/src/test/compile-fail/unsafe-fn-called-from-safe.rs +++ b/src/test/compile-fail/unsafe-fn-called-from-safe.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/unsafe-fn-deref-ptr.rs b/src/test/compile-fail/unsafe-fn-deref-ptr.rs index c02e1f9f0b8..fb631e02b6f 100644 --- a/src/test/compile-fail/unsafe-fn-deref-ptr.rs +++ b/src/test/compile-fail/unsafe-fn-deref-ptr.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/compile-fail/unsafe-fn-used-as-value.rs b/src/test/compile-fail/unsafe-fn-used-as-value.rs index b5565b4821b..8e2d82b8fdb 100644 --- a/src/test/compile-fail/unsafe-fn-used-as-value.rs +++ b/src/test/compile-fail/unsafe-fn-used-as-value.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-fail/addr-of-bot.rs b/src/test/run-fail/addr-of-bot.rs new file mode 100644 index 00000000000..45dbe11c76e --- /dev/null +++ b/src/test/run-fail/addr-of-bot.rs @@ -0,0 +1,15 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern:explicit failure + +fn main() { + &fail!() +} diff --git a/src/test/run-fail/linked-failure.rs b/src/test/run-fail/linked-failure.rs index 52dfb8aef13..8426c4ba7d5 100644 --- a/src/test/run-fail/linked-failure.rs +++ b/src/test/run-fail/linked-failure.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-fail/linked-failure2.rs b/src/test/run-fail/linked-failure2.rs index 52a67872d4c..a8bc2b63beb 100644 --- a/src/test/run-fail/linked-failure2.rs +++ b/src/test/run-fail/linked-failure2.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-fail/linked-failure3.rs b/src/test/run-fail/linked-failure3.rs index f40eae20bc0..51a5d6d112e 100644 --- a/src/test/run-fail/linked-failure3.rs +++ b/src/test/run-fail/linked-failure3.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-fail/linked-failure4.rs b/src/test/run-fail/linked-failure4.rs index 94e41f1ae68..bdcdcb9c53e 100644 --- a/src/test/run-fail/linked-failure4.rs +++ b/src/test/run-fail/linked-failure4.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-fail/str-overrun.rs b/src/test/run-fail/str-overrun.rs index 5ec2c093eeb..5e158fe7418 100644 --- a/src/test/run-fail/str-overrun.rs +++ b/src/test/run-fail/str-overrun.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-fail/vec-overrun.rs b/src/test/run-fail/vec-overrun.rs index 411895a2ef0..e7421fe241d 100644 --- a/src/test/run-fail/vec-overrun.rs +++ b/src/test/run-fail/vec-overrun.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/auto-instantiate.rs b/src/test/run-pass/auto-instantiate.rs index b7e3de478a4..a4b6d33fb79 100644 --- a/src/test/run-pass/auto-instantiate.rs +++ b/src/test/run-pass/auto-instantiate.rs @@ -11,7 +11,6 @@ -// -*- rust -*- struct Pair<T, U> { a: T, b: U } struct Triple { x: int, y: int, z: int } diff --git a/src/test/run-pass/bitwise.rs b/src/test/run-pass/bitwise.rs index 169b3848c63..61e36d2d720 100644 --- a/src/test/run-pass/bitwise.rs +++ b/src/test/run-pass/bitwise.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/bool-not.rs b/src/test/run-pass/bool-not.rs index 3d659d5d256..e98087810b2 100644 --- a/src/test/run-pass/bool-not.rs +++ b/src/test/run-pass/bool-not.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { if !false { assert!((true)); } else { assert!((false)); } if !true { assert!((false)); } else { assert!((true)); } diff --git a/src/test/run-pass/cast.rs b/src/test/run-pass/cast.rs index 8cf7c2eec99..f8a680b2a97 100644 --- a/src/test/run-pass/cast.rs +++ b/src/test/run-pass/cast.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// -*- rust -*- pub fn main() { let i: int = 'Q' as int; assert_eq!(i, 0x51); diff --git a/src/test/run-pass/comm.rs b/src/test/run-pass/comm.rs index a41f1fa42cd..18c6050095f 100644 --- a/src/test/run-pass/comm.rs +++ b/src/test/run-pass/comm.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/complex.rs b/src/test/run-pass/complex.rs index 11599f6b1e3..8ce7cb14042 100644 --- a/src/test/run-pass/complex.rs +++ b/src/test/run-pass/complex.rs @@ -11,7 +11,6 @@ -// -*- rust -*- type t = int; fn nothing() { } diff --git a/src/test/run-pass/dead-code-one-arm-if.rs b/src/test/run-pass/dead-code-one-arm-if.rs index 2749fc31cea..da5c692d212 100644 --- a/src/test/run-pass/dead-code-one-arm-if.rs +++ b/src/test/run-pass/dead-code-one-arm-if.rs @@ -11,5 +11,4 @@ -// -*- rust -*- pub fn main() { if 1 == 1 { return; } info!("Paul is dead"); } diff --git a/src/test/run-pass/deep.rs b/src/test/run-pass/deep.rs index ebb033d188e..2f82e729adf 100644 --- a/src/test/run-pass/deep.rs +++ b/src/test/run-pass/deep.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn f(x: int) -> int { if x == 1 { return 1; } else { let y: int = 1 + f(x - 1); return y; } } diff --git a/src/test/run-pass/div-mod.rs b/src/test/run-pass/div-mod.rs index 3aeaef01e18..331cd36a694 100644 --- a/src/test/run-pass/div-mod.rs +++ b/src/test/run-pass/div-mod.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let x: int = 15; let y: int = 5; diff --git a/src/test/run-pass/drop-on-ret.rs b/src/test/run-pass/drop-on-ret.rs index afc9e532ad8..6e2c709eec0 100644 --- a/src/test/run-pass/drop-on-ret.rs +++ b/src/test/run-pass/drop-on-ret.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn f() -> int { if true { let _s: ~str = ~"should not leak"; diff --git a/src/test/run-pass/expr-block-box.rs b/src/test/run-pass/expr-block-box.rs index 8385c95d999..af1fab2b595 100644 --- a/src/test/run-pass/expr-block-box.rs +++ b/src/test/run-pass/expr-block-box.rs @@ -11,5 +11,4 @@ -// -*- rust -*- pub fn main() { let x = { @100 }; assert!((*x == 100)); } diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs index 086a5b12292..562c3c1e523 100644 --- a/src/test/run-pass/expr-block-generic-box2.rs +++ b/src/test/run-pass/expr-block-generic-box2.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/expr-block-generic-unique1.rs b/src/test/run-pass/expr-block-generic-unique1.rs index b225f1a8ddf..159c2bfb8ef 100644 --- a/src/test/run-pass/expr-block-generic-unique1.rs +++ b/src/test/run-pass/expr-block-generic-unique1.rs @@ -10,7 +10,6 @@ -// -*- rust -*- type compare<'self, T> = &'self fn(~T, ~T) -> bool; fn test_generic<T:Clone>(expected: ~T, eq: compare<T>) { diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs index 3484a4f7f5a..ff811a9f458 100644 --- a/src/test/run-pass/expr-block-generic-unique2.rs +++ b/src/test/run-pass/expr-block-generic-unique2.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -// -*- rust -*- type compare<'self, T> = &'self fn(T, T) -> bool; diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs index 2f379602c6b..800f22169d3 100644 --- a/src/test/run-pass/expr-block-generic.rs +++ b/src/test/run-pass/expr-block-generic.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/expr-block-unique.rs b/src/test/run-pass/expr-block-unique.rs index 72151f7abe6..6ef7ffe86fa 100644 --- a/src/test/run-pass/expr-block-unique.rs +++ b/src/test/run-pass/expr-block-unique.rs @@ -11,5 +11,4 @@ -// -*- rust -*- pub fn main() { let x = { ~100 }; assert!((*x == 100)); } diff --git a/src/test/run-pass/expr-block.rs b/src/test/run-pass/expr-block.rs index e43377c71fe..ee1d955b0d3 100644 --- a/src/test/run-pass/expr-block.rs +++ b/src/test/run-pass/expr-block.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for standalone blocks as expressions fn test_basic() { let rs: bool = { true }; assert!((rs)); } diff --git a/src/test/run-pass/expr-if-box.rs b/src/test/run-pass/expr-if-box.rs index e560da224ff..d31723f9c6c 100644 --- a/src/test/run-pass/expr-if-box.rs +++ b/src/test/run-pass/expr-if-box.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for if as expressions returning boxed types fn test_box() { diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs index 1bbf3a537db..8e6e3f7ddda 100644 --- a/src/test/run-pass/expr-if-generic.rs +++ b/src/test/run-pass/expr-if-generic.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -// -*- rust -*- // Tests for if as expressions with dynamic type sizes type compare<T> = &'static fn(T, T) -> bool; diff --git a/src/test/run-pass/expr-if-struct.rs b/src/test/run-pass/expr-if-struct.rs index 00e0fe1f582..c40f2aa01c1 100644 --- a/src/test/run-pass/expr-if-struct.rs +++ b/src/test/run-pass/expr-if-struct.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for if as expressions returning nominal types diff --git a/src/test/run-pass/expr-if-unique.rs b/src/test/run-pass/expr-if-unique.rs index 22714619271..b40dc03ccfb 100644 --- a/src/test/run-pass/expr-if-unique.rs +++ b/src/test/run-pass/expr-if-unique.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for if as expressions returning boxed types fn test_box() { diff --git a/src/test/run-pass/expr-if.rs b/src/test/run-pass/expr-if.rs index 54f831e44b6..23446b3f650 100644 --- a/src/test/run-pass/expr-if.rs +++ b/src/test/run-pass/expr-if.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for if as expressions fn test_if() { let rs: bool = if true { true } else { false }; assert!((rs)); } diff --git a/src/test/run-pass/expr-match-box.rs b/src/test/run-pass/expr-match-box.rs index 84a78637187..5e6abc3e786 100644 --- a/src/test/run-pass/expr-match-box.rs +++ b/src/test/run-pass/expr-match-box.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for match as expressions resulting in boxed types fn test_box() { diff --git a/src/test/run-pass/expr-match-generic-unique1.rs b/src/test/run-pass/expr-match-generic-unique1.rs index 7371f8fd89b..b4bc7d3bef6 100644 --- a/src/test/run-pass/expr-match-generic-unique1.rs +++ b/src/test/run-pass/expr-match-generic-unique1.rs @@ -10,7 +10,6 @@ -// -*- rust -*- type compare<T> = &'static fn(~T, ~T) -> bool; fn test_generic<T:Clone>(expected: ~T, eq: compare<T>) { diff --git a/src/test/run-pass/expr-match-generic-unique2.rs b/src/test/run-pass/expr-match-generic-unique2.rs index d07d40e6757..8eb5861f71e 100644 --- a/src/test/run-pass/expr-match-generic-unique2.rs +++ b/src/test/run-pass/expr-match-generic-unique2.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -// -*- rust -*- type compare<'self, T> = &'self fn(T, T) -> bool; diff --git a/src/test/run-pass/expr-match-generic.rs b/src/test/run-pass/expr-match-generic.rs index b43085d346f..842fdf0b4fc 100644 --- a/src/test/run-pass/expr-match-generic.rs +++ b/src/test/run-pass/expr-match-generic.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-fast -// -*- rust -*- type compare<T> = extern "Rust" fn(T, T) -> bool; diff --git a/src/test/run-pass/expr-match-struct.rs b/src/test/run-pass/expr-match-struct.rs index 7cfcc38f8dd..66ab591bb52 100644 --- a/src/test/run-pass/expr-match-struct.rs +++ b/src/test/run-pass/expr-match-struct.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for match as expressions resulting in struct types struct R { i: int } diff --git a/src/test/run-pass/expr-match-unique.rs b/src/test/run-pass/expr-match-unique.rs index cdd4e45877a..85c6652c5aa 100644 --- a/src/test/run-pass/expr-match-unique.rs +++ b/src/test/run-pass/expr-match-unique.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for match as expressions resulting in boxed types fn test_box() { diff --git a/src/test/run-pass/expr-match.rs b/src/test/run-pass/expr-match.rs index 1e9ad5283d1..b8996de4199 100644 --- a/src/test/run-pass/expr-match.rs +++ b/src/test/run-pass/expr-match.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Tests for using match as an expression fn test_basic() { diff --git a/src/test/run-pass/fact.rs b/src/test/run-pass/fact.rs index 1c9f5e254f1..2f79784ce54 100644 --- a/src/test/run-pass/fact.rs +++ b/src/test/run-pass/fact.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn f(x: int) -> int { // info!("in f:"); diff --git a/src/test/run-pass/fat-arrow-match.rs b/src/test/run-pass/fat-arrow-match.rs index 63e62e254b8..973da6eab8d 100644 --- a/src/test/run-pass/fat-arrow-match.rs +++ b/src/test/run-pass/fat-arrow-match.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/field-destruction-order.rs b/src/test/run-pass/field-destruction-order.rs new file mode 100644 index 00000000000..1d4c08f0bb5 --- /dev/null +++ b/src/test/run-pass/field-destruction-order.rs @@ -0,0 +1,52 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// In theory, it doesn't matter what order destructors are run in for rust +// because we have explicit ownership of values meaning that there's no need to +// run one before another. With unsafe code, however, there may be a safe +// interface which relies on fields having their destructors run in a particular +// order. At the time of this writing, std::rt::sched::Scheduler is an example +// of a structure which contains unsafe handles to FFI-like types, and the +// destruction order of the fields matters in the sense that some handles need +// to get destroyed before others. +// +// In C++, destruction order happens bottom-to-top in order of field +// declarations, but we currently run them top-to-bottom. I don't think the +// order really matters that much as long as we define what it is. + +struct A; +struct B; +struct C { + a: A, + b: B, +} + +static mut hit: bool = false; + +impl Drop for A { + fn drop(&mut self) { + unsafe { + assert!(!hit); + hit = true; + } + } +} + +impl Drop for B { + fn drop(&mut self) { + unsafe { + assert!(hit); + } + } +} + +pub fn main() { + let _c = C { a: A, b: B }; +} diff --git a/src/test/run-pass/fn-lval.rs b/src/test/run-pass/fn-lval.rs index b19708a9712..4a81d8f0ece 100644 --- a/src/test/run-pass/fn-lval.rs +++ b/src/test/run-pass/fn-lval.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn foo(_f: extern fn(int) -> int) { } fn id(x: int) -> int { return x; } diff --git a/src/test/run-pass/foreach-nested.rs b/src/test/run-pass/foreach-nested.rs index 6987e2cf97d..36c086093cf 100644 --- a/src/test/run-pass/foreach-nested.rs +++ b/src/test/run-pass/foreach-nested.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn two(it: &fn(int)) { it(0); it(1); } pub fn main() { diff --git a/src/test/run-pass/foreach-simple-outer-slot.rs b/src/test/run-pass/foreach-simple-outer-slot.rs index 53201c7a91a..f38ac1ed38b 100644 --- a/src/test/run-pass/foreach-simple-outer-slot.rs +++ b/src/test/run-pass/foreach-simple-outer-slot.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let mut sum: int = 0; do first_ten |i| { info!("main"); info!("{}", i); sum = sum + i; } diff --git a/src/test/run-pass/foreign-mod-src/inner.rs b/src/test/run-pass/foreign-mod-src/inner.rs index 8f92cb95187..2fd316ce348 100644 --- a/src/test/run-pass/foreign-mod-src/inner.rs +++ b/src/test/run-pass/foreign-mod-src/inner.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let f = "Makefile"; let s = rustrt.str_buf(f); diff --git a/src/test/run-pass/foreign-mod.rc b/src/test/run-pass/foreign-mod.rc index a11e89f37be..f5bfbec1f4d 100644 --- a/src/test/run-pass/foreign-mod.rc +++ b/src/test/run-pass/foreign-mod.rc @@ -9,7 +9,6 @@ // except according to those terms. // xfail-test FIXME #7308 -// -*- rust -*- native mod libc = target_libc { fn open(int name, int flags, int mode) -> int; diff --git a/src/test/run-pass/foreign-src/foreign.rs b/src/test/run-pass/foreign-src/foreign.rs index df0d1bcd4b9..2e07795ec27 100644 --- a/src/test/run-pass/foreign-src/foreign.rs +++ b/src/test/run-pass/foreign-src/foreign.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { libc.puts(rustrt.str_buf("hello, extern world 1")); libc.puts(rustrt.str_buf("hello, extern world 2")); diff --git a/src/test/run-pass/foreign.rc b/src/test/run-pass/foreign.rc index 9fdcdca6072..5c794176dd5 100644 --- a/src/test/run-pass/foreign.rc +++ b/src/test/run-pass/foreign.rc @@ -9,7 +9,6 @@ // except according to those terms. // xfail-test -// -*- rust -*- native "cdecl" mod rustrt { fn str_buf(str s) -> int; diff --git a/src/test/run-pass/fun-call-variants.rs b/src/test/run-pass/fun-call-variants.rs index 5011998f929..0edfe174680 100644 --- a/src/test/run-pass/fun-call-variants.rs +++ b/src/test/run-pass/fun-call-variants.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/fun-indirect-call.rs b/src/test/run-pass/fun-indirect-call.rs index 738752924c3..72383104b3c 100644 --- a/src/test/run-pass/fun-indirect-call.rs +++ b/src/test/run-pass/fun-indirect-call.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn f() -> int { return 42; } pub fn main() { diff --git a/src/test/run-pass/generic-fn-infer.rs b/src/test/run-pass/generic-fn-infer.rs index 092a17bf456..2f88a54e3f5 100644 --- a/src/test/run-pass/generic-fn-infer.rs +++ b/src/test/run-pass/generic-fn-infer.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Issue #45: infer type parameters in function applications fn id<T>(x: T) -> T { return x; } diff --git a/src/test/run-pass/generic-fn-twice.rs b/src/test/run-pass/generic-fn-twice.rs index aace9571a09..6b503e711e9 100644 --- a/src/test/run-pass/generic-fn-twice.rs +++ b/src/test/run-pass/generic-fn-twice.rs @@ -11,7 +11,6 @@ -// -*- rust -*- mod foomod { pub fn foo<T>() { } } diff --git a/src/test/run-pass/generic-fn.rs b/src/test/run-pass/generic-fn.rs index 652349dea82..27dc4ad8069 100644 --- a/src/test/run-pass/generic-fn.rs +++ b/src/test/run-pass/generic-fn.rs @@ -10,7 +10,6 @@ #[allow(dead_assignment)]; -// -*- rust -*- fn id<T>(x: T) -> T { return x; } struct Triple {x: int, y: int, z: int} diff --git a/src/test/run-pass/generic-tag-values.rs b/src/test/run-pass/generic-tag-values.rs index 984765c4e51..7c4139664af 100644 --- a/src/test/run-pass/generic-tag-values.rs +++ b/src/test/run-pass/generic-tag-values.rs @@ -11,7 +11,6 @@ -// -*- rust -*- enum noption<T> { some(T), } struct Pair { x: int, y: int } diff --git a/src/test/run-pass/hello.rs b/src/test/run-pass/hello.rs index 93f6c3db255..1322756407a 100644 --- a/src/test/run-pass/hello.rs +++ b/src/test/run-pass/hello.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/i32-sub.rs b/src/test/run-pass/i32-sub.rs index af3b724cfe2..e5451431ade 100644 --- a/src/test/run-pass/i32-sub.rs +++ b/src/test/run-pass/i32-sub.rs @@ -11,5 +11,4 @@ -// -*- rust -*- pub fn main() { let mut x: i32 = -400_i32; x = 0_i32 - x; assert!((x == 400_i32)); } diff --git a/src/test/run-pass/i8-incr.rs b/src/test/run-pass/i8-incr.rs index 799910a6a5f..fbb4e446dd5 100644 --- a/src/test/run-pass/i8-incr.rs +++ b/src/test/run-pass/i8-incr.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let mut x: i8 = -12i8; let y: i8 = -12i8; diff --git a/src/test/run-pass/inner-module.rs b/src/test/run-pass/inner-module.rs index 1e53dd849fc..6dbc80c6a45 100644 --- a/src/test/run-pass/inner-module.rs +++ b/src/test/run-pass/inner-module.rs @@ -11,7 +11,6 @@ -// -*- rust -*- mod inner { pub mod inner2 { pub fn hello() { info!("hello, modular world"); } diff --git a/src/test/run-pass/int.rs b/src/test/run-pass/int.rs index c6632f8cd6c..169be054282 100644 --- a/src/test/run-pass/int.rs +++ b/src/test/run-pass/int.rs @@ -11,5 +11,4 @@ -// -*- rust -*- pub fn main() { let _x: int = 10; } diff --git a/src/test/run-pass/item-name-overload.rs b/src/test/run-pass/item-name-overload.rs index c6b777d3d8a..9aefda4bc71 100644 --- a/src/test/run-pass/item-name-overload.rs +++ b/src/test/run-pass/item-name-overload.rs @@ -11,7 +11,6 @@ -// -*- rust -*- mod foo { pub fn baz() { } } diff --git a/src/test/run-pass/large-records.rs b/src/test/run-pass/large-records.rs index 788d9cf03e0..20ec058b9f4 100644 --- a/src/test/run-pass/large-records.rs +++ b/src/test/run-pass/large-records.rs @@ -11,7 +11,6 @@ -// -*- rust -*- struct Large {a: int, b: int, diff --git a/src/test/run-pass/match-tag.rs b/src/test/run-pass/match-tag.rs index 9eeb12d9c45..25e5a84ffc2 100644 --- a/src/test/run-pass/match-tag.rs +++ b/src/test/run-pass/match-tag.rs @@ -11,7 +11,6 @@ -// -*- rust -*- enum color { rgb(int, int, int), rgba(int, int, int, int), diff --git a/src/test/run-pass/mlist-cycle.rs b/src/test/run-pass/mlist-cycle.rs index cb33feef539..66e7fc4265b 100644 --- a/src/test/run-pass/mlist-cycle.rs +++ b/src/test/run-pass/mlist-cycle.rs @@ -9,7 +9,6 @@ // except according to those terms. // xfail-test -// -*- rust -*- extern mod std; use std::gc; use std::gc::rustrt; diff --git a/src/test/run-pass/mlist.rs b/src/test/run-pass/mlist.rs index 9fba629be2a..13b19a258f6 100644 --- a/src/test/run-pass/mlist.rs +++ b/src/test/run-pass/mlist.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/multiline-comment.rs b/src/test/run-pass/multiline-comment.rs index 08fd933a142..6203d47be5e 100644 --- a/src/test/run-pass/multiline-comment.rs +++ b/src/test/run-pass/multiline-comment.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/mutable-alias-vec.rs b/src/test/run-pass/mutable-alias-vec.rs index 0d08c11b664..9779db91a9c 100644 --- a/src/test/run-pass/mutable-alias-vec.rs +++ b/src/test/run-pass/mutable-alias-vec.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// -*- rust -*- extern mod extra; fn grow(v: &mut ~[int]) { diff --git a/src/test/run-pass/opeq.rs b/src/test/run-pass/opeq.rs index c83a3b7dfd0..1fda2c80608 100644 --- a/src/test/run-pass/opeq.rs +++ b/src/test/run-pass/opeq.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let mut x: int = 1; x *= 2; diff --git a/src/test/run-pass/parse-fail.rs b/src/test/run-pass/parse-fail.rs index cfb5ecb1f5d..087c04e0ff0 100644 --- a/src/test/run-pass/parse-fail.rs +++ b/src/test/run-pass/parse-fail.rs @@ -10,7 +10,6 @@ #[allow(unreachable_code)]; -// -*- rust -*- fn dont_call_me() { fail!(); info!("{}", 1); } pub fn main() { } diff --git a/src/test/run-pass/readalias.rs b/src/test/run-pass/readalias.rs index 7447073b47c..51e955c4761 100644 --- a/src/test/run-pass/readalias.rs +++ b/src/test/run-pass/readalias.rs @@ -11,7 +11,6 @@ -// -*- rust -*- struct Point {x: int, y: int, z: int} fn f(p: Point) { assert!((p.z == 12)); } diff --git a/src/test/run-pass/rec-auto.rs b/src/test/run-pass/rec-auto.rs index 669965bd617..57da2e03832 100644 --- a/src/test/run-pass/rec-auto.rs +++ b/src/test/run-pass/rec-auto.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // Issue #50. diff --git a/src/test/run-pass/rec-extend.rs b/src/test/run-pass/rec-extend.rs index 4e029be8f76..de2e937ee84 100644 --- a/src/test/run-pass/rec-extend.rs +++ b/src/test/run-pass/rec-extend.rs @@ -11,7 +11,6 @@ -// -*- rust -*- struct Point {x: int, y: int} pub fn main() { diff --git a/src/test/run-pass/rec-tup.rs b/src/test/run-pass/rec-tup.rs index fb5c5f3ce01..0dc547f1a02 100644 --- a/src/test/run-pass/rec-tup.rs +++ b/src/test/run-pass/rec-tup.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/rec.rs b/src/test/run-pass/rec.rs index fa3fa01dd4d..b9b5cfebb0b 100644 --- a/src/test/run-pass/rec.rs +++ b/src/test/run-pass/rec.rs @@ -11,7 +11,6 @@ -// -*- rust -*- struct Rect {x: int, y: int, w: int, h: int} fn f(r: Rect, x: int, y: int, w: int, h: int) { diff --git a/src/test/run-pass/ret-bang.rs b/src/test/run-pass/ret-bang.rs index 9754b08cd18..4f9e3c2c1f6 100644 --- a/src/test/run-pass/ret-bang.rs +++ b/src/test/run-pass/ret-bang.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn my_err(s: ~str) -> ! { error!("{:?}", s); fail!(); } fn okay(i: uint) -> int { diff --git a/src/test/run-pass/shadow.rs b/src/test/run-pass/shadow.rs index 050c505b7c1..c5211889f3f 100644 --- a/src/test/run-pass/shadow.rs +++ b/src/test/run-pass/shadow.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/size-and-align.rs b/src/test/run-pass/size-and-align.rs index 4d2309cb869..2caef2d1b9e 100644 --- a/src/test/run-pass/size-and-align.rs +++ b/src/test/run-pass/size-and-align.rs @@ -11,7 +11,6 @@ -// -*- rust -*- enum clam<T> { a(T, int), b, } fn uhoh<T>(v: ~[clam<T>]) { diff --git a/src/test/run-pass/spawn-fn.rs b/src/test/run-pass/spawn-fn.rs index b8f356f80d4..c56991e541f 100644 --- a/src/test/run-pass/spawn-fn.rs +++ b/src/test/run-pass/spawn-fn.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/spawn.rs b/src/test/run-pass/spawn.rs index 5c24c622812..7e486a1129d 100644 --- a/src/test/run-pass/spawn.rs +++ b/src/test/run-pass/spawn.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/spawn2.rs b/src/test/run-pass/spawn2.rs index a94877714c5..81c7483ffef 100644 --- a/src/test/run-pass/spawn2.rs +++ b/src/test/run-pass/spawn2.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/str-append.rs b/src/test/run-pass/str-append.rs index 127838fd9ec..bede746f569 100644 --- a/src/test/run-pass/str-append.rs +++ b/src/test/run-pass/str-append.rs @@ -10,7 +10,6 @@ -// -*- rust -*- extern mod extra; fn test1() { diff --git a/src/test/run-pass/str-concat.rs b/src/test/run-pass/str-concat.rs index 870fc20f771..8b87682384b 100644 --- a/src/test/run-pass/str-concat.rs +++ b/src/test/run-pass/str-concat.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let a: ~str = ~"hello"; let b: ~str = ~"world"; diff --git a/src/test/run-pass/str-multiline.rs b/src/test/run-pass/str-multiline.rs index 28c2cd7a41a..59736829a23 100644 --- a/src/test/run-pass/str-multiline.rs +++ b/src/test/run-pass/str-multiline.rs @@ -10,7 +10,6 @@ -// -*- rust -*- extern mod extra; pub fn main() { diff --git a/src/test/run-pass/tag.rs b/src/test/run-pass/tag.rs index ff251a70f65..bb88e1b3f1e 100644 --- a/src/test/run-pass/tag.rs +++ b/src/test/run-pass/tag.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// -*- rust -*- enum colour { red(int, int), green, } diff --git a/src/test/run-pass/tail-cps.rs b/src/test/run-pass/tail-cps.rs index 22e2304c0ce..d0ba12bec1c 100644 --- a/src/test/run-pass/tail-cps.rs +++ b/src/test/run-pass/tail-cps.rs @@ -11,7 +11,6 @@ -// -*- rust -*- fn checktrue(rs: bool) -> bool { assert!((rs)); return true; } pub fn main() { let k = checktrue; evenk(42, k); oddk(45, k); } diff --git a/src/test/run-pass/tail-direct.rs b/src/test/run-pass/tail-direct.rs index 847e848f0d8..fd03d280503 100644 --- a/src/test/run-pass/tail-direct.rs +++ b/src/test/run-pass/tail-direct.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { assert!((even(42))); assert!((odd(45))); } fn even(n: int) -> bool { if n == 0 { return true; } else { return odd(n - 1); } } diff --git a/src/test/run-pass/task-comm-16.rs b/src/test/run-pass/task-comm-16.rs index d5a4b1a72c9..af4a8f68ac2 100644 --- a/src/test/run-pass/task-comm-16.rs +++ b/src/test/run-pass/task-comm-16.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/task-comm-chan-nil.rs b/src/test/run-pass/task-comm-chan-nil.rs index 8010089f3c6..cd53c633c4e 100644 --- a/src/test/run-pass/task-comm-chan-nil.rs +++ b/src/test/run-pass/task-comm-chan-nil.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/threads.rs b/src/test/run-pass/threads.rs index d5f853fc241..baa2b363a23 100644 --- a/src/test/run-pass/threads.rs +++ b/src/test/run-pass/threads.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/tup.rs b/src/test/run-pass/tup.rs index 795ed1d0f8a..dd508d6e90c 100644 --- a/src/test/run-pass/tup.rs +++ b/src/test/run-pass/tup.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/u32-decr.rs b/src/test/run-pass/u32-decr.rs index f40d06f6c92..6ad320580df 100644 --- a/src/test/run-pass/u32-decr.rs +++ b/src/test/run-pass/u32-decr.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let mut word: u32 = 200000u32; word = word - 1u32; diff --git a/src/test/run-pass/u8-incr-decr.rs b/src/test/run-pass/u8-incr-decr.rs index 18543599fd0..0a178b250af 100644 --- a/src/test/run-pass/u8-incr-decr.rs +++ b/src/test/run-pass/u8-incr-decr.rs @@ -11,7 +11,6 @@ -// -*- rust -*- // These constants were chosen because they aren't used anywhere // in the rest of the generated code so they're easily grep-able. diff --git a/src/test/run-pass/u8-incr.rs b/src/test/run-pass/u8-incr.rs index 1a4013645e8..90ed3a5eec3 100644 --- a/src/test/run-pass/u8-incr.rs +++ b/src/test/run-pass/u8-incr.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let mut x: u8 = 12u8; let y: u8 = 12u8; diff --git a/src/test/run-pass/uint.rs b/src/test/run-pass/uint.rs index 9b645efb936..876e37c5351 100644 --- a/src/test/run-pass/uint.rs +++ b/src/test/run-pass/uint.rs @@ -11,5 +11,4 @@ -// -*- rust -*- pub fn main() { let _x: uint = 10 as uint; } diff --git a/src/test/run-pass/unit.rs b/src/test/run-pass/unit.rs index a74bfc365e8..f42322799c1 100644 --- a/src/test/run-pass/unit.rs +++ b/src/test/run-pass/unit.rs @@ -11,7 +11,6 @@ #[allow(unused_variable)]; #[allow(dead_assignment)]; -// -*- rust -*- fn f(u: ()) { return u; } pub fn main() { diff --git a/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs b/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs index 8b1c003c66f..4ce3f2c53b3 100644 --- a/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs +++ b/src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs b/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs index 1564045a435..e68b868a246 100644 --- a/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs +++ b/src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/vec-concat.rs b/src/test/run-pass/vec-concat.rs index 3a4a424c3b8..7014ad5df14 100644 --- a/src/test/run-pass/vec-concat.rs +++ b/src/test/run-pass/vec-concat.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/vec.rs b/src/test/run-pass/vec.rs index 34fcca9e35b..cb67546dc1b 100644 --- a/src/test/run-pass/vec.rs +++ b/src/test/run-pass/vec.rs @@ -11,7 +11,6 @@ -// -*- rust -*- pub fn main() { let v: ~[int] = ~[10, 20]; assert_eq!(v[0], 10); diff --git a/src/test/run-pass/while-with-break.rs b/src/test/run-pass/while-with-break.rs index 82fb39a7c62..61a13a42fa0 100644 --- a/src/test/run-pass/while-with-break.rs +++ b/src/test/run-pass/while-with-break.rs @@ -1,7 +1,6 @@ -// -*- rust -*- pub fn main() { let mut i: int = 90; while i < 100 { diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index 2c331f29223..47bf6323c32 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index 21088c9dacc..39d6bf7390f 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. diff --git a/src/test/run-pass/yield2.rs b/src/test/run-pass/yield2.rs index aaf4b257f7a..7bc3c1fc1f4 100644 --- a/src/test/run-pass/yield2.rs +++ b/src/test/run-pass/yield2.rs @@ -1,4 +1,3 @@ -// -*- rust -*- // 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. |
