diff options
240 files changed, 3577 insertions, 2503 deletions
diff --git a/Makefile.in b/Makefile.in index d531b9879a9..8ab704ebe17 100644 --- a/Makefile.in +++ b/Makefile.in @@ -101,7 +101,7 @@ endif ifdef CFG_ENABLE_DEBUG $(info cfg: enabling more debugging (CFG_ENABLE_DEBUG)) - CFG_RUSTC_FLAGS += + CFG_RUSTC_FLAGS += --cfg debug CFG_GCCISH_CFLAGS += -DRUST_DEBUG else CFG_GCCISH_CFLAGS += -DRUST_NDEBUG diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index b806df5dd20..2a3d8dc1481 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -157,7 +157,7 @@ pub struct Unique<T> { priv ptr: *mut T } -pub impl<'self, T: Owned> Unique<T> { +pub impl<T: Owned> Unique<T> { fn new(value: T) -> Unique<T> { unsafe { let ptr = malloc(core::sys::size_of::<T>() as size_t) as *mut T; @@ -168,14 +168,14 @@ pub impl<'self, T: Owned> Unique<T> { } } - // the 'self lifetime results in the same semantics as `&*x` with ~T - fn borrow(&self) -> &'self T { - unsafe { cast::transmute(self.ptr) } + // the 'r lifetime results in the same semantics as `&*x` with ~T + fn borrow<'r>(&'r self) -> &'r T { + unsafe { cast::copy_lifetime(self, &*self.ptr) } } - // the 'self lifetime results in the same semantics as `&mut *x` with ~T - fn borrow_mut(&mut self) -> &'self mut T { - unsafe { cast::transmute(self.ptr) } + // the 'r lifetime results in the same semantics as `&mut *x` with ~T + fn borrow_mut<'r>(&'r mut self) -> &'r mut T { + unsafe { cast::copy_mut_lifetime(self, &mut *self.ptr) } } } diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index b03a1404f8e..a3981dd8491 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -29,9 +29,9 @@ pub mod rustrt { #[abi = "cdecl"] #[link_name = "rustrt"] pub extern { - pub unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc, - ++v: **vec::raw::VecRepr, - ++n: libc::size_t); + pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + v: **vec::raw::VecRepr, + n: libc::size_t); } } @@ -60,7 +60,7 @@ pub fn capacity<T>(v: @[T]) -> uint { pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] { let mut vec: @[A] = @[]; unsafe { raw::reserve(&mut vec, size); } - builder(|+x| unsafe { raw::push(&mut vec, x) }); + builder(|x| unsafe { raw::push(&mut vec, x) }); return unsafe { transmute(vec) }; } @@ -102,7 +102,7 @@ pub fn build_sized_opt<A>(size: Option<uint>, #[inline(always)] pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { - for vec::each(lhs) |x| { push(*x); } + for lhs.each |x| { push(*x); } for uint::range(0, rhs.len()) |i| { push(rhs[i]); } } } @@ -111,7 +111,7 @@ pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] { /// Apply a function to each element of a vector and return the results pub fn map<T, U>(v: &[T], f: &fn(x: &T) -> U) -> @[U] { do build_sized(v.len()) |push| { - for vec::each(v) |elem| { + for v.each |elem| { push(f(elem)); } } @@ -166,7 +166,7 @@ pub fn from_slice<T:Copy>(v: &[T]) -> @[T] { from_fn(v.len(), |i| v[i]) } -#[cfg(notest)] +#[cfg(not(test))] pub mod traits { use at_vec::append; use kinds::Copy; diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index 1b4b81dca26..76a8f456cd5 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -10,7 +10,7 @@ //! Boolean logic -#[cfg(notest)] +#[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering}; use option::{None, Option, Some}; use from_str::FromStr; @@ -75,7 +75,7 @@ pub fn all_values(blk: &fn(v: bool)) { #[inline(always)] pub fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for bool { #[inline(always)] fn lt(&self, other: &bool) -> bool { to_bit(*self) < to_bit(*other) } @@ -87,13 +87,13 @@ impl Ord for bool { fn ge(&self, other: &bool) -> bool { to_bit(*self) >= to_bit(*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl TotalOrd for bool { #[inline(always)] fn cmp(&self, other: &bool) -> Ordering { to_bit(*self).cmp(&to_bit(*other)) } } -#[cfg(notest)] +#[cfg(not(test))] impl Eq for bool { #[inline(always)] fn eq(&self, other: &bool) -> bool { (*self) == (*other) } diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index 96e1c3bd124..5e6d2f8b910 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -17,7 +17,7 @@ pub mod rusti { #[abi = "rust-intrinsic"] #[link_name = "rusti"] pub extern "rust-intrinsic" { - fn forget<T>(+x: T); + fn forget<T>(x: T); fn transmute<T,U>(e: T) -> U; } @@ -110,6 +110,12 @@ pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T { /// Transforms lifetime of the second pointer to match the first. #[inline(always)] +pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T { + transmute_mut_region(ptr) +} + +/// Transforms lifetime of the second pointer to match the first. +#[inline(always)] pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T { transmute_region(ptr) } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index a96f1a2ff81..a9c46b81f86 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -10,7 +10,7 @@ //! Utilities for manipulating the char type -#[cfg(notest)] +#[cfg(not(test))] use cmp::Ord; use option::{None, Option, Some}; use str; @@ -18,7 +18,7 @@ use u32; use uint; use unicode::{derived_property, general_category}; -#[cfg(notest)] use cmp::Eq; +#[cfg(not(test))] use cmp::Eq; /* Lu Uppercase_Letter an uppercase letter @@ -244,7 +244,7 @@ pub fn len_utf8_bytes(c: char) -> uint { else { fail!(~"invalid character!") } } -#[cfg(notest)] +#[cfg(not(test))] impl Eq for char { #[inline(always)] fn eq(&self, other: &char) -> bool { (*self) == (*other) } @@ -252,7 +252,7 @@ impl Eq for char { fn ne(&self, other: &char) -> bool { (*self) != (*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for char { #[inline(always)] fn lt(&self, other: &char) -> bool { *self < *other } diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index 424cc348309..912f965db7c 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -15,9 +15,9 @@ use ptr::mut_null; use repr::BoxRepr; use sys::TypeDesc; use cast::transmute; -#[cfg(notest)] use unstable::lang::clear_task_borrow_list; +#[cfg(not(test))] use unstable::lang::clear_task_borrow_list; -#[cfg(notest)] use ptr::to_unsafe_ptr; +#[cfg(not(test))] use ptr::to_unsafe_ptr; /** * Runtime structures @@ -164,7 +164,7 @@ fn debug_mem() -> bool { } /// Destroys all managed memory (i.e. @ boxes) held by the current task. -#[cfg(notest)] +#[cfg(not(test))] #[lang="annihilate"] pub unsafe fn annihilate() { use unstable::lang::local_free; diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index d075ff08bb7..7eaa8535493 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -12,6 +12,7 @@ Message passing */ +use cast::{transmute, transmute_mut}; use cast; use either::{Either, Left, Right}; use kinds::Owned; @@ -118,13 +119,15 @@ pub mod streamp { } /// An endpoint that can send many messages. +#[unsafe_mut_field(endp)] pub struct Chan<T> { - mut endp: Option<streamp::client::Open<T>> + endp: Option<streamp::client::Open<T>> } /// An endpoint that can receive many messages. +#[unsafe_mut_field(endp)] pub struct Port<T> { - mut endp: Option<streamp::server::Open<T>>, + endp: Option<streamp::server::Open<T>>, } /** Creates a `(Port, Chan)` pair. @@ -135,30 +138,39 @@ These allow sending or receiving an unlimited number of messages. pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) { let (c, s) = streamp::init(); - (Port { endp: Some(s) }, Chan { endp: Some(c) }) + (Port { + endp: Some(s) + }, Chan { + endp: Some(c) + }) } impl<T: Owned> GenericChan<T> for Chan<T> { #[inline(always)] fn send(&self, x: T) { - let mut endp = None; - endp <-> self.endp; - self.endp = Some( - streamp::client::data(endp.unwrap(), x)) + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + *self_endp = Some(streamp::client::data(endp.unwrap(), x)) + } } } impl<T: Owned> GenericSmartChan<T> for Chan<T> { #[inline(always)] fn try_send(&self, x: T) -> bool { - let mut endp = None; - endp <-> self.endp; - match streamp::client::try_data(endp.unwrap(), x) { - Some(next) => { - self.endp = Some(next); - true + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + match streamp::client::try_data(endp.unwrap(), x) { + Some(next) => { + *self_endp = Some(next); + true + } + None => false } - None => false } } } @@ -166,23 +178,29 @@ impl<T: Owned> GenericSmartChan<T> for Chan<T> { impl<T: Owned> GenericPort<T> for Port<T> { #[inline(always)] fn recv(&self) -> T { - let mut endp = None; - endp <-> self.endp; - let streamp::data(x, endp) = recv(endp.unwrap()); - self.endp = Some(endp); - x + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + let streamp::data(x, endp) = recv(endp.unwrap()); + *self_endp = Some(endp); + x + } } #[inline(always)] fn try_recv(&self) -> Option<T> { - let mut endp = None; - endp <-> self.endp; - match try_recv(endp.unwrap()) { - Some(streamp::data(x, endp)) => { - self.endp = Some(endp); - Some(x) + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + match try_recv(endp.unwrap()) { + Some(streamp::data(x, endp)) => { + *self_endp = Some(endp); + Some(x) + } + None => None } - None => None } } } @@ -190,22 +208,25 @@ impl<T: Owned> GenericPort<T> for Port<T> { impl<T: Owned> Peekable<T> for Port<T> { #[inline(always)] fn peek(&self) -> bool { - let mut endp = None; - endp <-> self.endp; - let peek = match &endp { - &Some(ref endp) => peek(endp), - &None => fail!(~"peeking empty stream") - }; - self.endp <-> endp; - peek + unsafe { + let mut endp = None; + let mut self_endp = transmute_mut(&self.endp); + endp <-> *self_endp; + let peek = match endp { + Some(ref mut endp) => peek(endp), + None => fail!(~"peeking empty stream") + }; + *self_endp <-> endp; + peek + } } } impl<T: Owned> Selectable for Port<T> { - fn header(&self) -> *PacketHeader { + fn header(&mut self) -> *mut PacketHeader { unsafe { match self.endp { - Some(ref endp) => endp.header(), + Some(ref mut endp) => endp.header(), None => fail!(~"peeking empty stream") } } @@ -213,12 +234,12 @@ impl<T: Owned> Selectable for Port<T> { } /// Treat many ports as one. +#[unsafe_mut_field(ports)] pub struct PortSet<T> { - mut ports: ~[Port<T>], + ports: ~[Port<T>], } pub impl<T: Owned> PortSet<T> { - fn new() -> PortSet<T> { PortSet { ports: ~[] @@ -226,7 +247,10 @@ pub impl<T: Owned> PortSet<T> { } fn add(&self, port: Port<T>) { - self.ports.push(port) + unsafe { + let self_ports = transmute_mut(&self.ports); + self_ports.push(port) + } } fn chan(&self) -> Chan<T> { @@ -238,25 +262,28 @@ pub impl<T: Owned> PortSet<T> { impl<T:Owned> GenericPort<T> for PortSet<T> { fn try_recv(&self) -> Option<T> { - let mut result = None; - // we have to swap the ports array so we aren't borrowing - // aliasable mutable memory. - let mut ports = ~[]; - ports <-> self.ports; - while result.is_none() && ports.len() > 0 { - let i = wait_many(ports); - match ports[i].try_recv() { - Some(m) => { - result = Some(m); - } - None => { - // Remove this port. - let _ = ports.swap_remove(i); + unsafe { + let mut self_ports = transmute_mut(&self.ports); + let mut result = None; + // we have to swap the ports array so we aren't borrowing + // aliasable mutable memory. + let mut ports = ~[]; + ports <-> *self_ports; + while result.is_none() && ports.len() > 0 { + let i = wait_many(ports); + match ports[i].try_recv() { + Some(m) => { + result = Some(m); + } + None => { + // Remove this port. + let _ = ports.swap_remove(i); + } } } + ports <-> *self_ports; + result } - ports <-> self.ports; - result } fn recv(&self) -> T { self.try_recv().expect("port_set: endpoints closed") @@ -268,10 +295,9 @@ impl<T: Owned> Peekable<T> for PortSet<T> { // It'd be nice to use self.port.each, but that version isn't // pure. for uint::range(0, vec::uniq_len(&const self.ports)) |i| { - // XXX: Botch pending demuting. - unsafe { - let port: &Port<T> = cast::transmute(&mut self.ports[i]); - if port.peek() { return true } + let port: &Port<T> = &self.ports[i]; + if port.peek() { + return true; } } false @@ -327,23 +353,20 @@ impl<T: Owned> ::clone::Clone for SharedChan<T> { #[allow(non_camel_case_types)] pub mod oneshot { priv use core::kinds::Owned; - use ptr::to_unsafe_ptr; + use ptr::to_mut_unsafe_ptr; pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) { pub use core::pipes::HasBuffer; - let buffer = - ~::core::pipes::Buffer{ + let mut buffer = ~::core::pipes::Buffer { header: ::core::pipes::BufferHeader(), - data: __Buffer{ + data: __Buffer { Oneshot: ::core::pipes::mk_packet::<Oneshot<T>>() }, }; do ::core::pipes::entangle_buffer(buffer) |buffer, data| { - { - data.Oneshot.set_buffer(buffer); - to_unsafe_ptr(&data.Oneshot) - } + data.Oneshot.set_buffer(buffer); + to_mut_unsafe_ptr(&mut data.Oneshot) } } #[allow(non_camel_case_types)] @@ -497,48 +520,66 @@ pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool { /// Returns the index of an endpoint that is ready to receive. -pub fn selecti<T: Selectable>(endpoints: &[T]) -> uint { +pub fn selecti<T: Selectable>(endpoints: &mut [T]) -> uint { wait_many(endpoints) } /// Returns 0 or 1 depending on which endpoint is ready to receive -pub fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) -> - Either<(), ()> { - match wait_many([a.header(), b.header()]) { - 0 => Left(()), - 1 => Right(()), - _ => fail!(~"wait returned unexpected index") +pub fn select2i<A:Selectable, B:Selectable>(a: &mut A, b: &mut B) + -> Either<(), ()> { + let mut endpoints = [ a.header(), b.header() ]; + match wait_many(endpoints) { + 0 => Left(()), + 1 => Right(()), + _ => fail!(~"wait returned unexpected index"), } } /// Receive a message from one of two endpoints. pub trait Select2<T: Owned, U: Owned> { /// Receive a message or return `None` if a connection closes. - fn try_select(&self) -> Either<Option<T>, Option<U>>; + fn try_select(&mut self) -> Either<Option<T>, Option<U>>; /// Receive a message or fail if a connection closes. - fn select(&self) -> Either<T, U>; + fn select(&mut self) -> Either<T, U>; } -impl<T: Owned, U: Owned, - Left: Selectable + GenericPort<T>, - Right: Selectable + GenericPort<U>> - Select2<T, U> for (Left, Right) { - - fn select(&self) -> Either<T, U> { - match *self { - (ref lp, ref rp) => match select2i(lp, rp) { - Left(()) => Left (lp.recv()), - Right(()) => Right(rp.recv()) - } +impl<T:Owned, + U:Owned, + Left:Selectable + GenericPort<T>, + Right:Selectable + GenericPort<U>> + Select2<T, U> + for (Left, Right) { + fn select(&mut self) -> Either<T, U> { + // XXX: Bad borrow check workaround. + unsafe { + let this: &(Left, Right) = transmute(self); + match *this { + (ref lp, ref rp) => { + let lp: &mut Left = transmute(lp); + let rp: &mut Right = transmute(rp); + match select2i(lp, rp) { + Left(()) => Left(lp.recv()), + Right(()) => Right(rp.recv()), + } + } + } } } - fn try_select(&self) -> Either<Option<T>, Option<U>> { - match *self { - (ref lp, ref rp) => match select2i(lp, rp) { - Left(()) => Left (lp.try_recv()), - Right(()) => Right(rp.try_recv()) - } + fn try_select(&mut self) -> Either<Option<T>, Option<U>> { + // XXX: Bad borrow check workaround. + unsafe { + let this: &(Left, Right) = transmute(self); + match *this { + (ref lp, ref rp) => { + let lp: &mut Left = transmute(lp); + let rp: &mut Right = transmute(rp); + match select2i(lp, rp) { + Left(()) => Left (lp.try_recv()), + Right(()) => Right(rp.try_recv()), + } + } + } } } } @@ -555,9 +596,10 @@ mod test { c1.send(~"abc"); - match (p1, p2).select() { - Right(_) => fail!(), - _ => () + let mut tuple = (p1, p2); + match tuple.select() { + Right(_) => fail!(), + _ => (), } c2.send(123); diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 15b0be7b4bc..3ab81fd7161 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -179,9 +179,9 @@ pub mod managed; /* Core language traits */ -#[cfg(notest)] pub mod kinds; -#[cfg(notest)] pub mod ops; -#[cfg(notest)] pub mod cmp; +#[cfg(not(test))] pub mod kinds; +#[cfg(not(test))] pub mod ops; +#[cfg(not(test))] pub mod cmp; /* Common traits */ diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 33b7e81ee85..957e848b5e7 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -44,7 +44,7 @@ pub fn lefts<T:Copy,U>(eithers: &[Either<T, U>]) -> ~[T] { //! Extracts from a vector of either all the left values do vec::build_sized(eithers.len()) |push| { - for vec::each(eithers) |elt| { + for eithers.each |elt| { match *elt { Left(ref l) => { push(*l); } _ => { /* fallthrough */ } @@ -57,7 +57,7 @@ pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] { //! Extracts from a vector of either all the right values do vec::build_sized(eithers.len()) |push| { - for vec::each(eithers) |elt| { + for eithers.each |elt| { match *elt { Right(ref r) => { push(*r); } _ => { /* fallthrough */ } diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index ba10f97e626..29d0eb422d5 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -84,10 +84,11 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] { #[test] #[allow(non_implicitly_copyable_typarams)] fn test_flate_round_trip() { - let r = rand::rng(); + let mut r = rand::rng(); let mut words = ~[]; for 20.times { - words.push(r.gen_bytes(r.gen_uint_range(1, 10))); + let range = r.gen_uint_range(1, 10); + words.push(r.gen_bytes(range)); } for 20.times { let mut in = ~[]; diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs index ba1f8cebdb0..75b3b6bb566 100644 --- a/src/libcore/hash.rs +++ b/src/libcore/hash.rs @@ -19,11 +19,14 @@ * CPRNG like rand::rng. */ -use io; -use io::Writer; +#[cfg(stage0)] +use cast; +use rt::io::Writer; use to_bytes::IterBytes; use uint; -use vec; + +// Alias `SipState` to `State`. +pub use State = hash::SipState; /** * Types that can meaningfully be hashed should implement this. @@ -65,20 +68,32 @@ impl<A:Hash> HashUtil for A { /// Streaming hash-functions should implement this. pub trait Streaming { - fn input(&self, (&const [u8])); + fn input(&mut self, &[u8]); // These can be refactored some when we have default methods. - fn result_bytes(&self) -> ~[u8]; - fn result_str(&self) -> ~str; - fn result_u64(&self) -> u64; - fn reset(&self); + fn result_bytes(&mut self) -> ~[u8]; + fn result_str(&mut self) -> ~str; + fn result_u64(&mut self) -> u64; + fn reset(&mut self); +} + +// XXX: Ugly workaround for bootstrapping. +#[cfg(stage0)] +fn transmute_for_stage0<'a>(bytes: &'a [const u8]) -> &'a [u8] { + unsafe { + cast::transmute(bytes) + } +} +#[cfg(not(stage0))] +fn transmute_for_stage0<'a>(bytes: &'a [u8]) -> &'a [u8] { + bytes } impl<A:IterBytes> Hash for A { #[inline(always)] fn hash_keyed(&self, k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); + let mut s = State::new(k0, k1); for self.iter_bytes(true) |bytes| { - s.input(bytes); + s.input(transmute_for_stage0(bytes)); } s.result_u64() } @@ -86,32 +101,56 @@ impl<A:IterBytes> Hash for A { fn hash_keyed_2<A: IterBytes, B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } fn hash_keyed_3<A: IterBytes, B: IterBytes, C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } - for c.iter_bytes(true) |bytes| { s.input(bytes); } + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for c.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } fn hash_keyed_4<A: IterBytes, B: IterBytes, C: IterBytes, - D: IterBytes>(a: &A, b: &B, c: &C, d: &D, k0: u64, k1: u64) - -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } - for c.iter_bytes(true) |bytes| { s.input(bytes); } - for d.iter_bytes(true) |bytes| { s.input(bytes); } + D: IterBytes>( + a: &A, + b: &B, + c: &C, + d: &D, + k0: u64, + k1: u64) + -> u64 { + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for c.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for d.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } @@ -119,58 +158,68 @@ fn hash_keyed_5<A: IterBytes, B: IterBytes, C: IterBytes, D: IterBytes, - E: IterBytes>(a: &A, b: &B, c: &C, d: &D, e: &E, - k0: u64, k1: u64) -> u64 { - let s = &State(k0, k1); - for a.iter_bytes(true) |bytes| { s.input(bytes); } - for b.iter_bytes(true) |bytes| { s.input(bytes); } - for c.iter_bytes(true) |bytes| { s.input(bytes); } - for d.iter_bytes(true) |bytes| { s.input(bytes); } - for e.iter_bytes(true) |bytes| { s.input(bytes); } + E: IterBytes>( + a: &A, + b: &B, + c: &C, + d: &D, + e: &E, + k0: u64, + k1: u64) + -> u64 { + let mut s = State::new(k0, k1); + for a.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for b.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for c.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for d.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } + for e.iter_bytes(true) |bytes| { + s.input(transmute_for_stage0(bytes)); + } s.result_u64() } -// Implement State as SipState - -pub type State = SipState; - -#[inline(always)] -pub fn State(k0: u64, k1: u64) -> State { - SipState(k0, k1) -} - #[inline(always)] pub fn default_state() -> State { - State(0,0) + State::new(0, 0) } struct SipState { k0: u64, k1: u64, - mut length: uint, // how many bytes we've processed - mut v0: u64, // hash state - mut v1: u64, - mut v2: u64, - mut v3: u64, - mut tail: [u8, ..8], // unprocessed bytes - mut ntail: uint, // how many bytes in tail are valid + length: uint, // how many bytes we've processed + v0: u64, // hash state + v1: u64, + v2: u64, + v3: u64, + tail: [u8, ..8], // unprocessed bytes + ntail: uint, // how many bytes in tail are valid } -#[inline(always)] -fn SipState(key0: u64, key1: u64) -> SipState { - let state = SipState { - k0 : key0, - k1 : key1, - mut length : 0u, - mut v0 : 0u64, - mut v1 : 0u64, - mut v2 : 0u64, - mut v3 : 0u64, - mut tail : [0u8,0,0,0,0,0,0,0], - mut ntail : 0u, - }; - (&state).reset(); - state +impl SipState { + #[inline(always)] + fn new(key0: u64, key1: u64) -> SipState { + let mut state = SipState { + k0: key0, + k1: key1, + length: 0, + v0: 0, + v1: 0, + v2: 0, + v3: 0, + tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ], + ntail: 0, + }; + state.reset(); + state + } } // sadly, these macro definitions can't appear later, @@ -207,12 +256,10 @@ macro_rules! compress ( ) -impl io::Writer for SipState { - +impl Writer for SipState { // Methods for io::writer #[inline(always)] - fn write(&self, msg: &const [u8]) { - + fn write(&mut self, msg: &[u8]) { let length = msg.len(); self.length += length; @@ -272,29 +319,19 @@ impl io::Writer for SipState { self.ntail = left; } - fn seek(&self, _x: int, _s: io::SeekStyle) { - fail!(); - } - fn tell(&self) -> uint { - self.length - } - fn flush(&self) -> int { - 0 - } - fn get_type(&self) -> io::WriterType { - io::File + fn flush(&mut self) { + // No-op } } impl Streaming for SipState { - #[inline(always)] - fn input(&self, buf: &const [u8]) { + fn input(&mut self, buf: &[u8]) { self.write(buf); } #[inline(always)] - fn result_u64(&self) -> u64 { + fn result_u64(&mut self) -> u64 { let mut v0 = self.v0; let mut v1 = self.v1; let mut v2 = self.v2; @@ -324,7 +361,7 @@ impl Streaming for SipState { return (v0 ^ v1 ^ v2 ^ v3); } - fn result_bytes(&self) -> ~[u8] { + fn result_bytes(&mut self) -> ~[u8] { let h = self.result_u64(); ~[(h >> 0) as u8, (h >> 8) as u8, @@ -337,17 +374,17 @@ impl Streaming for SipState { ] } - fn result_str(&self) -> ~str { + fn result_str(&mut self) -> ~str { let r = self.result_bytes(); let mut s = ~""; - for vec::each(r) |b| { + for r.each |b| { s += uint::to_str_radix(*b as uint, 16u); } s } #[inline(always)] - fn reset(&self) { + fn reset(&mut self) { self.length = 0; self.v0 = self.k0 ^ 0x736f6d6570736575; self.v1 = self.k1 ^ 0x646f72616e646f6d; @@ -435,12 +472,12 @@ mod tests { let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64; let mut buf : ~[u8] = ~[]; let mut t = 0; - let stream_inc = &State(k0,k1); - let stream_full = &State(k0,k1); + let mut stream_inc = SipState::new(k0, k1); + let mut stream_full = SipState::new(k0, k1); - fn to_hex_str(r: &[u8, ..8]) -> ~str { + fn to_hex_str(r: &[u8, ..8]) -> ~str { let mut s = ~""; - for vec::each(*r) |b| { + for (*r).each |b| { s += uint::to_str_radix(*b as uint, 16u); } s @@ -529,4 +566,4 @@ mod tests { val & !(0xff << (byte * 8)) } } -} \ No newline at end of file +} diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index b764fccf64c..8e0a185248e 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -56,7 +56,7 @@ fn resize_at(capacity: uint) -> uint { pub fn linear_map_with_capacity<K:Eq + Hash,V>( initial_capacity: uint) -> HashMap<K, V> { - let r = rand::task_rng(); + let mut r = rand::task_rng(); linear_map_with_capacity_and_keys(r.gen(), r.gen(), initial_capacity) } diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 64b69a7928b..7fc2c2559c2 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -983,36 +983,50 @@ pub fn file_reader(path: &Path) -> Result<@Reader, ~str> { // Byte readers pub struct BytesReader<'self> { bytes: &'self [u8], - mut pos: uint + pos: @mut uint } impl<'self> Reader for BytesReader<'self> { fn read(&self, bytes: &mut [u8], len: uint) -> uint { - let count = uint::min(len, self.bytes.len() - self.pos); + let count = uint::min(len, self.bytes.len() - *self.pos); - let view = vec::slice(self.bytes, self.pos, self.bytes.len()); + let view = vec::slice(self.bytes, *self.pos, self.bytes.len()); vec::bytes::copy_memory(bytes, view, count); - self.pos += count; + *self.pos += count; count } + fn read_byte(&self) -> int { - if self.pos == self.bytes.len() { return -1; } - let b = self.bytes[self.pos]; - self.pos += 1u; - return b as int; + if *self.pos == self.bytes.len() { + return -1; + } + + let b = self.bytes[*self.pos]; + *self.pos += 1u; + b as int + } + + fn eof(&self) -> bool { + *self.pos == self.bytes.len() } - fn eof(&self) -> bool { self.pos == self.bytes.len() } + fn seek(&self, offset: int, whence: SeekStyle) { - let pos = self.pos; - self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence); + let pos = *self.pos; + *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence); + } + + fn tell(&self) -> uint { + *self.pos } - fn tell(&self) -> uint { self.pos } } -pub fn with_bytes_reader<t>(bytes: &[u8], f: &fn(@Reader) -> t) -> t { - f(@BytesReader { bytes: bytes, pos: 0u } as @Reader) +pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T { + f(@BytesReader { + bytes: bytes, + pos: @mut 0 + } as @Reader) } pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T { @@ -1186,7 +1200,7 @@ pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) fn wb() -> c_int { O_WRONLY as c_int } let mut fflags: c_int = wb(); - for vec::each(flags) |f| { + for flags.each |f| { match *f { Append => fflags |= O_APPEND as c_int, Create => fflags |= O_CREAT as c_int, @@ -1498,49 +1512,70 @@ pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> { pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) } pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) } -pub fn print(s: &str) { stdout().write_str(s); } -pub fn println(s: &str) { stdout().write_line(s); } +pub fn print(s: &str) { + stdout().write_str(s); +} + +pub fn println(s: &str) { + stdout().write_line(s); +} pub struct BytesWriter { - mut bytes: ~[u8], - mut pos: uint, + bytes: @mut ~[u8], + pos: @mut uint, } impl Writer for BytesWriter { fn write(&self, v: &[u8]) { let v_len = v.len(); - let bytes_len = vec::uniq_len(&const self.bytes); - let count = uint::max(bytes_len, self.pos + v_len); - vec::reserve(&mut self.bytes, count); + let bytes = &mut *self.bytes; + let count = uint::max(bytes.len(), *self.pos + v_len); + vec::reserve(bytes, count); unsafe { - vec::raw::set_len(&mut self.bytes, count); - let view = vec::mut_slice(self.bytes, self.pos, count); + // Silly stage0 borrow check workaround... + let casted: &mut ~[u8] = cast::transmute_copy(&bytes); + vec::raw::set_len(casted, count); + + let view = vec::mut_slice(*bytes, *self.pos, count); vec::bytes::copy_memory(view, v, v_len); } - self.pos += v_len; + *self.pos += v_len; } + fn seek(&self, offset: int, whence: SeekStyle) { - let pos = self.pos; - let len = vec::uniq_len(&const self.bytes); - self.pos = seek_in_buf(offset, pos, len, whence); + let pos = *self.pos; + let len = vec::uniq_len(&const *self.bytes); + *self.pos = seek_in_buf(offset, pos, len, whence); + } + + fn tell(&self) -> uint { + *self.pos + } + + fn flush(&self) -> int { + 0 + } + + fn get_type(&self) -> WriterType { + File } - fn tell(&self) -> uint { self.pos } - fn flush(&self) -> int { 0 } - fn get_type(&self) -> WriterType { File } } pub fn BytesWriter() -> BytesWriter { - BytesWriter { bytes: ~[], mut pos: 0u } + BytesWriter { + bytes: @mut ~[], + pos: @mut 0 + } } pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] { let wr = @BytesWriter(); f(wr as @Writer); - let @BytesWriter{bytes, _} = wr; - return bytes; + let @BytesWriter { bytes, _ } = wr; + copy *bytes } pub fn with_str_writer(f: &fn(@Writer)) -> ~str { @@ -1550,7 +1585,9 @@ pub fn with_str_writer(f: &fn(@Writer)) -> ~str { v.push(0); assert!(str::is_utf8(v)); - unsafe { ::cast::transmute(v) } + unsafe { + ::cast::transmute(v) + } } // Utility functions @@ -1849,15 +1886,15 @@ mod tests { fn bytes_buffer_overwrite() { let wr = BytesWriter(); wr.write(~[0u8, 1u8, 2u8, 3u8]); - assert!(wr.bytes == ~[0u8, 1u8, 2u8, 3u8]); + assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]); wr.seek(-2, SeekCur); wr.write(~[4u8, 5u8, 6u8, 7u8]); - assert!(wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]); + assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]); wr.seek(-2, SeekEnd); wr.write(~[8u8]); wr.seek(1, SeekSet); wr.write(~[9u8]); - assert!(wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]); + assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]); } #[test] diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 8fc2db6d6f1..b68d1158334 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -17,8 +17,7 @@ breaking out of iteration. The adaptors in the module work with any such iterato tied to specific traits. For example: ~~~~ -use core::iter::iter_to_vec; -println(iter_to_vec(|f| uint::range(0, 20, f)).to_str()); +println(iter::to_vec(|f| uint::range(0, 20, f)).to_str()); ~~~~ An external iterator object implementing the interface in the `iterator` module can be used as an @@ -55,12 +54,12 @@ pub trait Times { * * ~~~ * let xs = ~[1, 2, 3]; - * let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) }; + * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) }; * assert_eq!(xs, ys); * ~~~ */ #[inline(always)] -pub fn iter_to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] { +pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] { let mut v = ~[]; for iter |x| { v.push(x) } v @@ -185,9 +184,9 @@ mod tests { use prelude::*; #[test] - fn test_iter_to_vec() { + fn test_to_vec() { let xs = ~[1, 2, 3]; - let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) }; + let ys = do to_vec |f| { xs.each(|x| f(*x)) }; assert_eq!(xs, ys); } diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 5e95485b273..29dd4538aa2 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -378,7 +378,7 @@ mod tests { #[test] fn test_counter_to_vec() { let mut it = Counter::new(0, 5).take(10); - let xs = iter::iter_to_vec(|f| it.advance(f)); + let xs = iter::to_vec(|f| it.advance(f)); assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); } diff --git a/src/libcore/logging.rs b/src/libcore/logging.rs index afe8338f2ce..69ecad56a8f 100644 --- a/src/libcore/logging.rs +++ b/src/libcore/logging.rs @@ -42,7 +42,7 @@ pub fn console_off() { } } -#[cfg(notest)] +#[cfg(not(test))] #[lang="log_type"] pub fn log_type<T>(level: u32, object: &T) { use cast::transmute; diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs index debca1ead82..d2bb88ca302 100644 --- a/src/libcore/managed.rs +++ b/src/libcore/managed.rs @@ -12,7 +12,7 @@ use ptr::to_unsafe_ptr; -#[cfg(notest)] use cmp::{Eq, Ord}; +#[cfg(not(test))] use cmp::{Eq, Ord}; pub mod raw { use intrinsic::TyDesc; @@ -49,7 +49,7 @@ pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool { a_ptr == b_ptr } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Eq> Eq for @T { #[inline(always)] fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) } @@ -57,7 +57,7 @@ impl<T:Eq> Eq for @T { fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Eq> Eq for @mut T { #[inline(always)] fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) } @@ -65,7 +65,7 @@ impl<T:Eq> Eq for @mut T { fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Ord> Ord for @T { #[inline(always)] fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) } @@ -77,7 +77,7 @@ impl<T:Ord> Ord for @T { fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Ord> Ord for @mut T { #[inline(always)] fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) } diff --git a/src/libcore/nil.rs b/src/libcore/nil.rs index 6b8c390fc25..833bd3459ce 100644 --- a/src/libcore/nil.rs +++ b/src/libcore/nil.rs @@ -14,10 +14,10 @@ Functions for the unit type. */ -#[cfg(notest)] +#[cfg(not(test))] use prelude::*; -#[cfg(notest)] +#[cfg(not(test))] impl Eq for () { #[inline(always)] fn eq(&self, _other: &()) -> bool { true } @@ -25,7 +25,7 @@ impl Eq for () { fn ne(&self, _other: &()) -> bool { false } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for () { #[inline(always)] fn lt(&self, _other: &()) -> bool { false } @@ -37,13 +37,13 @@ impl Ord for () { fn gt(&self, _other: &()) -> bool { false } } -#[cfg(notest)] +#[cfg(not(test))] impl TotalOrd for () { #[inline(always)] fn cmp(&self, _other: &()) -> Ordering { Equal } } -#[cfg(notest)] +#[cfg(not(test))] impl TotalEq for () { #[inline(always)] fn equals(&self, _other: &()) -> bool { true } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 3c4faa95dd1..93e881c50e8 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -198,7 +198,7 @@ pub mod consts { impl Num for f32 {} -#[cfg(notest)] +#[cfg(not(test))] impl Eq for f32 { #[inline(always)] fn eq(&self, other: &f32) -> bool { (*self) == (*other) } @@ -206,7 +206,7 @@ impl Eq for f32 { fn ne(&self, other: &f32) -> bool { (*self) != (*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl ApproxEq<f32> for f32 { #[inline(always)] fn approx_epsilon() -> f32 { 1.0e-6 } @@ -222,7 +222,7 @@ impl ApproxEq<f32> for f32 { } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for f32 { #[inline(always)] fn lt(&self, other: &f32) -> bool { (*self) < (*other) } @@ -272,37 +272,37 @@ impl One for f32 { fn one() -> f32 { 1.0 } } -#[cfg(notest)] +#[cfg(not(test))] impl Add<f32,f32> for f32 { #[inline(always)] fn add(&self, other: &f32) -> f32 { *self + *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Sub<f32,f32> for f32 { #[inline(always)] fn sub(&self, other: &f32) -> f32 { *self - *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Mul<f32,f32> for f32 { #[inline(always)] fn mul(&self, other: &f32) -> f32 { *self * *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Div<f32,f32> for f32 { #[inline(always)] fn div(&self, other: &f32) -> f32 { *self / *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Rem<f32,f32> for f32 { #[inline(always)] fn rem(&self, other: &f32) -> f32 { *self % *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Neg<f32> for f32 { #[inline(always)] fn neg(&self) -> f32 { -*self } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 30c101fe8a9..096206d7183 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -221,7 +221,7 @@ pub mod consts { impl Num for f64 {} -#[cfg(notest)] +#[cfg(not(test))] impl Eq for f64 { #[inline(always)] fn eq(&self, other: &f64) -> bool { (*self) == (*other) } @@ -229,7 +229,7 @@ impl Eq for f64 { fn ne(&self, other: &f64) -> bool { (*self) != (*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl ApproxEq<f64> for f64 { #[inline(always)] fn approx_epsilon() -> f64 { 1.0e-6 } @@ -245,7 +245,7 @@ impl ApproxEq<f64> for f64 { } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for f64 { #[inline(always)] fn lt(&self, other: &f64) -> bool { (*self) < (*other) } @@ -295,28 +295,28 @@ impl One for f64 { fn one() -> f64 { 1.0 } } -#[cfg(notest)] +#[cfg(not(test))] impl Add<f64,f64> for f64 { fn add(&self, other: &f64) -> f64 { *self + *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Sub<f64,f64> for f64 { fn sub(&self, other: &f64) -> f64 { *self - *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Mul<f64,f64> for f64 { fn mul(&self, other: &f64) -> f64 { *self * *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Div<f64,f64> for f64 { fn div(&self, other: &f64) -> f64 { *self / *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Rem<f64,f64> for f64 { #[inline(always)] fn rem(&self, other: &f64) -> f64 { *self % *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Neg<f64> for f64 { fn neg(&self) -> f64 { -*self } } diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index 9c3d30be0d4..e6a2ed7ea97 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -363,7 +363,7 @@ pub fn tan(x: float) -> float { impl Num for float {} -#[cfg(notest)] +#[cfg(not(test))] impl Eq for float { #[inline(always)] fn eq(&self, other: &float) -> bool { (*self) == (*other) } @@ -371,7 +371,7 @@ impl Eq for float { fn ne(&self, other: &float) -> bool { (*self) != (*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl ApproxEq<float> for float { #[inline(always)] fn approx_epsilon() -> float { 1.0e-6 } @@ -387,7 +387,7 @@ impl ApproxEq<float> for float { } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for float { #[inline(always)] fn lt(&self, other: &float) -> bool { (*self) < (*other) } @@ -695,36 +695,36 @@ impl RealExt for float { fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float } } -#[cfg(notest)] +#[cfg(not(test))] impl Add<float,float> for float { #[inline(always)] fn add(&self, other: &float) -> float { *self + *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Sub<float,float> for float { #[inline(always)] fn sub(&self, other: &float) -> float { *self - *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Mul<float,float> for float { #[inline(always)] fn mul(&self, other: &float) -> float { *self * *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Div<float,float> for float { #[inline(always)] fn div(&self, other: &float) -> float { *self / *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Rem<float,float> for float { #[inline(always)] fn rem(&self, other: &float) -> float { *self % *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Neg<float> for float { #[inline(always)] fn neg(&self) -> float { -*self } diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 06a9a0b4562..9ee5ba4753d 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -131,7 +131,7 @@ pub fn abs(i: T) -> T { i.abs() } impl Num for T {} -#[cfg(notest)] +#[cfg(not(test))] impl Ord for T { #[inline(always)] fn lt(&self, other: &T) -> bool { return (*self) < (*other); } @@ -143,7 +143,7 @@ impl Ord for T { fn gt(&self, other: &T) -> bool { return (*self) > (*other); } } -#[cfg(notest)] +#[cfg(not(test))] impl Eq for T { #[inline(always)] fn eq(&self, other: &T) -> bool { return (*self) == (*other); } @@ -182,25 +182,25 @@ impl One for T { fn one() -> T { 1 } } -#[cfg(notest)] +#[cfg(not(test))] impl Add<T,T> for T { #[inline(always)] fn add(&self, other: &T) -> T { *self + *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Sub<T,T> for T { #[inline(always)] fn sub(&self, other: &T) -> T { *self - *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Mul<T,T> for T { #[inline(always)] fn mul(&self, other: &T) -> T { *self * *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Div<T,T> for T { /// /// Integer division, truncated towards 0. As this behaviour reflects the underlying @@ -224,7 +224,7 @@ impl Div<T,T> for T { fn div(&self, other: &T) -> T { *self / *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Rem<T,T> for T { /// /// Returns the integer remainder after division, satisfying: @@ -251,7 +251,7 @@ impl Rem<T,T> for T { fn rem(&self, other: &T) -> T { *self % *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Neg<T> for T { #[inline(always)] fn neg(&self) -> T { -*self } @@ -417,37 +417,37 @@ impl Integer for T { impl Bitwise for T {} -#[cfg(notest)] +#[cfg(not(test))] impl BitOr<T,T> for T { #[inline(always)] fn bitor(&self, other: &T) -> T { *self | *other } } -#[cfg(notest)] +#[cfg(not(test))] impl BitAnd<T,T> for T { #[inline(always)] fn bitand(&self, other: &T) -> T { *self & *other } } -#[cfg(notest)] +#[cfg(not(test))] impl BitXor<T,T> for T { #[inline(always)] fn bitxor(&self, other: &T) -> T { *self ^ *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Shl<T,T> for T { #[inline(always)] fn shl(&self, other: &T) -> T { *self << *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Shr<T,T> for T { #[inline(always)] fn shr(&self, other: &T) -> T { *self >> *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Not<T> for T { #[inline(always)] fn not(&self) -> T { !*self } diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index 6d0f1fe1fc7..dcb0865cb9b 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -96,7 +96,7 @@ pub fn compl(i: T) -> T { impl Num for T {} -#[cfg(notest)] +#[cfg(not(test))] impl Ord for T { #[inline(always)] fn lt(&self, other: &T) -> bool { (*self) < (*other) } @@ -108,7 +108,7 @@ impl Ord for T { fn gt(&self, other: &T) -> bool { (*self) > (*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl Eq for T { #[inline(always)] fn eq(&self, other: &T) -> bool { return (*self) == (*other); } @@ -147,37 +147,37 @@ impl One for T { fn one() -> T { 1 } } -#[cfg(notest)] +#[cfg(not(test))] impl Add<T,T> for T { #[inline(always)] fn add(&self, other: &T) -> T { *self + *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Sub<T,T> for T { #[inline(always)] fn sub(&self, other: &T) -> T { *self - *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Mul<T,T> for T { #[inline(always)] fn mul(&self, other: &T) -> T { *self * *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Div<T,T> for T { #[inline(always)] fn div(&self, other: &T) -> T { *self / *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Rem<T,T> for T { #[inline(always)] fn rem(&self, other: &T) -> T { *self % *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Neg<T> for T { #[inline(always)] fn neg(&self) -> T { -*self } @@ -240,37 +240,37 @@ impl Integer for T { impl Bitwise for T {} -#[cfg(notest)] +#[cfg(not(test))] impl BitOr<T,T> for T { #[inline(always)] fn bitor(&self, other: &T) -> T { *self | *other } } -#[cfg(notest)] +#[cfg(not(test))] impl BitAnd<T,T> for T { #[inline(always)] fn bitand(&self, other: &T) -> T { *self & *other } } -#[cfg(notest)] +#[cfg(not(test))] impl BitXor<T,T> for T { #[inline(always)] fn bitxor(&self, other: &T) -> T { *self ^ *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Shl<T,T> for T { #[inline(always)] fn shl(&self, other: &T) -> T { *self << *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Shr<T,T> for T { #[inline(always)] fn shr(&self, other: &T) -> T { *self >> *other } } -#[cfg(notest)] +#[cfg(not(test))] impl Not<T> for T { #[inline(always)] fn not(&self) -> T { !*self } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 42c77a687e5..574618026d9 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -352,7 +352,10 @@ pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int { } } -pub struct Pipe { in: c_int, out: c_int } +pub struct Pipe { + in: c_int, + out: c_int +} #[cfg(unix)] pub fn pipe() -> Pipe { @@ -1432,7 +1435,7 @@ mod tests { } fn make_rand_name() -> ~str { - let rng = rand::rng(); + let mut rng = rand::rng(); let n = ~"TEST" + rng.gen_str(10u); assert!(getenv(n).is_none()); n @@ -1488,7 +1491,7 @@ mod tests { fn test_env_getenv() { let e = env(); assert!(vec::len(e) > 0u); - for vec::each(e) |p| { + for e.each |p| { let (n, v) = copy *p; debug!(copy n); let v2 = getenv(n); @@ -1580,7 +1583,7 @@ mod tests { // Just assuming that we've got some contents in the current directory assert!((vec::len(dirs) > 0u)); - for vec::each(dirs) |dir| { + for dirs.each |dir| { debug!(copy *dir); } } diff --git a/src/libcore/owned.rs b/src/libcore/owned.rs index 599591e2f6d..3262fb4afdc 100644 --- a/src/libcore/owned.rs +++ b/src/libcore/owned.rs @@ -10,9 +10,9 @@ //! Operations on unique pointer types -#[cfg(notest)] use cmp::{Eq, Ord}; +#[cfg(not(test))] use cmp::{Eq, Ord}; -#[cfg(notest)] +#[cfg(not(test))] impl<T:Eq> Eq for ~T { #[inline(always)] fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) } @@ -20,7 +20,7 @@ impl<T:Eq> Eq for ~T { fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Ord> Ord for ~T { #[inline(always)] fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) } diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 19674900f90..8301254fbdd 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -111,7 +111,7 @@ enum State { pub struct BufferHeader { // Tracks whether this buffer needs to be freed. We can probably // get away with restricting it to 0 or 1, if we're careful. - mut ref_count: int, + ref_count: int, // We may want a drop, and to be careful about stringing this // thing along. @@ -130,12 +130,12 @@ pub struct Buffer<T> { } pub struct PacketHeader { - mut state: State, - mut blocked_task: *rust_task, + state: State, + blocked_task: *rust_task, // This is a transmute_copy of a ~buffer, that can also be cast // to a buffer_header if need be. - mut buffer: *libc::c_void, + buffer: *libc::c_void, } pub fn PacketHeader() -> PacketHeader { @@ -148,14 +148,14 @@ pub fn PacketHeader() -> PacketHeader { pub impl PacketHeader { // Returns the old state. - unsafe fn mark_blocked(&self, this: *rust_task) -> State { + unsafe fn mark_blocked(&mut self, this: *rust_task) -> State { rustrt::rust_task_ref(this); let old_task = swap_task(&mut self.blocked_task, this); assert!(old_task.is_null()); swap_state_acq(&mut self.state, Blocked) } - unsafe fn unblock(&self) { + unsafe fn unblock(&mut self) { let old_task = swap_task(&mut self.blocked_task, ptr::null()); if !old_task.is_null() { rustrt::rust_task_deref(old_task) @@ -169,13 +169,13 @@ pub impl PacketHeader { // unsafe because this can do weird things to the space/time // continuum. It ends making multiple unique pointers to the same - // thing. You'll proobably want to forget them when you're done. - unsafe fn buf_header(&self) -> ~BufferHeader { + // thing. You'll probably want to forget them when you're done. + unsafe fn buf_header(&mut self) -> ~BufferHeader { assert!(self.buffer.is_not_null()); transmute_copy(&self.buffer) } - fn set_buffer<T:Owned>(&self, b: ~Buffer<T>) { + fn set_buffer<T:Owned>(&mut self, b: ~Buffer<T>) { unsafe { self.buffer = transmute_copy(&b); } @@ -184,15 +184,15 @@ pub impl PacketHeader { pub struct Packet<T> { header: PacketHeader, - mut payload: Option<T>, + payload: Option<T>, } pub trait HasBuffer { - fn set_buffer(&self, b: *libc::c_void); + fn set_buffer(&mut self, b: *libc::c_void); } impl<T:Owned> HasBuffer for Packet<T> { - fn set_buffer(&self, b: *libc::c_void) { + fn set_buffer(&mut self, b: *libc::c_void) { self.header.buffer = b; } } @@ -204,7 +204,7 @@ pub fn mk_packet<T:Owned>() -> Packet<T> { } } fn unibuffer<T>() -> ~Buffer<Packet<T>> { - let b = ~Buffer { + let mut b = ~Buffer { header: BufferHeader(), data: Packet { header: PacketHeader(), @@ -218,22 +218,25 @@ fn unibuffer<T>() -> ~Buffer<Packet<T>> { b } -pub fn packet<T>() -> *Packet<T> { - let b = unibuffer(); - let p = ptr::to_unsafe_ptr(&(b.data)); +pub fn packet<T>() -> *mut Packet<T> { + let mut b = unibuffer(); + let p = ptr::to_mut_unsafe_ptr(&mut b.data); // We'll take over memory management from here. - unsafe { forget(b) } + unsafe { + forget(b); + } p } pub fn entangle_buffer<T:Owned,Tstart:Owned>( - buffer: ~Buffer<T>, - init: &fn(*libc::c_void, x: &T) -> *Packet<Tstart>) - -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) -{ - let p = init(unsafe { transmute_copy(&buffer) }, &buffer.data); - unsafe { forget(buffer) } - (SendPacketBuffered(p), RecvPacketBuffered(p)) + mut buffer: ~Buffer<T>, + init: &fn(*libc::c_void, x: &mut T) -> *mut Packet<Tstart>) + -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) { + unsafe { + let p = init(transmute_copy(&buffer), &mut buffer.data); + forget(buffer); + (SendPacketBuffered(p), RecvPacketBuffered(p)) + } } pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task { @@ -292,7 +295,7 @@ fn swap_state_rel(dst: &mut State, src: State) -> State { } } -pub unsafe fn get_buffer<T>(p: *PacketHeader) -> ~Buffer<T> { +pub unsafe fn get_buffer<T>(p: *mut PacketHeader) -> ~Buffer<T> { transmute((*p).buf_header()) } @@ -306,10 +309,14 @@ struct BufferResource<T> { impl<T> Drop for BufferResource<T> { fn finalize(&self) { unsafe { - let b = move_it!(self.buffer); + let this: &mut BufferResource<T> = transmute(self); + + let mut b = move_it!(this.buffer); //let p = ptr::to_unsafe_ptr(*b); //error!("drop %?", p); - let old_count = intrinsics::atomic_xsub_rel(&mut b.header.ref_count, 1); + let old_count = intrinsics::atomic_xsub_rel( + &mut b.header.ref_count, + 1); //let old_count = atomic_xchng_rel(b.header.ref_count, 0); if old_count == 1 { // The new count is 0. @@ -323,10 +330,12 @@ impl<T> Drop for BufferResource<T> { } } -fn BufferResource<T>(b: ~Buffer<T>) -> BufferResource<T> { +fn BufferResource<T>(mut b: ~Buffer<T>) -> BufferResource<T> { //let p = ptr::to_unsafe_ptr(*b); //error!("take %?", p); - unsafe { intrinsics::atomic_xadd_acq(&mut b.header.ref_count, 1) }; + unsafe { + intrinsics::atomic_xadd_acq(&mut b.header.ref_count, 1); + } BufferResource { // tjc: ???? @@ -334,10 +343,12 @@ fn BufferResource<T>(b: ~Buffer<T>) -> BufferResource<T> { } } -pub fn send<T,Tbuffer>(p: SendPacketBuffered<T,Tbuffer>, payload: T) -> bool { +pub fn send<T,Tbuffer>(mut p: SendPacketBuffered<T,Tbuffer>, + payload: T) + -> bool { let header = p.header(); - let p_ = p.unwrap(); - let p = unsafe { &*p_ }; + let mut p_ = p.unwrap(); + let p = unsafe { &mut *p_ }; assert!(ptr::to_unsafe_ptr(&(p.header)) == header); assert!(p.payload.is_none()); p.payload = Some(payload); @@ -391,11 +402,12 @@ Returns `None` if the sender has closed the connection without sending a message, or `Some(T)` if a message was received. */ -pub fn try_recv<T:Owned,Tbuffer:Owned>(p: RecvPacketBuffered<T, Tbuffer>) - -> Option<T> -{ - let p_ = p.unwrap(); - let p = unsafe { &*p_ }; +pub fn try_recv<T:Owned,Tbuffer:Owned>(mut p: RecvPacketBuffered<T, Tbuffer>) + -> Option<T> { + let mut p_ = p.unwrap(); + let mut p = unsafe { + &mut *p_ + }; do (|| { try_recv_(p) @@ -412,7 +424,7 @@ pub fn try_recv<T:Owned,Tbuffer:Owned>(p: RecvPacketBuffered<T, Tbuffer>) } } -fn try_recv_<T:Owned>(p: &Packet<T>) -> Option<T> { +fn try_recv_<T:Owned>(p: &mut Packet<T>) -> Option<T> { // optimistic path match p.header.state { Full => { @@ -498,16 +510,20 @@ fn try_recv_<T:Owned>(p: &Packet<T>) -> Option<T> { } /// Returns true if messages are available. -pub fn peek<T:Owned,Tb:Owned>(p: &RecvPacketBuffered<T, Tb>) -> bool { - match unsafe {(*p.header()).state} { - Empty | Terminated => false, - Blocked => fail!(~"peeking on blocked packet"), - Full => true +pub fn peek<T:Owned,Tb:Owned>(p: &mut RecvPacketBuffered<T, Tb>) -> bool { + unsafe { + match (*p.header()).state { + Empty | Terminated => false, + Blocked => fail!(~"peeking on blocked packet"), + Full => true + } } } -fn sender_terminate<T:Owned>(p: *Packet<T>) { - let p = unsafe { &*p }; +fn sender_terminate<T:Owned>(p: *mut Packet<T>) { + let p = unsafe { + &mut *p + }; match swap_state_rel(&mut p.header.state, Terminated) { Empty => { // The receiver will eventually clean up. @@ -536,8 +552,10 @@ fn sender_terminate<T:Owned>(p: *Packet<T>) { } } -fn receiver_terminate<T:Owned>(p: *Packet<T>) { - let p = unsafe { &*p }; +fn receiver_terminate<T:Owned>(p: *mut Packet<T>) { + let p = unsafe { + &mut *p + }; match swap_state_rel(&mut p.header.state, Terminated) { Empty => { assert!(p.header.blocked_task.is_null()); @@ -569,8 +587,10 @@ that vector. The index points to an endpoint that has either been closed by the sender or has a message waiting to be received. */ -pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { - let this = unsafe { rustrt::rust_get_task() }; +pub fn wait_many<T: Selectable>(pkts: &mut [T]) -> uint { + let this = unsafe { + rustrt::rust_get_task() + }; unsafe { rustrt::task_clear_event_reject(this); @@ -578,19 +598,19 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { let mut data_avail = false; let mut ready_packet = pkts.len(); - for pkts.eachi |i, p| { + for vec::eachi_mut(pkts) |i, p| { unsafe { - let p = &*p.header(); + let p = &mut *p.header(); let old = p.mark_blocked(this); match old { - Full | Terminated => { - data_avail = true; - ready_packet = i; - (*p).state = old; - break; - } - Blocked => fail!(~"blocking on blocked packet"), - Empty => () + Full | Terminated => { + data_avail = true; + ready_packet = i; + (*p).state = old; + break; + } + Blocked => fail!(~"blocking on blocked packet"), + Empty => () } } } @@ -598,7 +618,14 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { while !data_avail { debug!("sleeping on %? packets", pkts.len()); let event = wait_event(this) as *PacketHeader; - let pos = vec::position(pkts, |p| p.header() == event); + + let mut pos = None; + for vec::eachi_mut(pkts) |i, p| { + if p.header() == event { + pos = Some(i); + break; + } + }; match pos { Some(i) => { @@ -609,11 +636,15 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint { } } - debug!("%?", pkts[ready_packet]); + debug!("%?", &mut pkts[ready_packet]); - for pkts.each |p| { unsafe{ (*p.header()).unblock()} } + for vec::each_mut(pkts) |p| { + unsafe { + (*p.header()).unblock() + } + } - debug!("%?, %?", ready_packet, pkts[ready_packet]); + debug!("%?, %?", ready_packet, &mut pkts[ready_packet]); unsafe { assert!((*pkts[ready_packet].header()).state == Full @@ -629,65 +660,58 @@ message. */ pub type SendPacket<T> = SendPacketBuffered<T, Packet<T>>; -pub fn SendPacket<T>(p: *Packet<T>) -> SendPacket<T> { +pub fn SendPacket<T>(p: *mut Packet<T>) -> SendPacket<T> { SendPacketBuffered(p) } pub struct SendPacketBuffered<T, Tbuffer> { - mut p: Option<*Packet<T>>, - mut buffer: Option<BufferResource<Tbuffer>>, + p: Option<*mut Packet<T>>, + buffer: Option<BufferResource<Tbuffer>>, } #[unsafe_destructor] impl<T:Owned,Tbuffer:Owned> Drop for SendPacketBuffered<T,Tbuffer> { fn finalize(&self) { - //if self.p != none { - // debug!("drop send %?", option::get(self.p)); - //} - if self.p != None { - let mut p = None; - p <-> self.p; - sender_terminate(p.unwrap()) + unsafe { + let this: &mut SendPacketBuffered<T,Tbuffer> = transmute(self); + if this.p != None { + let mut p = None; + p <-> this.p; + sender_terminate(p.unwrap()) + } } - //unsafe { error!("send_drop: %?", - // if self.buffer == none { - // "none" - // } else { "some" }); } } } -pub fn SendPacketBuffered<T,Tbuffer>(p: *Packet<T>) - -> SendPacketBuffered<T, Tbuffer> { - //debug!("take send %?", p); +pub fn SendPacketBuffered<T,Tbuffer>(p: *mut Packet<T>) + -> SendPacketBuffered<T,Tbuffer> { SendPacketBuffered { p: Some(p), buffer: unsafe { - Some(BufferResource( - get_buffer(ptr::to_unsafe_ptr(&((*p).header))))) + Some(BufferResource(get_buffer(&mut (*p).header))) } } } pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> { - fn unwrap(&self) -> *Packet<T> { + fn unwrap(&mut self) -> *mut Packet<T> { let mut p = None; p <-> self.p; p.unwrap() } - fn header(&self) -> *PacketHeader { + fn header(&mut self) -> *mut PacketHeader { match self.p { - Some(packet) => unsafe { - let packet = &*packet; - let header = ptr::to_unsafe_ptr(&(packet.header)); - //forget(packet); - header - }, - None => fail!(~"packet already consumed") + Some(packet) => unsafe { + let packet = &mut *packet; + let header = ptr::to_mut_unsafe_ptr(&mut packet.header); + header + }, + None => fail!(~"packet already consumed") } } - fn reuse_buffer(&self) -> BufferResource<Tbuffer> { + fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> { //error!("send reuse_buffer"); let mut tmp = None; tmp <-> self.buffer; @@ -699,41 +723,37 @@ pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> { /// message. pub type RecvPacket<T> = RecvPacketBuffered<T, Packet<T>>; -pub fn RecvPacket<T>(p: *Packet<T>) -> RecvPacket<T> { +pub fn RecvPacket<T>(p: *mut Packet<T>) -> RecvPacket<T> { RecvPacketBuffered(p) } + pub struct RecvPacketBuffered<T, Tbuffer> { - mut p: Option<*Packet<T>>, - mut buffer: Option<BufferResource<Tbuffer>>, + p: Option<*mut Packet<T>>, + buffer: Option<BufferResource<Tbuffer>>, } #[unsafe_destructor] impl<T:Owned,Tbuffer:Owned> Drop for RecvPacketBuffered<T,Tbuffer> { fn finalize(&self) { - //if self.p != none { - // debug!("drop recv %?", option::get(self.p)); - //} - if self.p != None { - let mut p = None; - p <-> self.p; - receiver_terminate(p.unwrap()) + unsafe { + let this: &mut RecvPacketBuffered<T,Tbuffer> = transmute(self); + if this.p != None { + let mut p = None; + p <-> this.p; + receiver_terminate(p.unwrap()) + } } - //unsafe { error!("recv_drop: %?", - // if self.buffer == none { - // "none" - // } else { "some" }); } } } pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> { - fn unwrap(&self) -> *Packet<T> { + fn unwrap(&mut self) -> *mut Packet<T> { let mut p = None; p <-> self.p; p.unwrap() } - fn reuse_buffer(&self) -> BufferResource<Tbuffer> { - //error!("recv reuse_buffer"); + fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> { let mut tmp = None; tmp <-> self.buffer; tmp.unwrap() @@ -741,27 +761,24 @@ pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> { } impl<T:Owned,Tbuffer:Owned> Selectable for RecvPacketBuffered<T, Tbuffer> { - fn header(&self) -> *PacketHeader { + fn header(&mut self) -> *mut PacketHeader { match self.p { - Some(packet) => unsafe { - let packet = &*packet; - let header = ptr::to_unsafe_ptr(&(packet.header)); - //forget(packet); - header - }, - None => fail!(~"packet already consumed") + Some(packet) => unsafe { + let packet = &mut *packet; + let header = ptr::to_mut_unsafe_ptr(&mut packet.header); + header + }, + None => fail!(~"packet already consumed") } } } -pub fn RecvPacketBuffered<T,Tbuffer>(p: *Packet<T>) - -> RecvPacketBuffered<T,Tbuffer> { - //debug!("take recv %?", p); +pub fn RecvPacketBuffered<T,Tbuffer>(p: *mut Packet<T>) + -> RecvPacketBuffered<T,Tbuffer> { RecvPacketBuffered { p: Some(p), buffer: unsafe { - Some(BufferResource( - get_buffer(ptr::to_unsafe_ptr(&((*p).header))))) + Some(BufferResource(get_buffer(&mut (*p).header))) } } } @@ -800,51 +817,55 @@ this case, `select2` may return either `left` or `right`. */ pub fn select2<A:Owned,Ab:Owned,B:Owned,Bb:Owned>( - a: RecvPacketBuffered<A, Ab>, - b: RecvPacketBuffered<B, Bb>) + mut a: RecvPacketBuffered<A, Ab>, + mut b: RecvPacketBuffered<B, Bb>) -> Either<(Option<A>, RecvPacketBuffered<B, Bb>), - (RecvPacketBuffered<A, Ab>, Option<B>)> -{ - let i = wait_many([a.header(), b.header()]); - + (RecvPacketBuffered<A, Ab>, Option<B>)> { + let mut endpoints = [ a.header(), b.header() ]; + let i = wait_many(endpoints); match i { - 0 => Left((try_recv(a), b)), - 1 => Right((a, try_recv(b))), - _ => fail!(~"select2 return an invalid packet") + 0 => Left((try_recv(a), b)), + 1 => Right((a, try_recv(b))), + _ => fail!(~"select2 return an invalid packet") } } pub trait Selectable { - fn header(&self) -> *PacketHeader; + fn header(&mut self) -> *mut PacketHeader; } -impl Selectable for *PacketHeader { - fn header(&self) -> *PacketHeader { *self } +impl Selectable for *mut PacketHeader { + fn header(&mut self) -> *mut PacketHeader { *self } } /// Returns the index of an endpoint that is ready to receive. -pub fn selecti<T:Selectable>(endpoints: &[T]) -> uint { +pub fn selecti<T:Selectable>(endpoints: &mut [T]) -> uint { wait_many(endpoints) } /// Returns 0 or 1 depending on which endpoint is ready to receive -pub fn select2i<A:Selectable,B:Selectable>(a: &A, b: &B) -> - Either<(), ()> { - match wait_many([a.header(), b.header()]) { - 0 => Left(()), - 1 => Right(()), - _ => fail!(~"wait returned unexpected index") +pub fn select2i<A:Selectable,B:Selectable>(a: &mut A, b: &mut B) + -> Either<(), ()> { + let mut endpoints = [ a.header(), b.header() ]; + match wait_many(endpoints) { + 0 => Left(()), + 1 => Right(()), + _ => fail!(~"wait returned unexpected index") } } -/** Waits on a set of endpoints. Returns a message, its index, and a - list of the remaining endpoints. +/// Waits on a set of endpoints. Returns a message, its index, and a +/// list of the remaining endpoints. +pub fn select<T:Owned,Tb:Owned>(mut endpoints: ~[RecvPacketBuffered<T, Tb>]) + -> (uint, + Option<T>, + ~[RecvPacketBuffered<T, Tb>]) { + let mut endpoint_headers = ~[]; + for vec::each_mut(endpoints) |endpoint| { + endpoint_headers.push(endpoint.header()); + } -*/ -pub fn select<T:Owned,Tb:Owned>(endpoints: ~[RecvPacketBuffered<T, Tb>]) - -> (uint, Option<T>, ~[RecvPacketBuffered<T, Tb>]) -{ - let ready = wait_many(endpoints.map(|p| p.header())); + let ready = wait_many(endpoint_headers); let mut remaining = endpoints; let port = remaining.swap_remove(ready); let result = try_recv(port); @@ -873,9 +894,10 @@ mod test { c1.send(~"abc"); - match (p1, p2).select() { - Right(_) => fail!(), - _ => () + let mut tuple = (p1, p2); + match tuple.select() { + Right(_) => fail!(), + _ => (), } c2.send(123); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 85e46a0feff..77e4143d090 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -15,7 +15,7 @@ use libc; use libc::{c_void, size_t}; use sys; -#[cfg(notest)] use cmp::{Eq, Ord}; +#[cfg(not(test))] use cmp::{Eq, Ord}; use uint; pub mod libc_ { @@ -243,7 +243,7 @@ impl<T> Ptr<T> for *mut T { } // Equality for pointers -#[cfg(notest)] +#[cfg(not(test))] impl<T> Eq for *const T { #[inline(always)] fn eq(&self, other: &*const T) -> bool { @@ -258,7 +258,7 @@ impl<T> Eq for *const T { } // Comparison for pointers -#[cfg(notest)] +#[cfg(not(test))] impl<T> Ord for *const T { #[inline(always)] fn lt(&self, other: &*const T) -> bool { @@ -295,7 +295,7 @@ impl<T> Ord for *const T { } // Equality for region pointers -#[cfg(notest)] +#[cfg(not(test))] impl<'self,T:Eq> Eq for &'self T { #[inline(always)] fn eq(&self, other: & &'self T) -> bool { @@ -308,7 +308,7 @@ impl<'self,T:Eq> Eq for &'self T { } // Comparison for region pointers -#[cfg(notest)] +#[cfg(not(test))] impl<'self,T:Ord> Ord for &'self T { #[inline(always)] fn lt(&self, other: & &'self T) -> bool { @@ -336,7 +336,10 @@ pub mod ptr_tests { #[test] fn test() { unsafe { - struct Pair {mut fst: int, mut snd: int}; + struct Pair { + fst: int, + snd: int + }; let mut p = Pair {fst: 10, snd: 20}; let pptr: *mut Pair = &mut p; let iptr: *mut int = cast::transmute(pptr); diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 80f69f067eb..f11840c95d5 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -55,12 +55,12 @@ pub mod distributions; /// A type that can be randomly generated using an Rng pub trait Rand { - fn rand<R: Rng>(rng: &R) -> Self; + fn rand<R: Rng>(rng: &mut R) -> Self; } impl Rand for int { #[inline] - fn rand<R: Rng>(rng: &R) -> int { + fn rand<R: Rng>(rng: &mut R) -> int { if int::bits == 32 { rng.next() as int } else { @@ -71,35 +71,35 @@ impl Rand for int { impl Rand for i8 { #[inline] - fn rand<R: Rng>(rng: &R) -> i8 { + fn rand<R: Rng>(rng: &mut R) -> i8 { rng.next() as i8 } } impl Rand for i16 { #[inline] - fn rand<R: Rng>(rng: &R) -> i16 { + fn rand<R: Rng>(rng: &mut R) -> i16 { rng.next() as i16 } } impl Rand for i32 { #[inline] - fn rand<R: Rng>(rng: &R) -> i32 { + fn rand<R: Rng>(rng: &mut R) -> i32 { rng.next() as i32 } } impl Rand for i64 { #[inline] - fn rand<R: Rng>(rng: &R) -> i64 { + fn rand<R: Rng>(rng: &mut R) -> i64 { (rng.next() as i64 << 32) | rng.next() as i64 } } impl Rand for uint { #[inline] - fn rand<R: Rng>(rng: &R) -> uint { + fn rand<R: Rng>(rng: &mut R) -> uint { if uint::bits == 32 { rng.next() as uint } else { @@ -110,42 +110,42 @@ impl Rand for uint { impl Rand for u8 { #[inline] - fn rand<R: Rng>(rng: &R) -> u8 { + fn rand<R: Rng>(rng: &mut R) -> u8 { rng.next() as u8 } } impl Rand for u16 { #[inline] - fn rand<R: Rng>(rng: &R) -> u16 { + fn rand<R: Rng>(rng: &mut R) -> u16 { rng.next() as u16 } } impl Rand for u32 { #[inline] - fn rand<R: Rng>(rng: &R) -> u32 { + fn rand<R: Rng>(rng: &mut R) -> u32 { rng.next() } } impl Rand for u64 { #[inline] - fn rand<R: Rng>(rng: &R) -> u64 { + fn rand<R: Rng>(rng: &mut R) -> u64 { (rng.next() as u64 << 32) | rng.next() as u64 } } impl Rand for float { #[inline] - fn rand<R: Rng>(rng: &R) -> float { + fn rand<R: Rng>(rng: &mut R) -> float { rng.gen::<f64>() as float } } impl Rand for f32 { #[inline] - fn rand<R: Rng>(rng: &R) -> f32 { + fn rand<R: Rng>(rng: &mut R) -> f32 { rng.gen::<f64>() as f32 } } @@ -153,7 +153,7 @@ impl Rand for f32 { static scale : f64 = (u32::max_value as f64) + 1.0f64; impl Rand for f64 { #[inline] - fn rand<R: Rng>(rng: &R) -> f64 { + fn rand<R: Rng>(rng: &mut R) -> f64 { let u1 = rng.next() as f64; let u2 = rng.next() as f64; let u3 = rng.next() as f64; @@ -164,14 +164,14 @@ impl Rand for f64 { impl Rand for char { #[inline] - fn rand<R: Rng>(rng: &R) -> char { + fn rand<R: Rng>(rng: &mut R) -> char { rng.next() as char } } impl Rand for bool { #[inline] - fn rand<R: Rng>(rng: &R) -> bool { + fn rand<R: Rng>(rng: &mut R) -> bool { rng.next() & 1u32 == 1u32 } } @@ -185,7 +185,7 @@ macro_rules! tuple_impl { > Rand for ( $( $tyvar ),* , ) { #[inline] - fn rand<R: Rng>(_rng: &R) -> ( $( $tyvar ),* , ) { + fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) { ( // use the $tyvar's to get the appropriate number of // repeats (they're not actually needed) @@ -201,7 +201,7 @@ macro_rules! tuple_impl { impl Rand for () { #[inline] - fn rand<R: Rng>(_: &R) -> () { () } + fn rand<R: Rng>(_: &mut R) -> () { () } } tuple_impl!{A} tuple_impl!{A, B} @@ -216,7 +216,7 @@ tuple_impl!{A, B, C, D, E, F, G, H, I, J} impl<T:Rand> Rand for Option<T> { #[inline] - fn rand<R: Rng>(rng: &R) -> Option<T> { + fn rand<R: Rng>(rng: &mut R) -> Option<T> { if rng.gen() { Some(rng.gen()) } else { @@ -227,12 +227,12 @@ impl<T:Rand> Rand for Option<T> { impl<T: Rand> Rand for ~T { #[inline] - fn rand<R: Rng>(rng: &R) -> ~T { ~rng.gen() } + fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() } } impl<T: Rand> Rand for @T { #[inline] - fn rand<R: Rng>(rng: &R) -> @T { @rng.gen() } + fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() } } #[abi = "cdecl"] @@ -248,7 +248,7 @@ pub mod rustrt { /// A random number generator pub trait Rng { /// Return the next random integer - pub fn next(&self) -> u32; + pub fn next(&mut self) -> u32; } /// A value with a particular weight compared to other values @@ -259,21 +259,21 @@ pub struct Weighted<T> { pub trait RngUtil { /// Return a random value of a Rand type - fn gen<T:Rand>(&self) -> T; + fn gen<T:Rand>(&mut self) -> T; /** * Return a int randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_int_range(&self, start: int, end: int) -> int; + fn gen_int_range(&mut self, start: int, end: int) -> int; /** * Return a uint randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_uint_range(&self, start: uint, end: uint) -> uint; + fn gen_uint_range(&mut self, start: uint, end: uint) -> uint; /** * Return a char randomly chosen from chars, failing if chars is empty */ - fn gen_char_from(&self, chars: &str) -> char; + fn gen_char_from(&mut self, chars: &str) -> char; /** * Return a bool with a 1 in n chance of true * @@ -289,7 +289,7 @@ pub trait RngUtil { * } * ~~~ */ - fn gen_weighted_bool(&self, n: uint) -> bool; + fn gen_weighted_bool(&mut self, n: uint) -> bool; /** * Return a random string of the specified length composed of A-Z,a-z,0-9 * @@ -305,7 +305,7 @@ pub trait RngUtil { * } * ~~~ */ - fn gen_str(&self, len: uint) -> ~str; + fn gen_str(&mut self, len: uint) -> ~str; /** * Return a random byte string of the specified length * @@ -321,7 +321,7 @@ pub trait RngUtil { * } * ~~~ */ - fn gen_bytes(&self, len: uint) -> ~[u8]; + fn gen_bytes(&mut self, len: uint) -> ~[u8]; /** * Choose an item randomly, failing if values is empty * @@ -337,9 +337,9 @@ pub trait RngUtil { * } * ~~~ */ - fn choose<T:Copy>(&self, values: &[T]) -> T; + fn choose<T:Copy>(&mut self, values: &[T]) -> T; /// Choose Some(item) randomly, returning None if values is empty - fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T>; + fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T>; /** * Choose an item respecting the relative weights, failing if the sum of * the weights is 0 @@ -359,7 +359,7 @@ pub trait RngUtil { * } * ~~~ */ - fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T; + fn choose_weighted<T:Copy>(&mut self, v : &[Weighted<T>]) -> T; /** * Choose Some(item) respecting the relative weights, returning none if * the sum of the weights is 0 @@ -379,7 +379,8 @@ pub trait RngUtil { * } * ~~~ */ - fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T>; + fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>]) + -> Option<T>; /** * Return a vec containing copies of the items, in order, where * the weight of the item determines how many copies there are @@ -399,7 +400,7 @@ pub trait RngUtil { * } * ~~~ */ - fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T]; + fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T]; /** * Shuffle a vec * @@ -415,7 +416,7 @@ pub trait RngUtil { * } * ~~~ */ - fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T]; + fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T]; /** * Shuffle a mutable vec in place * @@ -435,14 +436,14 @@ pub trait RngUtil { * } * ~~~ */ - fn shuffle_mut<T>(&self, values: &mut [T]); + fn shuffle_mut<T>(&mut self, values: &mut [T]); } /// Extension methods for random number generators impl<R: Rng> RngUtil for R { /// Return a random value for a Rand type #[inline(always)] - fn gen<T: Rand>(&self) -> T { + fn gen<T: Rand>(&mut self) -> T { Rand::rand(self) } @@ -450,7 +451,7 @@ impl<R: Rng> RngUtil for R { * Return an int randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_int_range(&self, start: int, end: int) -> int { + fn gen_int_range(&mut self, start: int, end: int) -> int { assert!(start < end); start + int::abs(self.gen::<int>() % (end - start)) } @@ -459,7 +460,7 @@ impl<R: Rng> RngUtil for R { * Return a uint randomly chosen from the range [start, end), * failing if start >= end */ - fn gen_uint_range(&self, start: uint, end: uint) -> uint { + fn gen_uint_range(&mut self, start: uint, end: uint) -> uint { assert!(start < end); start + (self.gen::<uint>() % (end - start)) } @@ -467,7 +468,7 @@ impl<R: Rng> RngUtil for R { /** * Return a char randomly chosen from chars, failing if chars is empty */ - fn gen_char_from(&self, chars: &str) -> char { + fn gen_char_from(&mut self, chars: &str) -> char { assert!(!chars.is_empty()); let mut cs = ~[]; for str::each_char(chars) |c| { cs.push(c) } @@ -475,7 +476,7 @@ impl<R: Rng> RngUtil for R { } /// Return a bool with a 1-in-n chance of true - fn gen_weighted_bool(&self, n: uint) -> bool { + fn gen_weighted_bool(&mut self, n: uint) -> bool { if n == 0u { true } else { @@ -486,7 +487,7 @@ impl<R: Rng> RngUtil for R { /** * Return a random string of the specified length composed of A-Z,a-z,0-9 */ - fn gen_str(&self, len: uint) -> ~str { + fn gen_str(&mut self, len: uint) -> ~str { let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz\ 0123456789"; @@ -500,19 +501,19 @@ impl<R: Rng> RngUtil for R { } /// Return a random byte string of the specified length - fn gen_bytes(&self, len: uint) -> ~[u8] { + fn gen_bytes(&mut self, len: uint) -> ~[u8] { do vec::from_fn(len) |_i| { self.gen() } } /// Choose an item randomly, failing if values is empty - fn choose<T:Copy>(&self, values: &[T]) -> T { + fn choose<T:Copy>(&mut self, values: &[T]) -> T { self.choose_option(values).get() } /// Choose Some(item) randomly, returning None if values is empty - fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T> { + fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T> { if values.is_empty() { None } else { @@ -523,7 +524,7 @@ impl<R: Rng> RngUtil for R { * Choose an item respecting the relative weights, failing if the sum of * the weights is 0 */ - fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T { + fn choose_weighted<T:Copy>(&mut self, v: &[Weighted<T>]) -> T { self.choose_weighted_option(v).get() } @@ -531,7 +532,8 @@ impl<R: Rng> RngUtil for R { * Choose Some(item) respecting the relative weights, returning none if * the sum of the weights is 0 */ - fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T> { + fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>]) + -> Option<T> { let mut total = 0u; for v.each |item| { total += item.weight; @@ -554,7 +556,7 @@ impl<R: Rng> RngUtil for R { * Return a vec containing copies of the items, in order, where * the weight of the item determines how many copies there are */ - fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T] { + fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T] { let mut r = ~[]; for v.each |item| { for uint::range(0u, item.weight) |_i| { @@ -565,14 +567,14 @@ impl<R: Rng> RngUtil for R { } /// Shuffle a vec - fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T] { + fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T] { let mut m = vec::from_slice(values); self.shuffle_mut(m); m } /// Shuffle a mutable vec in place - fn shuffle_mut<T>(&self, values: &mut [T]) { + fn shuffle_mut<T>(&mut self, values: &mut [T]) { let mut i = values.len(); while i >= 2u { // invariant: elements with index >= i have been locked in place. @@ -594,12 +596,12 @@ static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN; /// A random number generator that uses the [ISAAC /// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29). pub struct IsaacRng { - priv mut cnt: u32, - priv mut rsl: [u32, .. RAND_SIZE], - priv mut mem: [u32, .. RAND_SIZE], - priv mut a: u32, - priv mut b: u32, - priv mut c: u32 + priv cnt: u32, + priv rsl: [u32, .. RAND_SIZE], + priv mem: [u32, .. RAND_SIZE], + priv a: u32, + priv b: u32, + priv c: u32 } pub impl IsaacRng { @@ -647,7 +649,7 @@ pub impl IsaacRng { /// Initialises `self`. If `use_rsl` is true, then use the current value /// of `rsl` as a seed, otherwise construct one algorithmically (not /// randomly). - priv fn init(&self, use_rsl: bool) { + priv fn init(&mut self, use_rsl: bool) { macro_rules! init_mut_many ( ($( $var:ident ),* = $val:expr ) => { let mut $( $var = $val ),*; @@ -705,16 +707,16 @@ pub impl IsaacRng { /// Refills the output buffer (`self.rsl`) #[inline] - priv fn isaac(&self) { + priv fn isaac(&mut self) { self.c += 1; // abbreviations let mut a = self.a, b = self.b + self.c; - let mem = &mut self.mem; - let rsl = &mut self.rsl; static midpoint: uint = RAND_SIZE as uint / 2; - macro_rules! ind (($x:expr) => { mem[($x >> 2) & (RAND_SIZE - 1)] }); + macro_rules! ind (($x:expr) => { + self.mem[($x >> 2) & (RAND_SIZE - 1)] + }); macro_rules! rngstep( ($j:expr, $shift:expr) => {{ let base = base + $j; @@ -724,13 +726,13 @@ pub impl IsaacRng { a << $shift as uint }; - let x = mem[base + mr_offset]; - a = (a ^ mix) + mem[base + m2_offset]; + let x = self.mem[base + mr_offset]; + a = (a ^ mix) + self.mem[base + m2_offset]; let y = ind!(x) + a + b; - mem[base + mr_offset] = y; + self.mem[base + mr_offset] = y; b = ind!(y >> RAND_SIZE_LEN) + x; - rsl[base + mr_offset] = b; + self.rsl[base + mr_offset] = b; }} ); @@ -751,7 +753,7 @@ pub impl IsaacRng { impl Rng for IsaacRng { #[inline(always)] - fn next(&self) -> u32 { + fn next(&mut self) -> u32 { if self.cnt == 0 { // make some more numbers self.isaac(); @@ -765,15 +767,15 @@ impl Rng for IsaacRng { /// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for /// cryptographic purposes. pub struct XorShiftRng { - priv mut x: u32, - priv mut y: u32, - priv mut z: u32, - priv mut w: u32, + priv x: u32, + priv y: u32, + priv z: u32, + priv w: u32, } impl Rng for XorShiftRng { #[inline] - pub fn next(&self) -> u32 { + pub fn next(&mut self) -> u32 { let x = self.x; let t = x ^ (x << 11); self.x = self.y; @@ -789,7 +791,10 @@ pub impl XorShiftRng { /// Create an xor shift random number generator with a default seed. fn new() -> XorShiftRng { // constants taken from http://en.wikipedia.org/wiki/Xorshift - XorShiftRng::new_seeded(123456789u32, 362436069u32, 521288629u32, 88675123u32) + XorShiftRng::new_seeded(123456789u32, + 362436069u32, + 521288629u32, + 88675123u32) } /** @@ -798,7 +803,12 @@ pub impl XorShiftRng { * all other generators constructed with the same seed. */ fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng { - XorShiftRng { x: x, y: y, z: z, w: w } + XorShiftRng { + x: x, + y: y, + z: z, + w: w, + } } } @@ -815,7 +825,7 @@ pub fn seed() -> ~[u8] { } // used to make space in TLS for a random number generator -fn tls_rng_state(_v: @IsaacRng) {} +fn tls_rng_state(_v: @@mut IsaacRng) {} /** * Gives back a lazily initialized task-local random number generator, @@ -823,15 +833,15 @@ fn tls_rng_state(_v: @IsaacRng) {} * `task_rng().gen::<int>()`. */ #[inline] -pub fn task_rng() -> @IsaacRng { - let r : Option<@IsaacRng>; +pub fn task_rng() -> @@mut IsaacRng { + let r : Option<@@mut IsaacRng>; unsafe { r = task::local_data::local_data_get(tls_rng_state); } match r { None => { unsafe { - let rng = @IsaacRng::new_seeded(seed()); + let rng = @@mut IsaacRng::new_seeded(seed()); task::local_data::local_data_set(tls_rng_state, rng); rng } @@ -841,9 +851,13 @@ pub fn task_rng() -> @IsaacRng { } // Allow direct chaining with `task_rng` -impl<R: Rng> Rng for @R { +impl<R: Rng> Rng for @@mut R { #[inline(always)] - fn next(&self) -> u32 { (**self).next() } + fn next(&mut self) -> u32 { + match *self { + @@ref mut r => r.next() + } + } } /** @@ -852,7 +866,9 @@ impl<R: Rng> Rng for @R { */ #[inline] pub fn random<T: Rand>() -> T { - (*task_rng()).gen() + match *task_rng() { + @ref mut r => r.gen() + } } #[cfg(test)] @@ -863,8 +879,8 @@ mod tests { #[test] fn test_rng_seeded() { let seed = seed(); - let ra = IsaacRng::new_seeded(seed); - let rb = IsaacRng::new_seeded(seed); + let mut ra = IsaacRng::new_seeded(seed); + let mut rb = IsaacRng::new_seeded(seed); assert!(ra.gen_str(100u) == rb.gen_str(100u)); } @@ -872,15 +888,15 @@ mod tests { fn test_rng_seeded_custom_seed() { // much shorter than generated seeds which are 1024 bytes let seed = [2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = IsaacRng::new_seeded(seed); - let rb = IsaacRng::new_seeded(seed); + let mut ra = IsaacRng::new_seeded(seed); + let mut rb = IsaacRng::new_seeded(seed); assert!(ra.gen_str(100u) == rb.gen_str(100u)); } #[test] fn test_rng_seeded_custom_seed2() { let seed = [2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = IsaacRng::new_seeded(seed); + let mut ra = IsaacRng::new_seeded(seed); // Regression test that isaac is actually using the above vector let r = ra.next(); error!("%?", r); @@ -890,7 +906,7 @@ mod tests { #[test] fn test_gen_int_range() { - let r = rng(); + let mut r = rng(); let a = r.gen_int_range(-3, 42); assert!(a >= -3 && a < 42); assert!(r.gen_int_range(0, 1) == 0); @@ -901,12 +917,13 @@ mod tests { #[should_fail] #[ignore(cfg(windows))] fn test_gen_int_from_fail() { - rng().gen_int_range(5, -2); + let mut r = rng(); + r.gen_int_range(5, -2); } #[test] fn test_gen_uint_range() { - let r = rng(); + let mut r = rng(); let a = r.gen_uint_range(3u, 42u); assert!(a >= 3u && a < 42u); assert!(r.gen_uint_range(0u, 1u) == 0u); @@ -917,12 +934,13 @@ mod tests { #[should_fail] #[ignore(cfg(windows))] fn test_gen_uint_range_fail() { - rng().gen_uint_range(5u, 2u); + let mut r = rng(); + r.gen_uint_range(5u, 2u); } #[test] fn test_gen_float() { - let r = rng(); + let mut r = rng(); let a = r.gen::<float>(); let b = r.gen::<float>(); debug!((a, b)); @@ -930,14 +948,14 @@ mod tests { #[test] fn test_gen_weighted_bool() { - let r = rng(); + let mut r = rng(); assert!(r.gen_weighted_bool(0u) == true); assert!(r.gen_weighted_bool(1u) == true); } #[test] fn test_gen_str() { - let r = rng(); + let mut r = rng(); debug!(r.gen_str(10u)); debug!(r.gen_str(10u)); debug!(r.gen_str(10u)); @@ -948,7 +966,7 @@ mod tests { #[test] fn test_gen_bytes() { - let r = rng(); + let mut r = rng(); assert!(r.gen_bytes(0u).len() == 0u); assert!(r.gen_bytes(10u).len() == 10u); assert!(r.gen_bytes(16u).len() == 16u); @@ -956,13 +974,13 @@ mod tests { #[test] fn test_choose() { - let r = rng(); + let mut r = rng(); assert!(r.choose([1, 1, 1]) == 1); } #[test] fn test_choose_option() { - let r = rng(); + let mut r = rng(); let x: Option<int> = r.choose_option([]); assert!(x.is_none()); assert!(r.choose_option([1, 1, 1]) == Some(1)); @@ -970,7 +988,7 @@ mod tests { #[test] fn test_choose_weighted() { - let r = rng(); + let mut r = rng(); assert!(r.choose_weighted(~[ Weighted { weight: 1u, item: 42 }, ]) == 42); @@ -982,7 +1000,7 @@ mod tests { #[test] fn test_choose_weighted_option() { - let r = rng(); + let mut r = rng(); assert!(r.choose_weighted_option(~[ Weighted { weight: 1u, item: 42 }, ]) == Some(42)); @@ -996,7 +1014,7 @@ mod tests { #[test] fn test_weighted_vec() { - let r = rng(); + let mut r = rng(); let empty: ~[int] = ~[]; assert!(r.weighted_vec(~[]) == empty); assert!(r.weighted_vec(~[ @@ -1008,7 +1026,7 @@ mod tests { #[test] fn test_shuffle() { - let r = rng(); + let mut r = rng(); let empty: ~[int] = ~[]; assert!(r.shuffle(~[]) == empty); assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]); @@ -1016,7 +1034,7 @@ mod tests { #[test] fn test_task_rng() { - let r = task_rng(); + let mut r = task_rng(); r.gen::<int>(); assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]); assert!(r.gen_uint_range(0u, 1u) == 0u); @@ -1063,7 +1081,7 @@ mod tests { let rt_rng = do vec::as_imm_buf(seed) |p, sz| { rustrt::rand_new_seeded(p, sz as size_t) }; - let rng = IsaacRng::new_seeded(seed); + let mut rng = IsaacRng::new_seeded(seed); for 10000.times { assert_eq!(rng.next(), rustrt::rand_next(rt_rng)); diff --git a/src/libcore/rand/distributions.rs b/src/libcore/rand/distributions.rs index a644f60db69..72cff5111e7 100644 --- a/src/libcore/rand/distributions.rs +++ b/src/libcore/rand/distributions.rs @@ -27,13 +27,13 @@ mod ziggurat_tables; // inlining should mean there is no performance penalty for this #[inline(always)] -fn ziggurat<R:Rng>(rng: &R, +fn ziggurat<R:Rng>(rng: &mut R, center_u: bool, X: ziggurat_tables::ZigTable, F: ziggurat_tables::ZigTable, F_DIFF: ziggurat_tables::ZigTable, pdf: &'static fn(f64) -> f64, // probability density function - zero_case: &'static fn(&R, f64) -> f64) -> f64 { + zero_case: &'static fn(&mut R, f64) -> f64) -> f64 { loop { let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()}; let i: uint = rng.gen::<uint>() & 0xff; @@ -76,13 +76,13 @@ fn ziggurat<R:Rng>(rng: &R, pub struct StandardNormal(f64); impl Rand for StandardNormal { - fn rand<R:Rng>(rng: &R) -> StandardNormal { + fn rand<R:Rng>(rng: &mut R) -> StandardNormal { #[inline(always)] fn pdf(x: f64) -> f64 { f64::exp((-x*x/2.0) as f64) as f64 } #[inline(always)] - fn zero_case<R:Rng>(rng: &R, u: f64) -> f64 { + fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 { // compute a random number in the tail by hand // strange initial conditions, because the loop is not @@ -130,13 +130,13 @@ pub struct Exp1(f64); // This could be done via `-f64::ln(rng.gen::<f64>())` but that is slower. impl Rand for Exp1 { #[inline] - fn rand<R:Rng>(rng: &R) -> Exp1 { + fn rand<R:Rng>(rng: &mut R) -> Exp1 { #[inline(always)] fn pdf(x: f64) -> f64 { f64::exp(-x) } #[inline(always)] - fn zero_case<R:Rng>(rng: &R, _u: f64) -> f64 { + fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 { ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen()) } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 3d525993259..a645a7e8680 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -144,28 +144,30 @@ enum VariantState { } pub struct ReprVisitor { - mut ptr: *c_void, - mut ptr_stk: ~[*c_void], - mut var_stk: ~[VariantState], + ptr: @mut *c_void, + ptr_stk: @mut ~[*c_void], + var_stk: @mut ~[VariantState], writer: @Writer } pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor { - ReprVisitor { ptr: ptr, - ptr_stk: ~[], - var_stk: ~[], - writer: writer } + ReprVisitor { + ptr: @mut ptr, + ptr_stk: @mut ~[], + var_stk: @mut ~[], + writer: writer, + } } impl MovePtr for ReprVisitor { #[inline(always)] fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void) { - self.ptr = adjustment(self.ptr); + *self.ptr = adjustment(*self.ptr); } fn push_ptr(&self) { - self.ptr_stk.push(self.ptr); + self.ptr_stk.push(*self.ptr); } fn pop_ptr(&self) { - self.ptr = self.ptr_stk.pop(); + *self.ptr = self.ptr_stk.pop(); } } @@ -176,14 +178,14 @@ pub impl ReprVisitor { #[inline(always)] fn get<T>(&self, f: &fn(&T)) -> bool { unsafe { - f(transmute::<*c_void,&T>(copy self.ptr)); + f(transmute::<*c_void,&T>(*self.ptr)); } true } #[inline(always)] fn visit_inner(&self, inner: *TyDesc) -> bool { - self.visit_ptr_inner(self.ptr, inner) + self.visit_ptr_inner(*self.ptr, inner) } #[inline(always)] @@ -446,11 +448,16 @@ impl TyVisitor for ReprVisitor { true } - fn visit_enter_enum(&self, _n_variants: uint, + fn visit_enter_enum(&self, + _n_variants: uint, get_disr: extern unsafe fn(ptr: *Opaque) -> int, - _sz: uint, _align: uint) -> bool { - let disr = unsafe { get_disr(transmute(self.ptr)) }; - self.var_stk.push(SearchingFor(disr)); + _sz: uint, + _align: uint) -> bool { + let var_stk: &mut ~[VariantState] = self.var_stk; + let disr = unsafe { + get_disr(transmute(*self.ptr)) + }; + var_stk.push(SearchingFor(disr)); true } @@ -482,8 +489,12 @@ impl TyVisitor for ReprVisitor { true } - fn visit_enum_variant_field(&self, i: uint, _offset: uint, inner: *TyDesc) -> bool { - match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] { + fn visit_enum_variant_field(&self, + i: uint, + _offset: uint, + inner: *TyDesc) + -> bool { + match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] { Matched => { if i != 0 { self.writer.write_str(", "); @@ -501,7 +512,7 @@ impl TyVisitor for ReprVisitor { _disr_val: int, n_fields: uint, _name: &str) -> bool { - match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] { + match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] { Matched => { if n_fields > 0 { self.writer.write_char(')'); @@ -512,10 +523,14 @@ impl TyVisitor for ReprVisitor { true } - fn visit_leave_enum(&self, _n_variants: uint, + fn visit_leave_enum(&self, + _n_variants: uint, _get_disr: extern unsafe fn(ptr: *Opaque) -> int, - _sz: uint, _align: uint) -> bool { - match self.var_stk.pop() { + _sz: uint, + _align: uint) + -> bool { + let var_stk: &mut ~[VariantState] = self.var_stk; + match var_stk.pop() { SearchingFor(*) => fail!(~"enum value matched no variant"), _ => true } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 17cc07c660d..1d67e754a4f 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -300,7 +300,7 @@ pub fn map_vec<T,U:Copy,V:Copy>( ts: &[T], op: &fn(&T) -> Result<V,U>) -> Result<~[V],U> { let mut vs: ~[V] = vec::with_capacity(vec::len(ts)); - for vec::each(ts) |t| { + for ts.each |t| { match op(t) { Ok(copy v) => vs.push(v), Err(copy u) => return Err(u) diff --git a/src/libcore/rt/local_services.rs b/src/libcore/rt/local_services.rs index b83e1d24648..5ca7a72e84e 100644 --- a/src/libcore/rt/local_services.rs +++ b/src/libcore/rt/local_services.rs @@ -225,8 +225,8 @@ mod test { fn rng() { do run_in_newsched_task() { use rand::{rng, Rng}; - let r = rng(); + let mut r = rng(); let _ = r.next(); } } -} \ No newline at end of file +} diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs index a072fccd33d..25f6c870654 100644 --- a/src/libcore/rt/mod.rs +++ b/src/libcore/rt/mod.rs @@ -38,22 +38,35 @@ mod local_heap; pub mod test; pub fn start(main: *u8, _argc: int, _argv: **c_char, _crate_map: *u8) -> int { + use self::sched::{Scheduler, Task}; use self::uvio::UvEventLoop; + use sys::Closure; + use ptr; + use cast; let loop_ = ~UvEventLoop::new(); let mut sched = ~Scheduler::new(loop_); + let main_task = ~do Task::new(&mut sched.stack_pool) { - // XXX: Can't call a C function pointer from Rust yet - unsafe { rust_call_nullary_fn(main) }; + + unsafe { + // `main` is an `fn() -> ()` that doesn't take an environment + // XXX: Could also call this as an `extern "Rust" fn` once they work + let main = Closure { + code: main as *(), + env: ptr::null(), + }; + let mainfn: &fn() = cast::transmute(main); + + mainfn(); + } }; + sched.task_queue.push_back(main_task); sched.run(); - return 0; - extern { - fn rust_call_nullary_fn(f: *u8); - } + return 0; } /// Possible contexts in which Rust code may be executing. diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs index 3eb7f8006b9..4bff3bff7d3 100644 --- a/src/libcore/rt/uvll.rs +++ b/src/libcore/rt/uvll.rs @@ -393,24 +393,26 @@ extern { // FIXME ref #2064 fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in) -> c_int; + after_cb: *u8, + addr: *sockaddr_in) -> c_int; // FIXME ref #2064 - fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in) -> c_int; + fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int; // FIXME ref #2064 fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in6) -> c_int; + after_cb: *u8, + addr: *sockaddr_in6) -> c_int; // FIXME ref #2064 - fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> c_int; - fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in) -> c_int; - fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in6) ->c_int; + fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int; + fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in) -> c_int; + fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in6) ->c_int; fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int; fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int; fn rust_uv_write(req: *c_void, stream: *c_void, - ++buf_in: *uv_buf_t, + buf_in: *uv_buf_t, buf_cnt: c_int, cb: *u8) -> c_int; fn rust_uv_read_start(stream: *c_void, @@ -426,7 +428,7 @@ extern { fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int; fn rust_uv_malloc_buf_base_of(sug_size: size_t) -> *u8; - fn rust_uv_free_base_of_buf(++buf: uv_buf_t); + fn rust_uv_free_base_of_buf(buf: uv_buf_t); fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t; fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t; fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void; @@ -436,6 +438,6 @@ extern { fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void); fn rust_uv_get_data_for_req(req: *c_void) -> *c_void; fn rust_uv_set_data_for_req(req: *c_void, data: *c_void); - fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; - fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> size_t; + fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8; + fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> size_t; } diff --git a/src/libcore/run.rs b/src/libcore/run.rs index 55b6c5100dd..fd168dc02f6 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -426,7 +426,7 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: &fn(**libc::c_char) -> T) -> T { let mut argptrs = str::as_c_str(prog, |b| ~[b]); let mut tmps = ~[]; - for vec::each(args) |arg| { + for args.each |arg| { let t = @copy *arg; tmps.push(t); argptrs.push_all(str::as_c_str(*t, |b| ~[b])); @@ -445,7 +445,7 @@ fn with_envp<T>(env: &Option<~[(~str,~str)]>, let mut tmps = ~[]; let mut ptrs = ~[]; - for vec::each(*es) |e| { + for (*es).each |e| { let (k,v) = copy *e; let t = @(fmt!("%s=%s", k, v)); tmps.push(t); @@ -470,7 +470,7 @@ fn with_envp<T>(env: &Option<~[(~str,~str)]>, match *env { Some(ref es) if !vec::is_empty(*es) => { let mut blk : ~[u8] = ~[]; - for vec::each(*es) |e| { + for (*es).each |e| { let (k,v) = copy *e; let t = fmt!("%s=%s", k, v); let mut v : ~[u8] = ::cast::transmute(t); diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 24237694502..1958b5b9d80 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -81,6 +81,6 @@ fn frame_address(f: &fn(x: *u8)) { pub mod rusti { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { - pub fn frame_address(+f: &once fn(x: *u8)); + pub fn frame_address(f: &once fn(x: *u8)); } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index a41c99b266b..5ec6471ac4a 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -32,7 +32,7 @@ use uint; use vec; use to_str::ToStr; -#[cfg(notest)] use cmp::{Eq, Ord, Equiv, TotalEq}; +#[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq}; /* Section: Creating a string @@ -189,7 +189,7 @@ pub fn from_char(ch: char) -> ~str { pub fn from_chars(chs: &[char]) -> ~str { let mut buf = ~""; reserve(&mut buf, chs.len()); - for vec::each(chs) |ch| { + for chs.each |ch| { push_char(&mut buf, *ch); } buf @@ -326,7 +326,7 @@ pub fn connect_slices(v: &[&str], sep: &str) -> ~str { do as_buf(sep) |sepbuf, seplen| { let seplen = seplen - 1; let mut buf = ::cast::transmute_mut_unsafe(buf); - for vec::each(v) |ss| { + for v.each |ss| { do as_buf(*ss) |ssbuf, sslen| { let sslen = sslen - 1; if first { @@ -913,7 +913,7 @@ Section: Comparing strings */ /// Bytewise slice equality -#[cfg(notest)] +#[cfg(not(test))] #[lang="str_eq"] #[inline] pub fn eq_slice(a: &str, b: &str) -> bool { @@ -949,7 +949,7 @@ pub fn eq_slice(a: &str, b: &str) -> bool { } /// Bytewise string equality -#[cfg(notest)] +#[cfg(not(test))] #[lang="uniq_str_eq"] #[inline] pub fn eq(a: &~str, b: &~str) -> bool { @@ -977,19 +977,19 @@ fn cmp(a: &str, b: &str) -> Ordering { a.len().cmp(&b.len()) } -#[cfg(notest)] +#[cfg(not(test))] impl<'self> TotalOrd for &'self str { #[inline] fn cmp(&self, other: & &'self str) -> Ordering { cmp(*self, *other) } } -#[cfg(notest)] +#[cfg(not(test))] impl TotalOrd for ~str { #[inline] fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) } } -#[cfg(notest)] +#[cfg(not(test))] impl TotalOrd for @str { #[inline] fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) } @@ -1030,7 +1030,7 @@ fn gt(a: &str, b: &str) -> bool { !le(a, b) } -#[cfg(notest)] +#[cfg(not(test))] impl<'self> Eq for &'self str { #[inline(always)] fn eq(&self, other: & &'self str) -> bool { @@ -1040,7 +1040,7 @@ impl<'self> Eq for &'self str { fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl Eq for ~str { #[inline(always)] fn eq(&self, other: &~str) -> bool { @@ -1050,7 +1050,7 @@ impl Eq for ~str { fn ne(&self, other: &~str) -> bool { !(*self).eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl Eq for @str { #[inline(always)] fn eq(&self, other: &@str) -> bool { @@ -1060,7 +1060,7 @@ impl Eq for @str { fn ne(&self, other: &@str) -> bool { !(*self).eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<'self> TotalEq for &'self str { #[inline(always)] fn equals(&self, other: & &'self str) -> bool { @@ -1068,7 +1068,7 @@ impl<'self> TotalEq for &'self str { } } -#[cfg(notest)] +#[cfg(not(test))] impl TotalEq for ~str { #[inline(always)] fn equals(&self, other: &~str) -> bool { @@ -1076,7 +1076,7 @@ impl TotalEq for ~str { } } -#[cfg(notest)] +#[cfg(not(test))] impl TotalEq for @str { #[inline(always)] fn equals(&self, other: &@str) -> bool { @@ -1084,7 +1084,7 @@ impl TotalEq for @str { } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for ~str { #[inline(always)] fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) } @@ -1096,7 +1096,7 @@ impl Ord for ~str { fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) } } -#[cfg(notest)] +#[cfg(not(test))] impl<'self> Ord for &'self str { #[inline(always)] fn lt(&self, other: & &'self str) -> bool { lt((*self), (*other)) } @@ -1108,7 +1108,7 @@ impl<'self> Ord for &'self str { fn gt(&self, other: & &'self str) -> bool { gt((*self), (*other)) } } -#[cfg(notest)] +#[cfg(not(test))] impl Ord for @str { #[inline(always)] fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) } @@ -1120,7 +1120,7 @@ impl Ord for @str { fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) } } -#[cfg(notest)] +#[cfg(not(test))] impl<'self> Equiv<~str> for &'self str { #[inline(always)] fn equiv(&self, other: &~str) -> bool { eq_slice(*self, *other) } @@ -2407,7 +2407,7 @@ pub mod raw { unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) { let new_len = s.len() + bytes.len(); reserve_at_least(&mut *s, new_len); - for vec::each(bytes) |byte| { push_byte(&mut *s, *byte); } + for bytes.each |byte| { push_byte(&mut *s, *byte); } } /// Removes the last byte from a string and returns it. (Not UTF-8 safe). @@ -2451,7 +2451,7 @@ pub mod raw { } -#[cfg(notest)] +#[cfg(not(test))] pub mod traits { use ops::Add; use str::append; @@ -3782,7 +3782,7 @@ mod tests { 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16, 0x000a_u16 ]) ]; - for vec::each(pairs) |p| { + for pairs.each |p| { let (s, u) = copy *p; assert!(to_utf16(s) == u); assert!(from_utf16(u) == s); diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index fd695c16ea7..e58aa14572b 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -156,7 +156,7 @@ pub struct SchedOpts { pub struct TaskOpts { linked: bool, supervised: bool, - mut notify_chan: Option<Chan<TaskResult>>, + notify_chan: Option<Chan<TaskResult>>, sched: SchedOpts } @@ -176,9 +176,9 @@ pub struct TaskOpts { // FIXME (#3724): Replace the 'consumed' bit with move mode on self pub struct TaskBuilder { opts: TaskOpts, - mut gen_body: Option<~fn(v: ~fn()) -> ~fn()>, + gen_body: Option<~fn(v: ~fn()) -> ~fn()>, can_not_copy: Option<util::NonCopyable>, - mut consumed: bool, + consumed: bool, } /** @@ -191,13 +191,13 @@ pub fn task() -> TaskBuilder { opts: default_task_opts(), gen_body: None, can_not_copy: None, - mut consumed: false, + consumed: false, } } #[doc(hidden)] // FIXME #3538 priv impl TaskBuilder { - fn consume(&self) -> TaskBuilder { + fn consume(&mut self) -> TaskBuilder { if self.consumed { fail!(~"Cannot copy a task_builder"); // Fake move mode on self } @@ -219,57 +219,25 @@ priv impl TaskBuilder { } pub impl TaskBuilder { - /** - * Decouple the child task's failure from the parent's. If either fails, - * the other will not be killed. - */ - fn unlinked(&self) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: false, - supervised: self.opts.supervised, - notify_chan: notify_chan, - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + /// Decouple the child task's failure from the parent's. If either fails, + /// the other will not be killed. + fn unlinked(&mut self) { + self.opts.linked = false; } - /** - * Unidirectionally link the child task's failure with the parent's. The - * child's failure will not kill the parent, but the parent's will kill - * the child. - */ - fn supervised(&self) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: false, - supervised: true, - notify_chan: notify_chan, - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + + /// Unidirectionally link the child task's failure with the parent's. The + /// child's failure will not kill the parent, but the parent's will kill + /// the child. + fn supervised(&mut self) { + self.opts.supervised = true; + self.opts.linked = false; } - /** - * Link the child task's and parent task's failures. If either fails, the - * other will be killed. - */ - fn linked(&self) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: true, - supervised: false, - notify_chan: notify_chan, - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + + /// Link the child task's and parent task's failures. If either fails, the + /// other will be killed. + fn linked(&mut self) { + self.opts.linked = true; + self.opts.supervised = false; } /** @@ -289,7 +257,7 @@ pub impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn future_result(&self, blk: &fn(v: Port<TaskResult>)) -> TaskBuilder { + fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) { // FIXME (#3725): Once linked failure and notification are // handled in the library, I can imagine implementing this by just // registering an arbitrary number of task::on_exit handlers and @@ -305,30 +273,12 @@ pub impl TaskBuilder { blk(notify_pipe_po); // Reconfigure self to use a notify channel. - TaskBuilder { - opts: TaskOpts { - linked: self.opts.linked, - supervised: self.opts.supervised, - notify_chan: Some(notify_pipe_ch), - sched: self.opts.sched - }, - can_not_copy: None, - .. self.consume() - } + self.opts.notify_chan = Some(notify_pipe_ch); } + /// Configure a custom scheduler mode for the task. - fn sched_mode(&self, mode: SchedMode) -> TaskBuilder { - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: self.opts.linked, - supervised: self.opts.supervised, - notify_chan: notify_chan, - sched: SchedOpts { mode: mode, foreign_stack_size: None} - }, - can_not_copy: None, - .. self.consume() - } + fn sched_mode(&mut self, mode: SchedMode) { + self.opts.sched.mode = mode; } /** @@ -343,7 +293,7 @@ pub impl TaskBuilder { * generator by applying the task body which results from the * existing body generator to the new body generator. */ - fn add_wrapper(&self, wrapper: ~fn(v: ~fn()) -> ~fn()) -> TaskBuilder { + fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) { let prev_gen_body = replace(&mut self.gen_body, None); let prev_gen_body = match prev_gen_body { Some(gen) => gen, @@ -360,18 +310,7 @@ pub impl TaskBuilder { }; f }; - let notify_chan = replace(&mut self.opts.notify_chan, None); - TaskBuilder { - opts: TaskOpts { - linked: self.opts.linked, - supervised: self.opts.supervised, - notify_chan: notify_chan, - sched: self.opts.sched - }, - gen_body: Some(next_gen_body), - can_not_copy: None, - .. self.consume() - } + self.gen_body = Some(next_gen_body); } /** @@ -386,7 +325,7 @@ pub impl TaskBuilder { * When spawning into a new scheduler, the number of threads requested * must be greater than zero. */ - fn spawn(&self, f: ~fn()) { + fn spawn(&mut self, f: ~fn()) { let gen_body = replace(&mut self.gen_body, None); let notify_chan = replace(&mut self.opts.notify_chan, None); let x = self.consume(); @@ -406,8 +345,9 @@ pub impl TaskBuilder { }; spawn::spawn_raw(opts, f); } + /// Runs a task, while transfering ownership of one argument to the child. - fn spawn_with<A:Owned>(&self, arg: A, f: ~fn(v: A)) { + fn spawn_with<A:Owned>(&mut self, arg: A, f: ~fn(v: A)) { let arg = Cell(arg); do self.spawn { f(arg.take()); @@ -427,16 +367,16 @@ pub impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn try<T:Owned>(&self, f: ~fn() -> T) -> Result<T,()> { + fn try<T:Owned>(&mut self, f: ~fn() -> T) -> Result<T,()> { let (po, ch) = stream::<T>(); let mut result = None; - let fr_task_builder = self.future_result(|+r| { - result = Some(r); - }); - do fr_task_builder.spawn || { + self.future_result(|r| { result = Some(r); }); + + do self.spawn { ch.send(f()); } + match result.unwrap().recv() { Success => result::Ok(po.recv()), Failure => result::Err(()) @@ -468,26 +408,23 @@ pub fn default_task_opts() -> TaskOpts { /* Spawn convenience functions */ +/// Creates and executes a new child task +/// +/// Sets up a new task with its own call stack and schedules it to run +/// the provided unique closure. +/// +/// This function is equivalent to `task().spawn(f)`. pub fn spawn(f: ~fn()) { - /*! - * Creates and executes a new child task - * - * Sets up a new task with its own call stack and schedules it to run - * the provided unique closure. - * - * This function is equivalent to `task().spawn(f)`. - */ - - task().spawn(f) + let mut task = task(); + task.spawn(f) } +/// Creates a child task unlinked from the current one. If either this +/// task or the child task fails, the other will not be killed. pub fn spawn_unlinked(f: ~fn()) { - /*! - * Creates a child task unlinked from the current one. If either this - * task or the child task fails, the other will not be killed. - */ - - task().unlinked().spawn(f) + let mut task = task(); + task.unlinked(); + task.spawn(f) } pub fn spawn_supervised(f: ~fn()) { @@ -497,7 +434,9 @@ pub fn spawn_supervised(f: ~fn()) { * the child will be killed. */ - task().supervised().spawn(f) + let mut task = task(); + task.supervised(); + task.spawn(f) } pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) { @@ -511,7 +450,8 @@ pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) { * This function is equivalent to `task().spawn_with(arg, f)`. */ - task().spawn_with(arg, f) + let mut task = task(); + task.spawn_with(arg, f) } pub fn spawn_sched(mode: SchedMode, f: ~fn()) { @@ -527,7 +467,9 @@ pub fn spawn_sched(mode: SchedMode, f: ~fn()) { * greater than zero. */ - task().sched_mode(mode).spawn(f) + let mut task = task(); + task.sched_mode(mode); + task.spawn(f) } pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> { @@ -538,7 +480,9 @@ pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> { * This is equivalent to task().supervised().try. */ - task().supervised().try(f) + let mut task = task(); + task.supervised(); + task.try(f) } @@ -653,12 +597,13 @@ pub unsafe fn atomically<U>(f: &fn() -> U) -> U { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_cant_dup_task_builder() { - let b = task().unlinked(); - do b.spawn { } + let mut builder = task(); + builder.unlinked(); + do builder.spawn {} // FIXME(#3724): For now, this is a -runtime- failure, because we haven't // got move mode on self. When 3724 is fixed, this test should fail to // compile instead, and should go in tests/compile-fail. - do b.spawn { } // b should have been consumed by the previous call + do builder.spawn {} // b should have been consumed by the previous call } // The following 8 tests test the following 2^3 combinations: @@ -701,43 +646,31 @@ fn test_spawn_unlinked_sup_fail_down() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_sup_fail_up() { // child fails; parent fails let (po, _ch) = stream::<()>(); + // Unidirectional "parenting" shouldn't override bidirectional linked. // We have to cheat with opts - the interface doesn't support them because // they don't make sense (redundant with task().supervised()). - let opts = { - let mut opts = default_task_opts(); - opts.linked = true; - opts.supervised = true; - opts - }; + let mut b0 = task(); + b0.opts.linked = true; + b0.opts.supervised = true; - let b0 = task(); - let b1 = TaskBuilder { - opts: opts, - can_not_copy: None, - .. b0 - }; - do b1.spawn { fail!(); } + do b0.spawn { + fail!(); + } po.recv(); // We should get punted awake } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_sup_fail_down() { // parent fails; child fails // We have to cheat with opts - the interface doesn't support them because // they don't make sense (redundant with task().supervised()). - let opts = { - let mut opts = default_task_opts(); - opts.linked = true; - opts.supervised = true; - opts - }; - - let b0 = task(); - let b1 = TaskBuilder { - opts: opts, - can_not_copy: None, - .. b0 - }; - do b1.spawn { loop { task::yield(); } } + let mut b0 = task(); + b0.opts.linked = true; + b0.opts.supervised = true; + do b0.spawn { + loop { + task::yield(); + } + } fail!(); // *both* mechanisms would be wrong if this didn't kill the child } #[test] #[should_fail] #[ignore(cfg(windows))] @@ -756,7 +689,13 @@ fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails // Make sure the above test is the same as this one. - do task().linked().spawn { loop { task::yield(); } } + let mut builder = task(); + builder.linked(); + do builder.spawn { + loop { + task::yield(); + } + } fail!(); } @@ -814,7 +753,8 @@ fn test_spawn_linked_sup_propagate_sibling() { #[test] fn test_run_basic() { let (po, ch) = stream::<()>(); - do task().spawn { + let mut builder = task(); + do builder.spawn { ch.send(()); } po.recv(); @@ -822,24 +762,24 @@ fn test_run_basic() { #[cfg(test)] struct Wrapper { - mut f: Option<Chan<()>> + f: Option<Chan<()>> } #[test] fn test_add_wrapper() { let (po, ch) = stream::<()>(); - let b0 = task(); - let ch = Wrapper { f: Some(ch) }; - let b1 = do b0.add_wrapper |body| { - let ch = Wrapper { f: Some(ch.f.swap_unwrap()) }; + let mut b0 = task(); + let ch = Cell(ch); + do b0.add_wrapper |body| { + let ch = Cell(ch.take()); let result: ~fn() = || { - let ch = ch.f.swap_unwrap(); + let mut ch = ch.take(); body(); ch.send(()); }; result }; - do b1.spawn { } + do b0.spawn { } po.recv(); } @@ -847,12 +787,16 @@ fn test_add_wrapper() { #[ignore(cfg(windows))] fn test_future_result() { let mut result = None; - do task().future_result(|+r| { result = Some(r); }).spawn { } + let mut builder = task(); + builder.future_result(|r| result = Some(r)); + do builder.spawn {} assert!(result.unwrap().recv() == Success); result = None; - do task().future_result(|+r| - { result = Some(r); }).unlinked().spawn { + let mut builder = task(); + builder.future_result(|r| result = Some(r)); + builder.unlinked(); + do builder.spawn { fail!(); } assert!(result.unwrap().recv() == Failure); @@ -860,7 +804,9 @@ fn test_future_result() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_back_to_the_future_result() { - let _ = task().future_result(util::ignore).future_result(util::ignore); + let mut builder = task(); + builder.future_result(util::ignore); + builder.future_result(util::ignore); } #[test] @@ -922,12 +868,12 @@ fn test_spawn_sched_childs_on_default_sched() { // Assuming tests run on the default scheduler let default_id = unsafe { rt::rust_get_sched_id() }; - let ch = Wrapper { f: Some(ch) }; + let ch = Cell(ch); do spawn_sched(SingleThreaded) { let parent_sched_id = unsafe { rt::rust_get_sched_id() }; - let ch = Wrapper { f: Some(ch.f.swap_unwrap()) }; + let ch = Cell(ch.take()); do spawn { - let ch = ch.f.swap_unwrap(); + let ch = ch.take(); let child_sched_id = unsafe { rt::rust_get_sched_id() }; assert!(parent_sched_id != child_sched_id); assert!(child_sched_id == default_id); @@ -1035,7 +981,8 @@ fn test_avoid_copying_the_body_spawn() { #[test] fn test_avoid_copying_the_body_task_spawn() { do avoid_copying_the_body |f| { - do task().spawn || { + let mut builder = task(); + do builder.spawn || { f(); } } @@ -1062,7 +1009,9 @@ fn test_avoid_copying_the_body_unlinked() { #[test] fn test_platform_thread() { let (po, ch) = stream(); - do task().sched_mode(PlatformThread).spawn { + let mut builder = task(); + builder.sched_mode(PlatformThread); + do builder.spawn { ch.send(()); } po.recv(); diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 267250b3642..19c417dfdfc 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -72,6 +72,7 @@ #[doc(hidden)]; // FIXME #3538 +use cast::transmute; use cast; use cell::Cell; use container::Map; @@ -117,10 +118,10 @@ pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) { struct TaskGroupData { // All tasks which might kill this group. When this is empty, the group // can be "GC"ed (i.e., its link in the ancestor list can be removed). - mut members: TaskSet, + members: TaskSet, // All tasks unidirectionally supervised by (directly or transitively) // tasks in this group. - mut descendants: TaskSet, + descendants: TaskSet, } type TaskGroupArc = unstable::Exclusive<Option<TaskGroupData>>; @@ -145,11 +146,11 @@ struct AncestorNode { // Hence we assert that this counter monotonically decreases as we // approach the tail of the list. // FIXME(#3068): Make the generation counter togglable with #[cfg(debug)]. - generation: uint, - // Should really be an immutable non-option. This way appeases borrowck. - mut parent_group: Option<TaskGroupArc>, + generation: uint, + // Should really be a non-option. This way appeases borrowck. + parent_group: Option<TaskGroupArc>, // Recursive rest of the list. - mut ancestors: AncestorList, + ancestors: AncestorList, } struct AncestorList(Option<unstable::Exclusive<AncestorNode>>); @@ -301,22 +302,26 @@ fn each_ancestor(list: &mut AncestorList, // One of these per task. struct TCB { - me: *rust_task, + me: *rust_task, // List of tasks with whose fates this one's is intertwined. - tasks: TaskGroupArc, // 'none' means the group has failed. + tasks: TaskGroupArc, // 'none' means the group has failed. // Lists of tasks who will kill us if they fail, but whom we won't kill. - mut ancestors: AncestorList, - is_main: bool, - notifier: Option<AutoNotify>, + ancestors: AncestorList, + is_main: bool, + notifier: Option<AutoNotify>, } impl Drop for TCB { // Runs on task exit. fn finalize(&self) { unsafe { + let this: &mut TCB = transmute(self); + // If we are failing, the whole taskgroup needs to die. if rt::rust_task_is_unwinding(self.me) { - for self.notifier.each |x| { x.failed = true; } + for this.notifier.each_mut |x| { + x.failed = true; + } // Take everybody down with us. do access_group(&self.tasks) |tg| { kill_taskgroup(tg, self.me, self.is_main); @@ -331,16 +336,21 @@ impl Drop for TCB { // with our own taskgroup, so long as both happen before we die. // We remove ourself from every ancestor we can, so no cleanup; no // break. - for each_ancestor(&mut self.ancestors, None) |ancestor_group| { + for each_ancestor(&mut this.ancestors, None) |ancestor_group| { leave_taskgroup(ancestor_group, self.me, false); }; } } } -fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, - is_main: bool, notifier: Option<AutoNotify>) -> TCB { - for notifier.each |x| { x.failed = false; } +fn TCB(me: *rust_task, + tasks: TaskGroupArc, + ancestors: AncestorList, + is_main: bool, + mut notifier: Option<AutoNotify>) -> TCB { + for notifier.each_mut |x| { + x.failed = false; + } TCB { me: me, @@ -353,7 +363,7 @@ fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, struct AutoNotify { notify_chan: Chan<TaskResult>, - mut failed: bool, + failed: bool, } impl Drop for AutoNotify { @@ -375,9 +385,12 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, let newstate = util::replace(&mut *state, None); // If 'None', the group was failing. Can't enlist. if newstate.is_some() { - let group = newstate.unwrap(); - taskset_insert(if is_member { &mut group.members } - else { &mut group.descendants }, me); + let mut group = newstate.unwrap(); + taskset_insert(if is_member { + &mut group.members + } else { + &mut group.descendants + }, me); *state = Some(group); true } else { @@ -391,9 +404,12 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, let newstate = util::replace(&mut *state, None); // If 'None', already failing and we've already gotten a kill signal. if newstate.is_some() { - let group = newstate.unwrap(); - taskset_remove(if is_member { &mut group.members } - else { &mut group.descendants }, me); + let mut group = newstate.unwrap(); + taskset_remove(if is_member { + &mut group.members + } else { + &mut group.descendants + }, me); *state = Some(group); } } @@ -451,23 +467,30 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) /*##################################################################* * Step 1. Get spawner's taskgroup info. *##################################################################*/ - let spawner_group = match local_get(OldHandle(spawner), taskgroup_key!()) { - None => { - // Main task, doing first spawn ever. Lazily initialise here. - let mut members = new_taskset(); - taskset_insert(&mut members, spawner); - let tasks = unstable::exclusive(Some(TaskGroupData { - members: members, - descendants: new_taskset(), - })); - // Main task/group has no ancestors, no notifier, etc. - let group = - @TCB(spawner, tasks, AncestorList(None), true, None); - local_set(OldHandle(spawner), taskgroup_key!(), group); - group - } - Some(group) => group - }; + let mut spawner_group: @@mut TCB = + match local_get(OldHandle(spawner), taskgroup_key!()) { + None => { + // Main task, doing first spawn ever. Lazily initialise + // here. + let mut members = new_taskset(); + taskset_insert(&mut members, spawner); + let tasks = unstable::exclusive(Some(TaskGroupData { + members: members, + descendants: new_taskset(), + })); + // Main task/group has no ancestors, no notifier, etc. + let group = @@mut TCB(spawner, + tasks, + AncestorList(None), + true, + None); + local_set(OldHandle(spawner), taskgroup_key!(), group); + group + } + Some(group) => group + }; + let spawner_group: &mut TCB = *spawner_group; + /*##################################################################* * Step 2. Process spawn options for child. *##################################################################*/ @@ -557,7 +580,7 @@ fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) { sched.schedule_new_task(task); } -fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) { +fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { let (child_tg, ancestors, is_main) = gen_child_taskgroup(opts.linked, opts.supervised); @@ -624,8 +647,11 @@ fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) { }; if enlist_many(child, &child_arc, &mut ancestors) { - let group = @TCB(child, child_arc, ancestors, - is_main, notifier); + let group = @@mut TCB(child, + child_arc, + ancestors, + is_main, + notifier); unsafe { local_set(OldHandle(child), taskgroup_key!(), group); } diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 6da22657906..b29a4e55426 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -14,7 +14,7 @@ use clone::Clone; use kinds::Copy; use vec; -#[cfg(notest)] use cmp::{Eq, Ord}; +#[cfg(not(test))] use cmp::{Eq, Ord}; pub trait CopyableTuple<T, U> { fn first(&self) -> T; @@ -122,7 +122,7 @@ impl<A:Copy,B:Copy> ExtendedTupleOps<A,B> for (~[A], ~[B]) { } } -#[cfg(notest)] +#[cfg(not(test))] impl<A:Eq> Eq for (A,) { #[inline(always)] fn eq(&self, other: &(A,)) -> bool { @@ -138,7 +138,7 @@ impl<A:Eq> Eq for (A,) { fn ne(&self, other: &(A,)) -> bool { !(*self).eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<A:Ord> Ord for (A,) { #[inline(always)] fn lt(&self, other: &(A,)) -> bool { @@ -161,7 +161,7 @@ impl<A:Ord> Ord for (A,) { fn gt(&self, other: &(A,)) -> bool { other.lt(&(*self)) } } -#[cfg(notest)] +#[cfg(not(test))] impl<A:Eq,B:Eq> Eq for (A, B) { #[inline(always)] fn eq(&self, other: &(A, B)) -> bool { @@ -177,7 +177,7 @@ impl<A:Eq,B:Eq> Eq for (A, B) { fn ne(&self, other: &(A, B)) -> bool { !(*self).eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<A:Ord,B:Ord> Ord for (A, B) { #[inline(always)] fn lt(&self, other: &(A, B)) -> bool { @@ -202,7 +202,7 @@ impl<A:Ord,B:Ord> Ord for (A, B) { fn gt(&self, other: &(A, B)) -> bool { (*other).lt(&(*self)) } } -#[cfg(notest)] +#[cfg(not(test))] impl<A:Eq,B:Eq,C:Eq> Eq for (A, B, C) { #[inline(always)] fn eq(&self, other: &(A, B, C)) -> bool { @@ -219,7 +219,7 @@ impl<A:Eq,B:Eq,C:Eq> Eq for (A, B, C) { fn ne(&self, other: &(A, B, C)) -> bool { !(*self).eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<A:Ord,B:Ord,C:Ord> Ord for (A, B, C) { #[inline(always)] fn lt(&self, other: &(A, B, C)) -> bool { diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs index 4a69de26f6b..25e4d07b01d 100644 --- a/src/libcore/unstable.rs +++ b/src/libcore/unstable.rs @@ -30,10 +30,12 @@ pub mod weak_task; pub mod exchange_alloc; #[path = "unstable/intrinsics.rs"] pub mod intrinsics; +#[path = "unstable/simd.rs"] +pub mod simd; #[path = "unstable/extfmt.rs"] pub mod extfmt; #[path = "unstable/lang.rs"] -#[cfg(notest)] +#[cfg(not(test))] pub mod lang; mod rustrt { @@ -233,17 +235,30 @@ pub impl LittleLock { } } -struct ExData<T> { lock: LittleLock, failed: bool, data: T, } +struct ExData<T> { + lock: LittleLock, + failed: bool, + data: T, +} + /** * An arc over mutable data that is protected by a lock. For library use only. */ -pub struct Exclusive<T> { x: SharedMutableState<ExData<T>> } +pub struct Exclusive<T> { + x: SharedMutableState<ExData<T>> +} pub fn exclusive<T:Owned>(user_data: T) -> Exclusive<T> { let data = ExData { - lock: LittleLock(), failed: false, data: user_data + lock: LittleLock(), + failed: false, + data: user_data }; - Exclusive { x: unsafe { shared_mutable_state(data) } } + Exclusive { + x: unsafe { + shared_mutable_state(data) + } + } } impl<T:Owned> Clone for Exclusive<T> { diff --git a/src/libcore/unstable/at_exit.rs b/src/libcore/unstable/at_exit.rs index bc4ec620aa8..39c930d415f 100644 --- a/src/libcore/unstable/at_exit.rs +++ b/src/libcore/unstable/at_exit.rs @@ -62,14 +62,17 @@ fn exit_runner(exit_fns: *ExitFunctions) { // give us ownership of the array of functions let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) }; // Let's not make any promises about execution order - rand::rng().shuffle_mut(exit_fns_vec); + let mut rng = rand::rng(); + rng.shuffle_mut(exit_fns_vec); debug!("running %u exit functions", exit_fns_vec.len()); while !exit_fns_vec.is_empty() { match exit_fns_vec.pop() { ~f => { - task::task().supervised().spawn(f); + let mut task = task::task(); + task.supervised(); + task.spawn(f); } } } diff --git a/src/libcore/unstable/intrinsics.rs b/src/libcore/unstable/intrinsics.rs index 65cfc6ec1fe..363dbb84c1c 100644 --- a/src/libcore/unstable/intrinsics.rs +++ b/src/libcore/unstable/intrinsics.rs @@ -34,8 +34,8 @@ pub extern "rust-intrinsic" { pub fn size_of<T>() -> uint; - pub fn move_val<T>(dst: &mut T, +src: T); - pub fn move_val_init<T>(dst: &mut T, +src: T); + pub fn move_val<T>(dst: &mut T, src: T); + pub fn move_val_init<T>(dst: &mut T, src: T); pub fn min_align_of<T>() -> uint; pub fn pref_align_of<T>() -> uint; diff --git a/src/libcore/unstable/simd.rs b/src/libcore/unstable/simd.rs new file mode 100644 index 00000000000..a05f6e8af5a --- /dev/null +++ b/src/libcore/unstable/simd.rs @@ -0,0 +1,43 @@ +// 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. + +//! SIMD vectors + +#[allow(non_camel_case_types)]; + +#[simd] +pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8); + +#[simd] +pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); + +#[simd] +pub struct i32x4(i32, i32, i32, i32); + +#[simd] +pub struct i64x2(i64, i64); + +#[simd] +pub struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8); + +#[simd] +pub struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16); + +#[simd] +pub struct u32x4(u32, u32, u32, u32); + +#[simd] +pub struct u64x2(u64, u64); + +#[simd] +pub struct f32x4(f32, f32, f32, f32); + +#[simd] +pub struct f64x2(f64, f64); diff --git a/src/libcore/unstable/weak_task.rs b/src/libcore/unstable/weak_task.rs index 6edbdcb51b0..8670bcfcd9a 100644 --- a/src/libcore/unstable/weak_task.rs +++ b/src/libcore/unstable/weak_task.rs @@ -72,7 +72,9 @@ fn create_global_service() -> ~WeakTaskService { let chan = SharedChan::new(chan); let chan_clone = chan.clone(); - do task().unlinked().spawn { + let mut task = task(); + task.unlinked(); + do task.spawn { debug!("running global weak task service"); let port = Cell(port.take()); do (|| { @@ -189,12 +191,14 @@ fn test_select_stream_and_oneshot() { use comm::select2i; use either::{Left, Right}; - let (port, chan) = stream(); + let mut (port, chan) = stream(); + let port = Cell(port); let (waitport, waitchan) = stream(); do spawn { unsafe { - do weaken_task |signal| { - match select2i(&port, &signal) { + do weaken_task |mut signal| { + let mut port = port.take(); + match select2i(&mut port, &mut signal) { Left(*) => (), Right(*) => fail!() } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index bd8a1c8a156..bf8f5b4ce18 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -30,7 +30,7 @@ use uint; use unstable::intrinsics; use vec; -#[cfg(notest)] use cmp::Equiv; +#[cfg(not(test))] use cmp::Equiv; pub mod rustrt { use libc; @@ -42,13 +42,13 @@ pub mod rustrt { // These names are terrible. reserve_shared applies // to ~[] and reserve_shared_actual applies to @[]. #[fast_ffi] - unsafe fn vec_reserve_shared(++t: *sys::TypeDesc, - ++v: **raw::VecRepr, - ++n: libc::size_t); + unsafe fn vec_reserve_shared(t: *sys::TypeDesc, + v: **raw::VecRepr, + n: libc::size_t); #[fast_ffi] - unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc, - ++v: **raw::VecRepr, - ++n: libc::size_t); + unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + v: **raw::VecRepr, + n: libc::size_t); } } @@ -1656,7 +1656,7 @@ fn equals<T: TotalEq>(a: &[T], b: &[T]) -> bool { true } -#[cfg(notest)] +#[cfg(not(test))] impl<'self,T:Eq> Eq for &'self [T] { #[inline(always)] fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) } @@ -1664,7 +1664,7 @@ impl<'self,T:Eq> Eq for &'self [T] { fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Eq> Eq for ~[T] { #[inline(always)] fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) } @@ -1672,7 +1672,7 @@ impl<T:Eq> Eq for ~[T] { fn ne(&self, other: &~[T]) -> bool { !self.eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Eq> Eq for @[T] { #[inline(always)] fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) } @@ -1680,25 +1680,25 @@ impl<T:Eq> Eq for @[T] { fn ne(&self, other: &@[T]) -> bool { !self.eq(other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<'self,T:TotalEq> TotalEq for &'self [T] { #[inline(always)] fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:TotalEq> TotalEq for ~[T] { #[inline(always)] fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:TotalEq> TotalEq for @[T] { #[inline(always)] fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<'self,T:Eq> Equiv<~[T]> for &'self [T] { #[inline(always)] fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) } @@ -1720,19 +1720,19 @@ fn cmp<T: TotalOrd>(a: &[T], b: &[T]) -> Ordering { a.len().cmp(&b.len()) } -#[cfg(notest)] +#[cfg(not(test))] impl<'self,T:TotalOrd> TotalOrd for &'self [T] { #[inline(always)] fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T: TotalOrd> TotalOrd for ~[T] { #[inline(always)] fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T: TotalOrd> TotalOrd for @[T] { #[inline(always)] fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } @@ -1757,7 +1757,7 @@ fn le<T:Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) } fn ge<T:Ord>(a: &[T], b: &[T]) -> bool { !lt(a, b) } fn gt<T:Ord>(a: &[T], b: &[T]) -> bool { lt(b, a) } -#[cfg(notest)] +#[cfg(not(test))] impl<'self,T:Ord> Ord for &'self [T] { #[inline(always)] fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) } @@ -1769,7 +1769,7 @@ impl<'self,T:Ord> Ord for &'self [T] { fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Ord> Ord for ~[T] { #[inline(always)] fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) } @@ -1781,7 +1781,7 @@ impl<T:Ord> Ord for ~[T] { fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) } } -#[cfg(notest)] +#[cfg(not(test))] impl<T:Ord> Ord for @[T] { #[inline(always)] fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) } @@ -1793,7 +1793,7 @@ impl<T:Ord> Ord for @[T] { fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) } } -#[cfg(notest)] +#[cfg(not(test))] pub mod traits { use kinds::Copy; use ops::Add; diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc index 7c93d867f50..33e970c305a 100644 --- a/src/libfuzzer/fuzzer.rc +++ b/src/libfuzzer/fuzzer.rc @@ -263,7 +263,7 @@ pub fn under(n: uint, it: &fn(uint)) { while i < n { it(i); i += 1u; } } -pub fn as_str(f: @fn(+x: @io::Writer)) -> ~str { +pub fn as_str(f: @fn(x: @io::Writer)) -> ~str { io::with_str_writer(f) } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index c34c7fe303e..3b5c90ec1f9 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -22,9 +22,9 @@ use util::ppaux; use core::hash::Streaming; use core::hash; -use core::io::WriterUtil; use core::libc::{c_int, c_uint}; use core::os::consts::{macos, freebsd, linux, android, win32}; +use core::rt::io::Writer; use core::run; use syntax::ast; use syntax::ast_map::{path, path_mod, path_name}; @@ -41,6 +41,11 @@ pub enum output_type { output_type_exe, } +fn write_string<W:Writer>(writer: &mut W, string: &str) { + let buffer = str::as_bytes_slice(string); + writer.write(buffer); +} + pub fn llvm_err(sess: Session, msg: ~str) -> ! { unsafe { let cstr = llvm::LLVMRustGetLastError(); @@ -458,9 +463,11 @@ pub mod write { * */ -pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, - symbol_hasher: &hash::State) -> LinkMeta { - +pub fn build_link_meta(sess: Session, + c: &ast::crate, + output: &Path, + symbol_hasher: &mut hash::State) + -> LinkMeta { struct ProvidedMetas { name: Option<@str>, vers: Option<@str>, @@ -498,7 +505,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, } // This calculates CMH as defined above - fn crate_meta_extras_hash(symbol_hasher: &hash::State, + fn crate_meta_extras_hash(symbol_hasher: &mut hash::State, cmh_items: ~[@ast::meta_item], dep_hashes: ~[~str]) -> @str { fn len_and_str(s: &str) -> ~str { @@ -511,17 +518,17 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, let cmh_items = attr::sort_meta_items(cmh_items); - fn hash(symbol_hasher: &hash::State, m: &@ast::meta_item) { + fn hash(symbol_hasher: &mut hash::State, m: &@ast::meta_item) { match m.node { ast::meta_name_value(key, value) => { - symbol_hasher.write_str(len_and_str(*key)); - symbol_hasher.write_str(len_and_str_lit(value)); + write_string(symbol_hasher, len_and_str(*key)); + write_string(symbol_hasher, len_and_str_lit(value)); } ast::meta_word(name) => { - symbol_hasher.write_str(len_and_str(*name)); + write_string(symbol_hasher, len_and_str(*name)); } ast::meta_list(name, ref mis) => { - symbol_hasher.write_str(len_and_str(*name)); + write_string(symbol_hasher, len_and_str(*name)); for mis.each |m_| { hash(symbol_hasher, m_); } @@ -535,7 +542,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, } for dep_hashes.each |dh| { - symbol_hasher.write_str(len_and_str(*dh)); + write_string(symbol_hasher, len_and_str(*dh)); } // tjc: allocation is unfortunate; need to change core::hash @@ -596,23 +603,26 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, } } -pub fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str { +pub fn truncated_hash_result(symbol_hasher: &mut hash::State) -> ~str { symbol_hasher.result_str() } // This calculates STH for a symbol, as defined above -pub fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t, - link_meta: LinkMeta) -> @str { +pub fn symbol_hash(tcx: ty::ctxt, + symbol_hasher: &mut hash::State, + t: ty::t, + link_meta: LinkMeta) + -> @str { // NB: do *not* use abbrevs here as we want the symbol names // to be independent of one another in the crate. symbol_hasher.reset(); - symbol_hasher.write_str(link_meta.name); - symbol_hasher.write_str(~"-"); - symbol_hasher.write_str(link_meta.extras_hash); - symbol_hasher.write_str(~"-"); - symbol_hasher.write_str(encoder::encoded_ty(tcx, t)); + write_string(symbol_hasher, link_meta.name); + write_string(symbol_hasher, ~"-"); + write_string(symbol_hasher, link_meta.extras_hash); + write_string(symbol_hasher, ~"-"); + write_string(symbol_hasher, encoder::encoded_ty(tcx, t)); let mut hash = truncated_hash_result(symbol_hasher); // Prefix with _ so that it never blends into adjacent digits str::unshift_char(&mut hash, '_'); diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index 8fcc5234e8b..4d2ea4eb4a6 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -34,9 +34,9 @@ pub fn declare_upcalls(targ_cfg: @session::config, fn nothrow(f: ValueRef) -> ValueRef { base::set_no_unwind(f); f } - let d: &fn(+a: ~str, +b: ~[TypeRef], +c: TypeRef) -> ValueRef = + let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef = |a,b,c| decl(llmod, ~"upcall_", a, b, c); - let dv: &fn(+a: ~str, +b: ~[TypeRef]) -> ValueRef = + let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef = |a,b| decl(llmod, ~"upcall_", a, b, T_void()); let int_t = T_int(targ_cfg); diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 5e8dab0f772..cf77f81a492 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -119,9 +119,8 @@ pub fn build_configuration(sess: Session, argv0: @~str, input: &input) -> let default_cfg = default_configuration(sess, argv0, input); let user_cfg = /*bad*/copy sess.opts.cfg; // If the user wants a test runner, then add the test cfg - let user_cfg = append_configuration( - user_cfg, - if sess.opts.test { ~"test" } else { ~"notest" }); + let user_cfg = if sess.opts.test { append_configuration(user_cfg, ~"test") } + else { user_cfg }; // If the user requested GC, then add the GC cfg let user_cfg = append_configuration( user_cfg, @@ -225,6 +224,9 @@ pub fn compile_rest(sess: Session, time(time_passes, ~"resolution", || middle::resolve::resolve_crate(sess, lang_items, crate)); + time(time_passes, ~"looking for entry point", + || middle::entry::find_entry_point(sess, crate, ast_map)); + let freevars = time(time_passes, ~"freevar finding", || freevars::annotate_freevars(def_map, crate)); diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs index 452623c2742..ece53451ccf 100644 --- a/src/librustc/front/intrinsic.rs +++ b/src/librustc/front/intrinsic.rs @@ -132,7 +132,7 @@ pub mod intrinsic { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { pub fn get_tydesc<T>() -> *(); - pub fn visit_tydesc(++td: *TyDesc, ++tv: @TyVisitor); + pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); } } } diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index fbb3380554d..36d5a8e3cfe 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1561,12 +1561,18 @@ pub mod llvm { Name: *c_char) -> ValueRef; /* Atomic Operations */ - pub unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef, - CMP: ValueRef, RHS: ValueRef, - ++Order: AtomicOrdering) -> ValueRef; - pub unsafe fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp, - LHS: ValueRef, RHS: ValueRef, - ++Order: AtomicOrdering) -> ValueRef; + pub unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef, + LHS: ValueRef, + CMP: ValueRef, + RHS: ValueRef, + Order: AtomicOrdering) + -> ValueRef; + pub unsafe fn LLVMBuildAtomicRMW(B: BuilderRef, + Op: AtomicBinOp, + LHS: ValueRef, + RHS: ValueRef, + Order: AtomicOrdering) + -> ValueRef; /* Selected entries from the downcasts. */ #[fast_ffi] diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 1e6bb397068..fd35a4425d8 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -204,18 +204,6 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) { } } -fn field_mutability(d: ebml::Doc) -> ast::struct_mutability { - // Use maybe_get_doc in case it's a method - reader::maybe_get_doc(d, tag_struct_mut).map_default( - ast::struct_immutable, - |d| { - match reader::doc_as_u8(*d) as char { - 'm' => ast::struct_mutable, - _ => ast::struct_immutable - } - }) -} - fn variant_disr_val(d: ebml::Doc) -> Option<int> { do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| { int::parse_bytes(reader::doc_data(val_doc), 10u) @@ -923,12 +911,10 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id) if f == PublicField || f == PrivateField || f == InheritedField { let name = item_name(intr, an_item); let did = item_def_id(an_item, cdata); - let mt = field_mutability(an_item); result.push(ty::field_ty { ident: name, id: did, vis: struct_field_family_to_visibility(f), - mutability: mt, }); } } @@ -938,7 +924,6 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id) ident: special_idents::unnamed_field, id: did, vis: ast::inherited, - mutability: ast::struct_immutable, }); } result diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index ccf3ffcdfff..6c02ece9289 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -119,16 +119,6 @@ fn encode_region_param(ecx: @EncodeContext, } } -fn encode_mutability(ebml_w: &mut writer::Encoder, mt: struct_mutability) { - ebml_w.start_tag(tag_struct_mut); - let val = match mt { - struct_immutable => 'a', - struct_mutable => 'm' - }; - ebml_w.writer.write(&[val as u8]); - ebml_w.end_tag(); -} - struct entry<T> { val: T, pos: uint @@ -518,13 +508,9 @@ fn encode_info_for_struct(ecx: @EncodeContext, /* We encode both private and public fields -- need to include private fields to get the offsets right */ for fields.each |field| { - let (nm, mt, vis) = match field.node.kind { - named_field(nm, mt, vis) => (nm, mt, vis), - unnamed_field => ( - special_idents::unnamed_field, - struct_immutable, - inherited - ) + let (nm, vis) = match field.node.kind { + named_field(nm, vis) => (nm, vis), + unnamed_field => (special_idents::unnamed_field, inherited) }; let id = field.node.id; @@ -537,7 +523,6 @@ fn encode_info_for_struct(ecx: @EncodeContext, encode_name(ecx, ebml_w, nm); encode_path(ecx, ebml_w, path, ast_map::path_name(nm)); encode_type(ecx, ebml_w, node_id_to_type(tcx, id)); - encode_mutability(ebml_w, mt); encode_def_id(ebml_w, local_def(id)); ebml_w.end_tag(); } @@ -828,7 +813,7 @@ fn encode_info_for_item(ecx: @EncodeContext, needs to know*/ for struct_def.fields.each |f| { match f.node.kind { - named_field(ident, _, vis) => { + named_field(ident, vis) => { ebml_w.start_tag(tag_item_field); encode_struct_field_family(ebml_w, vis); encode_name(ecx, ebml_w, ident); @@ -1099,7 +1084,7 @@ fn encode_index<T>(ebml_w: &mut writer::Encoder, for buckets.each |bucket| { bucket_locs.push(ebml_w.writer.tell()); ebml_w.start_tag(tag_index_buckets_bucket); - for vec::each(**bucket) |elt| { + for (**bucket).each |elt| { ebml_w.start_tag(tag_index_buckets_bucket_elt); assert!(elt.pos < 0xffff_ffff); writer.write_be_u32(elt.pos as u32); @@ -1372,41 +1357,40 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { encode_hash(&mut ebml_w, ecx.link_meta.extras_hash); - let mut i = wr.pos; + let mut i = *wr.pos; let crate_attrs = synthesize_crate_attrs(ecx, crate); encode_attributes(&mut ebml_w, crate_attrs); - ecx.stats.attr_bytes = wr.pos - i; + ecx.stats.attr_bytes = *wr.pos - i; - i = wr.pos; + i = *wr.pos; encode_crate_deps(ecx, &mut ebml_w, ecx.cstore); - ecx.stats.dep_bytes = wr.pos - i; + ecx.stats.dep_bytes = *wr.pos - i; // Encode the language items. - i = wr.pos; + i = *wr.pos; encode_lang_items(ecx, &mut ebml_w); - ecx.stats.lang_item_bytes = wr.pos - i; + ecx.stats.lang_item_bytes = *wr.pos - i; // Encode the link args. - i = wr.pos; + i = *wr.pos; encode_link_args(ecx, &mut ebml_w); - ecx.stats.link_args_bytes = wr.pos - i; + ecx.stats.link_args_bytes = *wr.pos - i; // Encode and index the items. ebml_w.start_tag(tag_items); - i = wr.pos; + i = *wr.pos; let items_index = encode_info_for_items(ecx, &mut ebml_w, crate); - ecx.stats.item_bytes = wr.pos - i; + ecx.stats.item_bytes = *wr.pos - i; - i = wr.pos; + i = *wr.pos; let items_buckets = create_index(items_index); encode_index(&mut ebml_w, items_buckets, write_int); - ecx.stats.index_bytes = wr.pos - i; + ecx.stats.index_bytes = *wr.pos - i; ebml_w.end_tag(); - ecx.stats.total_bytes = wr.pos; + ecx.stats.total_bytes = *wr.pos; if (tcx.sess.meta_stats()) { - do wr.bytes.each |e| { if *e == 0 { ecx.stats.zero_bytes += 1; @@ -1438,9 +1422,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { // // vec::from_slice(metadata_encoding_version) + + let writer_bytes: &mut ~[u8] = wr.bytes; + (do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| { vec::slice(*bytes, 0, 8).to_vec() - }) + flate::deflate_bytes(wr.bytes) + }) + flate::deflate_bytes(*writer_bytes) } // Get the encoded string for a type diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index c44a8e74130..3abe5b22e1a 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -17,7 +17,6 @@ use core::hashmap::HashMap; use core::io::WriterUtil; use core::io; use core::uint; -use core::vec; use syntax::abi::AbiSet; use syntax::ast; use syntax::ast::*; @@ -398,7 +397,7 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) { } fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) { - for vec::each(*bs) |bound| { + for (*bs).each |bound| { match *bound { ty::bound_owned => w.write_char('S'), ty::bound_copy => w.write_char('C'), diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index f3eac7995e8..c223ff821c2 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1237,7 +1237,7 @@ fn test_simplification() { let ext_cx = mk_ctxt(); let item_in = ast::ii_item(quote_item!( fn new_int_alist<B:Copy>() -> alist<int, B> { - fn eq_int(&&a: int, &&b: int) -> bool { a == b } + fn eq_int(a: int, b: int) -> bool { a == b } return alist {eq_fn: eq_int, data: ~[]}; } ).get()); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index a50895aa013..09232b5bba8 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -366,7 +366,7 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, } let variants = ty::enum_variants(cx.tcx, eid); if found.len() != (*variants).len() { - for vec::each(*variants) |v| { + for (*variants).each |v| { if !found.contains(&(variant(v.id))) { return Some(variant(v.id)); } diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs new file mode 100644 index 00000000000..9ffd0e6f22c --- /dev/null +++ b/src/librustc/middle/entry.rs @@ -0,0 +1,150 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use driver::session; +use driver::session::Session; +use syntax::parse::token::special_idents; +use syntax::ast::{crate, node_id, item, item_fn}; +use syntax::codemap::span; +use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item}; +use syntax::attr::{attrs_contains_name}; +use syntax::ast_map; +use core::util; + +struct EntryContext { + session: Session, + + ast_map: ast_map::map, + + // The top-level function called 'main' + main_fn: Option<(node_id, span)>, + + // The function that has attribute named 'main' + attr_main_fn: Option<(node_id, span)>, + + // The function that has the attribute 'start' on it + start_fn: Option<(node_id, span)>, + + // The functions that one might think are 'main' but aren't, e.g. + // main functions not defined at the top level. For diagnostics. + non_main_fns: ~[(node_id, span)], +} + +type EntryVisitor = vt<@mut EntryContext>; + +pub fn find_entry_point(session: Session, crate: @crate, ast_map: ast_map::map) { + + // FIXME #4404 android JNI hacks + if *session.building_library && + session.targ_cfg.os != session::os_android { + // No need to find a main function + return; + } + + let ctxt = @mut EntryContext { + session: session, + ast_map: ast_map, + main_fn: None, + attr_main_fn: None, + start_fn: None, + non_main_fns: ~[], + }; + + visit_crate(crate, ctxt, mk_vt(@Visitor { + visit_item: |item, ctxt, visitor| find_item(item, ctxt, visitor), + .. *default_visitor() + })); + + configure_main(ctxt); +} + +fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) { + match item.node { + item_fn(*) => { + if item.ident == special_idents::main { + match ctxt.ast_map.find(&item.id) { + Some(&ast_map::node_item(_, path)) => { + if path.len() == 0 { + // This is a top-level function so can be 'main' + if ctxt.main_fn.is_none() { + ctxt.main_fn = Some((item.id, item.span)); + } else { + ctxt.session.span_err( + item.span, + ~"multiple 'main' functions"); + } + } else { + // This isn't main + ctxt.non_main_fns.push((item.id, item.span)); + } + } + _ => util::unreachable() + } + } + + if attrs_contains_name(item.attrs, ~"main") { + if ctxt.attr_main_fn.is_none() { + ctxt.attr_main_fn = Some((item.id, item.span)); + } else { + ctxt.session.span_err( + item.span, + ~"multiple 'main' functions"); + } + } + + if attrs_contains_name(item.attrs, ~"start") { + if ctxt.start_fn.is_none() { + ctxt.start_fn = Some((item.id, item.span)); + } else { + ctxt.session.span_err( + item.span, + ~"multiple 'start' functions"); + } + } + } + _ => () + } + + visit_item(item, ctxt, visitor); +} + +fn configure_main(ctxt: @mut EntryContext) { + let this = &mut *ctxt; + if this.start_fn.is_some() { + *this.session.entry_fn = this.start_fn; + *this.session.entry_type = Some(session::EntryStart); + } else if this.attr_main_fn.is_some() { + *this.session.entry_fn = this.attr_main_fn; + *this.session.entry_type = Some(session::EntryMain); + } else if this.main_fn.is_some() { + *this.session.entry_fn = this.main_fn; + *this.session.entry_type = Some(session::EntryMain); + } else { + if !*this.session.building_library { + // No main function + this.session.err(~"main function not found"); + if !this.non_main_fns.is_empty() { + // There were some functions named 'main' though. Try to give the user a hint. + this.session.note(~"the main function must be defined at the crate level \ + but you have one or more functions named 'main' that are not \ + defined at the crate level. Either move the definition or \ + attach the `#[main]` attribute to override this behavior."); + for this.non_main_fns.each |&(_, span)| { + this.session.span_note(span, ~"here is a function named 'main'"); + } + } + this.session.abort_if_errors(); + } else { + // If we *are* building a library, then we're on android where we still might + // optionally want to translate main $4404 + assert!(this.session.targ_cfg.os == session::os_android); + } + } +} diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 57c3e7c3b9a..0050e0f81c7 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -235,7 +235,7 @@ fn check_fn( } fn check_arm(a: &arm, cx: Context, v: visit::vt<Context>) { - for vec::each(a.pats) |p| { + for a.pats.each |p| { do pat_util::pat_bindings(cx.tcx.def_map, *p) |mode, id, span, _pth| { if mode == bind_by_copy { let t = ty::node_id_to_type(cx.tcx, id); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 9ca1cc9b924..b3bd60d8ac7 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -56,7 +56,6 @@ pub enum lint { non_camel_case_types, type_limits, default_methods, - deprecated_mutable_fields, unused_unsafe, managed_heap_memory, @@ -197,13 +196,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ default: deny }), - ("deprecated_mutable_fields", - LintSpec { - lint: deprecated_mutable_fields, - desc: "deprecated mutable fields in structures", - default: deny - }), - ("unused_unsafe", LintSpec { lint: unused_unsafe, @@ -455,7 +447,6 @@ fn check_item(i: @ast::item, cx: ty::ctxt) { check_item_heap(cx, i); check_item_type_limits(cx, i); check_item_default_methods(cx, i); - check_item_deprecated_mutable_fields(cx, i); check_item_unused_unsafe(cx, i); check_item_unused_mut(cx, i); } @@ -640,28 +631,7 @@ fn check_item_default_methods(cx: ty::ctxt, item: @ast::item) { } } -fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) { - match item.node { - ast::item_struct(struct_def, _) => { - for struct_def.fields.each |field| { - match field.node.kind { - ast::named_field(_, ast::struct_mutable, _) => { - cx.sess.span_lint(deprecated_mutable_fields, - item.id, - item.id, - field.span, - "mutable fields are deprecated"); - } - ast::named_field(*) | ast::unnamed_field => {} - } - } - } - _ => {} - } -} - fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) { - fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id, decl: &ast::fn_decl) { let tys = vec::map(decl.inputs, |a| a.ty ); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index dde4c044792..26992388b29 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -581,17 +581,7 @@ pub impl mem_categorization_ctxt { f_name: ast::ident, f_ty: ty::t, field_id: ast::node_id) -> cmt { - let f_mutbl = match field_mutbl(self.tcx, base_cmt.ty, - f_name, field_id) { - Some(f_mutbl) => f_mutbl, - None => { - self.tcx.sess.span_bug( - node.span(), - fmt!("Cannot find field `%s` in type `%s`", - *self.tcx.sess.str_of(f_name), - ty_to_str(self.tcx, base_cmt.ty))); - } - }; + let f_mutbl = m_imm; let m = self.inherited_mutability(base_cmt.mutbl, f_mutbl); let f_interior = interior_field(f_name, f_mutbl); @cmt_ { @@ -968,11 +958,7 @@ pub fn field_mutbl(tcx: ty::ctxt, ty::ty_struct(did, _) => { for ty::lookup_struct_fields(tcx, did).each |fld| { if fld.ident == f_name { - let m = match fld.mutability { - ast::struct_mutable => ast::m_mutbl, - ast::struct_immutable => ast::m_imm - }; - return Some(m); + return Some(ast::m_imm); } } } @@ -981,11 +967,7 @@ pub fn field_mutbl(tcx: ty::ctxt, ast::def_variant(_, variant_id) => { for ty::lookup_struct_fields(tcx, variant_id).each |fld| { if fld.ident == f_name { - let m = match fld.mutability { - ast::struct_mutable => ast::m_mutbl, - ast::struct_immutable => ast::m_imm - }; - return Some(m); + return Some(ast::m_imm); } } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index cdc3aa9fedb..76d35527104 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -894,17 +894,7 @@ pub fn determine_rp_in_struct_field( cm: @ast::struct_field, cx: @mut DetermineRpCtxt, visitor: visit::vt<@mut DetermineRpCtxt>) { - match cm.node.kind { - ast::named_field(_, ast::struct_mutable, _) => { - do cx.with_ambient_variance(rv_invariant) { - visit::visit_struct_field(cm, cx, visitor); - } - } - ast::named_field(_, ast::struct_immutable, _) | - ast::unnamed_field => { - visit::visit_struct_field(cm, cx, visitor); - } - } + visit::visit_struct_field(cm, cx, visitor); } pub fn determine_rp_in_crate(sess: Session, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 946bf26fd27..5c3bb6ca401 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use driver::session; use driver::session::Session; use metadata::csearch::{each_path, get_trait_method_def_ids}; use metadata::csearch::get_method_name_and_self_ty; @@ -794,11 +793,6 @@ pub fn Resolver(session: Session, namespaces: ~[ TypeNS, ValueNS ], - attr_main_fn: None, - main_fns: ~[], - - start_fn: None, - def_map: @mut HashMap::new(), export_map2: @mut HashMap::new(), trait_map: HashMap::new(), @@ -856,15 +850,6 @@ pub struct Resolver { // The four namespaces. namespaces: ~[Namespace], - // The function that has attribute named 'main' - attr_main_fn: Option<(node_id, span)>, - - // The functions that could be main functions - main_fns: ~[Option<(node_id, span)>], - - // The function that has the attribute 'start' on it - start_fn: Option<(node_id, span)>, - def_map: DefMap, export_map2: ExportMap2, trait_map: TraitMap, @@ -885,7 +870,6 @@ pub impl Resolver { self.resolve_crate(); self.session.abort_if_errors(); - self.check_duplicate_main(); self.check_for_unused_imports_if_necessary(); } @@ -3544,40 +3528,6 @@ pub impl Resolver { } item_fn(ref fn_decl, _, _, ref generics, ref block) => { - // If this is the main function, we must record it in the - // session. - - // FIXME #4404 android JNI hacks - if !*self.session.building_library || - self.session.targ_cfg.os == session::os_android { - - if self.attr_main_fn.is_none() && - item.ident == special_idents::main { - - self.main_fns.push(Some((item.id, item.span))); - } - - if attrs_contains_name(item.attrs, ~"main") { - if self.attr_main_fn.is_none() { - self.attr_main_fn = Some((item.id, item.span)); - } else { - self.session.span_err( - item.span, - ~"multiple 'main' functions"); - } - } - - if attrs_contains_name(item.attrs, ~"start") { - if self.start_fn.is_none() { - self.start_fn = Some((item.id, item.span)); - } else { - self.session.span_err( - item.span, - ~"multiple 'start' functions"); - } - } - } - self.resolve_function(OpaqueFunctionRibKind, Some(fn_decl), HasTypeParameters @@ -4680,7 +4630,7 @@ pub impl Resolver { } let mut smallest = 0; - for vec::eachi(maybes) |i, &other| { + for maybes.eachi |i, &other| { values[i] = str::levdistance(name, other); @@ -4714,10 +4664,10 @@ pub impl Resolver { if item.id == node_id { match item.node { item_struct(class_def, _) => { - for vec::each(class_def.fields) |field| { + for class_def.fields.each |field| { match field.node.kind { unnamed_field => {}, - named_field(ident, _, _) => { + named_field(ident, _) => { if str::eq_slice(*this.session.str_of(ident), name) { return true @@ -5090,35 +5040,6 @@ pub impl Resolver { } // - // main function checking - // - // be sure that there is only one main function - // - fn check_duplicate_main(@mut self) { - let this = &mut *self; - if this.attr_main_fn.is_none() && this.start_fn.is_none() { - if this.main_fns.len() >= 1u { - let mut i = 1u; - while i < this.main_fns.len() { - let (_, dup_main_span) = this.main_fns[i].unwrap(); - this.session.span_err( - dup_main_span, - ~"multiple 'main' functions"); - i += 1; - } - *this.session.entry_fn = this.main_fns[0]; - *this.session.entry_type = Some(session::EntryMain); - } - } else if !this.start_fn.is_none() { - *this.session.entry_fn = this.start_fn; - *this.session.entry_type = Some(session::EntryStart); - } else { - *this.session.entry_fn = this.attr_main_fn; - *this.session.entry_type = Some(session::EntryMain); - } - } - - // // Unused import checking // // Although this is a lint pass, it lives in here because it depends on diff --git a/src/librustc/middle/resolve_stage0.rs b/src/librustc/middle/resolve_stage0.rs index 2773710ca98..3a6424efe1d 100644 --- a/src/librustc/middle/resolve_stage0.rs +++ b/src/librustc/middle/resolve_stage0.rs @@ -4681,7 +4681,7 @@ pub impl Resolver { } let mut smallest = 0; - for vec::eachi(maybes) |i, &other| { + for maybes.eachi |i, &other| { values[i] = str::levdistance(name, other); @@ -4715,10 +4715,10 @@ pub impl Resolver { if item.id == node_id { match item.node { item_struct(class_def, _) => { - for vec::each(class_def.fields) |field| { + for class_def.fields.each |field| { match field.node.kind { unnamed_field => {}, - named_field(ident, _, _) => { + named_field(ident, _) => { if str::eq_slice(*this.session.str_of(ident), name) { return true diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index d074a2f796f..1443a7ef304 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -283,7 +283,7 @@ pub fn variant_opt(bcx: block, pat_id: ast::node_id) match ccx.tcx.def_map.get_copy(&pat_id) { ast::def_variant(enum_id, var_id) => { let variants = ty::enum_variants(ccx.tcx, enum_id); - for vec::each(*variants) |v| { + for (*variants).each |v| { if var_id == v.id { return var(v.disr_val, adt::represent_node(bcx, pat_id)) @@ -349,7 +349,7 @@ pub fn matches_to_str(bcx: block, m: &[@Match]) -> ~str { } pub fn has_nested_bindings(m: &[@Match], col: uint) -> bool { - for vec::each(m) |br| { + for m.each |br| { match br.pats[col].node { ast::pat_ident(_, _, Some(_)) => return true, _ => () @@ -418,7 +418,7 @@ pub fn enter_match<'r>(bcx: block, let _indenter = indenter(); let mut result = ~[]; - for vec::each(m) |br| { + for m.each |br| { match e(br.pats[col]) { Some(sub) => { let pats = @@ -934,7 +934,7 @@ pub fn collect_record_or_struct_fields(bcx: block, col: uint) -> ~[ast::ident] { let mut fields: ~[ast::ident] = ~[]; - for vec::each(m) |br| { + for m.each |br| { match br.pats[col].node { ast::pat_struct(_, ref fs, _) => { match ty::get(node_id_type(bcx, br.pats[col].id)).sty { @@ -973,7 +973,7 @@ pub fn root_pats_as_necessary(mut bcx: block, col: uint, val: ValueRef) -> block { - for vec::each(m) |br| { + for m.each |br| { let pat_id = br.pats[col].id; if pat_id != 0 { let datum = Datum {val: val, ty: node_id_type(bcx, pat_id), @@ -1042,14 +1042,14 @@ pub fn pick_col(m: &[@Match]) -> uint { } } let mut scores = vec::from_elem(m[0].pats.len(), 0u); - for vec::each(m) |br| { + for m.each |br| { let mut i = 0u; - for vec::each(br.pats) |p| { scores[i] += score(*p); i += 1u; } + for br.pats.each |p| { scores[i] += score(*p); i += 1u; } } let mut max_score = 0u; let mut best_col = 0u; let mut i = 0u; - for vec::each(scores) |score| { + for scores.each |score| { let score = *score; // Irrefutable columns always go first, they'd only be duplicated in @@ -1306,7 +1306,7 @@ pub fn compile_submatch(bcx: block, let ccx = *bcx.fcx.ccx; let mut pat_id = 0; let mut pat_span = dummy_sp(); - for vec::each(m) |br| { + for m.each |br| { // Find a real id (we're adding placeholder wildcard patterns, but // each column is guaranteed to have at least one real pattern) if pat_id == 0 { @@ -1438,7 +1438,7 @@ pub fn compile_submatch(bcx: block, } } } - for vec::each(opts) |o| { + for opts.each |o| { match *o { range(_, _) => { kind = compare; break } _ => () @@ -1460,7 +1460,7 @@ pub fn compile_submatch(bcx: block, let mut i = 0u; // Compile subtrees for each option - for vec::each(opts) |opt| { + for opts.each |opt| { i += 1u; let mut opt_cx = else_cx; if !exhaustive || i < len { @@ -1631,7 +1631,7 @@ pub fn trans_match_inner(scope_cx: block, } let mut arm_datas = ~[], matches = ~[]; - for vec::each(arms) |arm| { + for arms.each |arm| { let body = scope_block(bcx, arm.body.info(), ~"case_body"); // Create the bindings map, which is a mapping from each binding name @@ -1670,7 +1670,7 @@ pub fn trans_match_inner(scope_cx: block, arm: arm, bindings_map: bindings_map}; arm_datas.push(arm_data); - for vec::each(arm.pats) |p| { + for arm.pats.each |p| { matches.push(@Match {pats: ~[*p], data: arm_data}); } } @@ -1793,7 +1793,7 @@ pub fn bind_irrefutable_pat(bcx: block, vinfo.disr_val, val); for sub_pats.each |sub_pat| { - for vec::eachi(args.vals) |i, argval| { + for args.vals.eachi |i, argval| { bcx = bind_irrefutable_pat(bcx, sub_pat[i], *argval, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 34f798ec7a6..77a90e22150 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -668,7 +668,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, ty::ty_struct(*) => { let repr = adt::represent_type(cx.ccx(), t); do expr::with_field_tys(cx.tcx(), t, None) |discr, field_tys| { - for vec::eachi(field_tys) |i, field_ty| { + for field_tys.eachi |i, field_ty| { let llfld_a = adt::trans_field_ptr(cx, repr, av, discr, i); cx = f(cx, llfld_a, field_ty.mt.ty); } @@ -709,7 +709,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, n_variants); let next_cx = sub_block(cx, ~"enum-iter-next"); - for vec::each(*variants) |variant| { + for (*variants).each |variant| { let variant_cx = sub_block(cx, ~"enum-iter-variant-" + int::to_str(variant.disr_val)); @@ -888,7 +888,7 @@ pub fn need_invoke(bcx: block) -> bool { match cur.kind { block_scope(inf) => { let inf = &mut *inf; // FIXME(#5074) workaround old borrowck - for vec::each(inf.cleanups) |cleanup| { + for inf.cleanups.each |cleanup| { match *cleanup { clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => { if cleanup_type == normal_exit_and_unwind { @@ -1391,7 +1391,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option<NodeInfo>, } pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { - for vec::each(b.node.stmts) |s| { + for b.node.stmts.each |s| { match s.node { ast::stmt_decl(d, _) => { match d.node { @@ -1973,7 +1973,7 @@ pub fn trans_enum_variant(ccx: @CrateContext, repr, ty_to_str(ccx.tcx, enum_ty)); adt::trans_start_init(bcx, repr, fcx.llretptr.get(), disr); - for vec::eachi(args) |i, va| { + for args.eachi |i, va| { let lldestptr = adt::trans_field_ptr(bcx, repr, fcx.llretptr.get(), @@ -2072,7 +2072,7 @@ pub fn trans_tuple_struct(ccx: @CrateContext, pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::enum_def, id: ast::node_id, vi: @~[ty::VariantInfo], i: &mut uint) { - for vec::each(enum_definition.variants) |variant| { + for enum_definition.variants.each |variant| { let disr_val = vi[*i].disr_val; *i += 1; @@ -2559,7 +2559,7 @@ pub fn trans_constant(ccx: @CrateContext, it: @ast::item) { node: it.id }); let mut i = 0; let path = item_path(ccx, it); - for vec::each((*enum_definition).variants) |variant| { + for (*enum_definition).variants.each |variant| { let p = vec::append(/*bad*/copy path, ~[ path_name(variant.node.name), path_name(special_idents::descrim) @@ -2987,9 +2987,8 @@ pub fn trans_crate(sess: session::Session, emap2: resolve::ExportMap2, maps: astencode::Maps) -> (ModuleRef, LinkMeta) { - let symbol_hasher = @hash::default_state(); - let link_meta = - link::build_link_meta(sess, crate, output, symbol_hasher); + let symbol_hasher = @mut hash::default_state(); + let link_meta = link::build_link_meta(sess, crate, output, symbol_hasher); let reachable = reachable::find_reachable( &crate.node.module, emap2, diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index c3dc4f1e8eb..29fd90edce8 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -963,20 +963,28 @@ pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> } pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef, - Index: ValueRef) { + Index: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return; } + if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } count_insn(cx, "insertelement"); - llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname()); + llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname()) } } pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, - Mask: ValueRef) { + Mask: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return; } + if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } count_insn(cx, "shufflevector"); - llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()); + llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()) + } +} + +pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef { + unsafe { + let Undef = llvm::LLVMGetUndef(T_vector(val_ty(EltVal), NumElts)); + let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0)); + ShuffleVector(cx, VecVal, Undef, C_null(T_vector(T_i32(), NumElts))) } } diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index ecde50f3470..4da2199501f 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -161,7 +161,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { cls: &mut [x86_64_reg_class], i: uint, off: uint) { let mut field_off = off; - for vec::each(tys) |ty| { + for tys.each |ty| { field_off = align(field_off, *ty); classify(*ty, cls, i, field_off); field_off += ty_size(*ty); @@ -283,7 +283,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef { fn llvec_len(cls: &[x86_64_reg_class]) -> uint { let mut len = 1u; - for vec::each(cls) |c| { + for cls.each |c| { if *c != sseup_class { break; } @@ -370,7 +370,7 @@ fn x86_64_tys(atys: &[TypeRef], let mut arg_tys = ~[]; let mut attrs = ~[]; - for vec::each(atys) |t| { + for atys.each |t| { let (ty, attr) = x86_64_ty(*t, is_pass_byval, ByValAttribute); arg_tys.push(ty); attrs.push(attr); diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 87322393ab9..e5e60b2d4ac 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -631,7 +631,7 @@ pub fn trans_args(cx: block, match args { ArgExprs(arg_exprs) => { let last = arg_exprs.len() - 1u; - for vec::eachi(arg_exprs) |i, arg_expr| { + for arg_exprs.eachi |i, arg_expr| { let arg_val = unpack_result!(bcx, { trans_arg_expr(bcx, arg_tys[i], diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 442b5d25c8b..c1309b42288 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -207,7 +207,7 @@ pub struct CrateContext { adt_reprs: @mut HashMap<ty::t, @adt::Repr>, names: namegen, next_addrspace: addrspace_gen, - symbol_hasher: @hash::State, + symbol_hasher: @mut hash::State, type_hashcodes: @mut HashMap<ty::t, @str>, type_short_names: @mut HashMap<ty::t, ~str>, all_llvm_symbols: @mut HashSet<@~str>, @@ -984,6 +984,12 @@ pub fn T_array(t: TypeRef, n: uint) -> TypeRef { } } +pub fn T_vector(t: TypeRef, n: uint) -> TypeRef { + unsafe { + return llvm::LLVMVectorType(t, n as c_uint); + } +} + // Interior vector. pub fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef { return T_struct(~[T_int(targ_cfg), // fill diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index f1192488bdd..8b72ddda044 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -34,7 +34,7 @@ pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block { do block_locals(b) |local| { bcx = alloc_local(bcx, local); }; - for vec::each(b.node.stmts) |s| { + for b.node.stmts.each |s| { debuginfo::update_source_pos(bcx, b.span); bcx = trans_stmt(bcx, *s); } @@ -107,7 +107,7 @@ pub fn trans_if(bcx: block, pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block { let out = sub_block(parent_bcx, ~"join"); let mut reachable = false; - for vec::each(in_cxs) |bcx| { + for in_cxs.each |bcx| { if !bcx.unreachable { Br(*bcx, out.llbb); reachable = true; diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 2c59d5c6bd6..29227b7c95a 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -120,14 +120,14 @@ lvalues are *never* stored by value. */ use back::abi; -use lib; use lib::llvm::{ValueRef, TypeRef, llvm}; +use lib; use metadata::csearch; use middle::trans::_match; use middle::trans::adt; use middle::trans::asm; -use middle::trans::base; use middle::trans::base::*; +use middle::trans::base; use middle::trans::build::*; use middle::trans::callee::DoAutorefArg; use middle::trans::callee; @@ -142,8 +142,10 @@ use middle::trans::machine; use middle::trans::meth; use middle::trans::tvec; use middle::trans::type_of; +use middle::ty::struct_fields; +use middle::ty::{AutoDerefRef, AutoAddEnv}; +use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn}; use middle::ty; -use middle::ty::struct_mutable_fields; use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn, AutoDerefRef, AutoAddEnv, AutoUnsafe}; use util::common::indenter; @@ -1107,7 +1109,7 @@ pub fn with_field_tys<R>(tcx: ty::ctxt, op: &fn(int, (&[ty::field])) -> R) -> R { match ty::get(ty).sty { ty::ty_struct(did, ref substs) => { - op(0, struct_mutable_fields(tcx, did, substs)) + op(0, struct_fields(tcx, did, substs)) } ty::ty_enum(_, ref substs) => { @@ -1124,8 +1126,8 @@ pub fn with_field_tys<R>(tcx: ty::ctxt, ast::def_variant(enum_id, variant_id) => { let variant_info = ty::enum_variant_with_id( tcx, enum_id, variant_id); - op(variant_info.disr_val, struct_mutable_fields( - tcx, variant_id, substs)) + op(variant_info.disr_val, + struct_fields(tcx, variant_id, substs)) } _ => { tcx.sess.bug(~"resolve didn't map this expr to a \ @@ -1262,7 +1264,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, } } - for vec::each(temp_cleanups) |cleanup| { + for temp_cleanups.each |cleanup| { revoke_clean(bcx, *cleanup); } return bcx; diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 21e29b9ad82..7eea65e458f 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -294,7 +294,7 @@ pub fn trans_foreign_mod(ccx: @CrateContext, Some(abi) => abi, }; - for vec::each(foreign_mod.items) |&foreign_item| { + for foreign_mod.items.each |&foreign_item| { match foreign_item.node { ast::foreign_item_fn(*) => { let id = foreign_item.id; diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index a35c40b8520..3b06f903641 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -496,9 +496,7 @@ pub fn trans_struct_drop(bcx: block, Call(bcx, dtor_addr, args); // Drop the fields - let field_tys = - ty::struct_mutable_fields(bcx.tcx(), class_did, - substs); + let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs); for vec::eachi(field_tys) |i, fld| { let llfld_a = adt::trans_field_ptr(bcx, repr, v0, 0, i); bcx = drop_ty(bcx, llfld_a, fld.mt.ty); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 934a995b588..f20af0409c5 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -51,7 +51,7 @@ pub fn trans_impl(ccx: @CrateContext, path: path, name: ast::ident, if !generics.ty_params.is_empty() { return; } let sub_path = vec::append_one(path, path_name(name)); - for vec::each(methods) |method| { + for methods.each |method| { if method.generics.ty_params.len() == 0u { let llfn = get_item_val(ccx, method.id); let path = vec::append_one(/*bad*/copy sub_path, diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index e8075c1f2ad..d9bf25bf377 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -28,7 +28,6 @@ use util::common::indenter; use util::ppaux::ty_to_str; use core::option::None; -use core::vec; use syntax::ast; use syntax::codemap; @@ -395,7 +394,7 @@ pub fn write_content(bcx: block, add_clean_temp_mem(bcx, lleltptr, vt.unit_ty); temp_cleanups.push(lleltptr); } - for vec::each(temp_cleanups) |cleanup| { + for temp_cleanups.each |cleanup| { revoke_clean(bcx, *cleanup); } } diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index fc27c11c06f..b8e0b58f866 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -155,9 +155,15 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef { } ty::ty_struct(did, _) => { - let repr = adt::represent_type(cx, t); - let packed = ty::lookup_packed(cx.tcx, did); - T_struct(adt::sizing_fields_of(cx, repr), packed) + if ty::type_is_simd(cx.tcx, t) { + let et = ty::simd_type(cx.tcx, t); + let n = ty::simd_size(cx.tcx, t); + T_vector(type_of(cx, et), n) + } else { + let repr = adt::represent_type(cx, t); + let packed = ty::lookup_packed(cx.tcx, did); + T_struct(adt::sizing_fields_of(cx, repr), packed) + } } ty::ty_self(_) | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => { @@ -263,14 +269,19 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { } ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx), ty::ty_struct(did, ref substs) => { - // Only create the named struct, but don't fill it in. We fill it - // in *after* placing it into the type cache. This prevents - // infinite recursion with recursive struct types. - - common::T_named_struct(llvm_type_name(cx, - a_struct, - did, - /*bad*/ copy substs.tps)) + if ty::type_is_simd(cx.tcx, t) { + let et = ty::simd_type(cx.tcx, t); + let n = ty::simd_size(cx.tcx, t); + T_vector(type_of(cx, et), n) + } else { + // Only create the named struct, but don't fill it in. We fill it + // in *after* placing it into the type cache. This prevents + // infinite recursion with recursive struct types. + T_named_struct(llvm_type_name(cx, + a_struct, + did, + /*bad*/ copy substs.tps)) + } } ty::ty_self(*) => cx.tcx.sess.unimpl(~"type_of: ty_self"), ty::ty_infer(*) => cx.tcx.sess.bug(~"type_of with ty_infer"), @@ -289,10 +300,12 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { } ty::ty_struct(did, _) => { - let repr = adt::represent_type(cx, t); - let packed = ty::lookup_packed(cx.tcx, did); - common::set_struct_body(llty, adt::fields_of(cx, repr), - packed); + if !ty::type_is_simd(cx.tcx, t) { + let repr = adt::represent_type(cx, t); + let packed = ty::lookup_packed(cx.tcx, did); + common::set_struct_body(llty, adt::fields_of(cx, repr), + packed); + } } _ => () } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 94ef33e45bb..f1c3a42d158 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -77,7 +77,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint) match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty { ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { - for vec::each(sig.inputs) |arg| { + for sig.inputs.each |arg| { type_needs(cx, use_repr, arg.ty); } } @@ -213,7 +213,7 @@ pub fn type_needs_inner(cx: Context, if list::find(enums_seen, |id| *id == did).is_none() { let seen = @Cons(did, enums_seen); for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) |v| { - for vec::each(v.args) |aty| { + for v.args.each |aty| { let t = ty::subst(cx.ccx.tcx, &(*substs), *aty); type_needs_inner(cx, use_, t, seen); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b6e024b011e..2daba3212e1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -106,10 +106,9 @@ pub enum SelfMode { } pub struct field_ty { - ident: ident, - id: def_id, - vis: ast::visibility, - mutability: ast::struct_mutability, + ident: ident, + id: def_id, + vis: ast::visibility, } // Contains information needed to resolve types and (in the future) look up @@ -1567,6 +1566,13 @@ pub fn type_is_sequence(ty: t) -> bool { } } +pub fn type_is_simd(cx: ctxt, ty: t) -> bool { + match get(ty).sty { + ty_struct(did, _) => lookup_simd(cx, did), + _ => false + } +} + pub fn type_is_str(ty: t) -> bool { match get(ty).sty { ty_estr(_) => true, @@ -1583,6 +1589,26 @@ pub fn sequence_element_type(cx: ctxt, ty: t) -> t { } } +pub fn simd_type(cx: ctxt, ty: t) -> t { + match get(ty).sty { + ty_struct(did, ref substs) => { + let fields = lookup_struct_fields(cx, did); + lookup_field_type(cx, did, fields[0].id, substs) + } + _ => fail!(~"simd_type called on invalid type") + } +} + +pub fn simd_size(cx: ctxt, ty: t) -> uint { + match get(ty).sty { + ty_struct(did, _) => { + let fields = lookup_struct_fields(cx, did); + fields.len() + } + _ => fail!(~"simd_size called on invalid type") + } +} + pub fn get_element_type(ty: t, i: uint) -> t { match get(ty).sty { ty_tup(ref ts) => return ts[i], @@ -1714,7 +1740,7 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t, true } ty_enum(did, ref substs) => { - for vec::each(*enum_variants(cx, did)) |v| { + for (*enum_variants(cx, did)).each |v| { for v.args.each |aty| { let t = subst(cx, substs, *aty); needs_unwind_cleanup |= @@ -2309,7 +2335,7 @@ pub fn type_structurally_contains(cx: ctxt, if test(sty) { return true; } match *sty { ty_enum(did, ref substs) => { - for vec::each(*enum_variants(cx, did)) |variant| { + for (*enum_variants(cx, did)).each |variant| { for variant.args.each |aty| { let sty = subst(cx, substs, *aty); if type_structurally_contains(cx, sty, test) { return true; } @@ -2381,6 +2407,14 @@ pub fn type_is_signed(ty: t) -> bool { } } +pub fn type_is_machine(ty: t) -> bool { + match get(ty).sty { + ty_int(ast::ty_i) | ty_uint(ast::ty_u) | ty_float(ast::ty_f) => false, + ty_int(*) | ty_uint(*) | ty_float(*) => true, + _ => false + } +} + // Whether a type is Plain Old Data -- meaning it does not contain pointers // that the cycle collector might care about. pub fn type_is_pod(cx: ctxt, ty: t) -> bool { @@ -2397,7 +2431,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { // Structural types ty_enum(did, ref substs) => { let variants = enum_variants(cx, did); - for vec::each(*variants) |variant| { + for (*variants).each |variant| { let tup_ty = mk_tup(cx, /*bad*/copy variant.args); // Perform any type parameter substitutions. @@ -3896,7 +3930,7 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool { attrs: ref attrs, _ }, _)) => attr::attrs_contains_name(*attrs, attr), - _ => tcx.sess.bug(fmt!("lookup_packed: %? is not an item", + _ => tcx.sess.bug(fmt!("has_attr: %? is not an item", did)) } } else { @@ -3908,11 +3942,16 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool { } } -/// Determine whether an item is annotated with `#[packed]` or not +/// Determine whether an item is annotated with `#[packed]` pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool { has_attr(tcx, did, "packed") } +/// Determine whether an item is annotated with `#[simd]` +pub fn lookup_simd(tcx: ctxt, did: def_id) -> bool { + has_attr(tcx, did, "simd") +} + // Look up a field ID, whether or not it's local // Takes a list of type substs in case the struct is generic pub fn lookup_field_type(tcx: ctxt, @@ -3987,12 +4026,11 @@ pub fn lookup_struct_field(cx: ctxt, fn struct_field_tys(fields: &[@struct_field]) -> ~[field_ty] { do fields.map |field| { match field.node.kind { - named_field(ident, mutability, visibility) => { + named_field(ident, visibility) => { field_ty { ident: ident, id: ast_util::local_def(field.node.id), vis: visibility, - mutability: mutability, } } unnamed_field => { @@ -4001,51 +4039,22 @@ fn struct_field_tys(fields: &[@struct_field]) -> ~[field_ty] { syntax::parse::token::special_idents::unnamed_field, id: ast_util::local_def(field.node.id), vis: ast::public, - mutability: ast::struct_immutable, } } } } } -// Return a list of fields corresponding to the struct's items -// (as if the struct was a record). trans uses this -// Takes a list of substs with which to instantiate field types -// Keep in mind that this function reports that all fields are -// mutable, regardless of how they were declared. It's meant to -// be used in trans. -pub fn struct_mutable_fields(cx: ctxt, - did: ast::def_id, - substs: &substs) - -> ~[field] { - struct_item_fields(cx, did, substs, |_mt| m_mutbl) -} - -// Same as struct_mutable_fields, but doesn't change -// mutability. -pub fn struct_fields(cx: ctxt, - did: ast::def_id, - substs: &substs) - -> ~[field] { - struct_item_fields(cx, did, substs, |mt| match mt { - struct_mutable => m_mutbl, - struct_immutable => m_imm }) -} - - -fn struct_item_fields(cx:ctxt, - did: ast::def_id, - substs: &substs, - frob_mutability: &fn(struct_mutability) -> mutability) - -> ~[field] { +// Returns a list of fields corresponding to the struct's items. trans uses +// this. Takes a list of substs with which to instantiate field types. +pub fn struct_fields(cx: ctxt, did: ast::def_id, substs: &substs) + -> ~[field] { do lookup_struct_fields(cx, did).map |f| { - // consider all instance vars mut, because the - // constructor may mutate all vars field { - ident: f.ident, + ident: f.ident, mt: mt { ty: lookup_field_type(cx, did, f.id, substs), - mutbl: frob_mutability(f.mutability) + mutbl: m_imm } } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 68700d62187..6cd10b5bd6f 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -561,8 +561,14 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt, } pub fn check_struct(ccx: @mut CrateCtxt, id: ast::node_id, span: span) { + let tcx = ccx.tcx; + // Check that the class is instantiable - check_instantiable(ccx.tcx, span, id); + check_instantiable(tcx, span, id); + + if ty::lookup_simd(tcx, local_def(id)) { + check_simd(tcx, span, id); + } } pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { @@ -3034,6 +3040,35 @@ pub fn check_instantiable(tcx: ty::ctxt, } } +pub fn check_simd(tcx: ty::ctxt, sp: span, id: ast::node_id) { + let t = ty::node_id_to_type(tcx, id); + if ty::type_needs_subst(t) { + tcx.sess.span_err(sp, "SIMD vector cannot be generic"); + return; + } + match ty::get(t).sty { + ty::ty_struct(did, ref substs) => { + let fields = ty::lookup_struct_fields(tcx, did); + if fields.is_empty() { + tcx.sess.span_err(sp, "SIMD vector cannot be empty"); + return; + } + let e = ty::lookup_field_type(tcx, did, fields[0].id, substs); + if !vec::all(fields, + |f| ty::lookup_field_type(tcx, did, f.id, substs) == e) { + tcx.sess.span_err(sp, "SIMD vector should be homogeneous"); + return; + } + if !ty::type_is_machine(e) { + tcx.sess.span_err(sp, "SIMD vector element type should be \ + machine type"); + return; + } + } + _ => () + } +} + pub fn check_enum_variants(ccx: @mut CrateCtxt, sp: span, vs: &[ast::variant], diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index b7713eaa2fd..2869c3737c9 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -228,7 +228,7 @@ fn visit_expr(e: @ast::expr, wbcx: @mut WbCtxt, v: wb_vt) { match e.node { ast::expr_fn_block(ref decl, _) => { - for vec::each(decl.inputs) |input| { + for decl.inputs.each |input| { let _ = resolve_type_vars_for_node(wbcx, e.span, input.id); } } diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index a3b5369d22a..8349e16d2c4 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -1572,8 +1572,8 @@ pub impl RegionVarBindings { return; } - for vec::each(lower_bounds) |lower_bound| { - for vec::each(upper_bounds) |upper_bound| { + for lower_bounds.each |lower_bound| { + for upper_bounds.each |upper_bound| { if !self.is_subregion_of(lower_bound.region, upper_bound.region) { @@ -1629,8 +1629,8 @@ pub impl RegionVarBindings { return; } - for vec::each(upper_bounds) |upper_bound_1| { - for vec::each(upper_bounds) |upper_bound_2| { + for upper_bounds.each |upper_bound_1| { + for upper_bounds.each |upper_bound_2| { match self.glb_concrete_regions(upper_bound_1.region, upper_bound_2.region) { Ok(_) => {} diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 1a152f3c291..5da14d99171 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -393,7 +393,7 @@ fn check_for_entry_fn(ccx: @mut CrateCtxt) { Some(session::EntryStart) => check_start_fn_ty(ccx, id, sp), None => tcx.sess.bug(~"entry function without a type") }, - None => tcx.sess.err(~"entry function not found") + None => tcx.sess.bug(~"type checking without entry function") } } } diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index f8a19eaf374..f69a38c96dc 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -100,6 +100,7 @@ pub mod middle { pub mod lang_items; pub mod privacy; pub mod moves; + pub mod entry; } pub mod front { diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index ce120f477a5..34faf6cefa3 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -22,7 +22,7 @@ use syntax; * there. */ macro_rules! interner_key ( () => (cast::transmute::<(uint, uint), - &fn(+v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u))) + &fn(v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u))) ) // Hack; rather than thread an interner through everywhere, rely on @@ -274,7 +274,7 @@ fn structdoc_from_struct( item: itemdoc, fields: do struct_def.fields.map |field| { match field.node.kind { - ast::named_field(ident, _, _) => to_str(ident), + ast::named_field(ident, _) => to_str(ident), ast::unnamed_field => ~"(unnamed)", } }, diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 16b84190ee3..e376e4afa5c 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -276,7 +276,7 @@ fn write_desc( } fn write_sections(ctxt: &Ctxt, sections: &[doc::Section]) { - for vec::each(sections) |section| { + for sections.each |section| { write_section(ctxt, copy *section); } } @@ -439,7 +439,7 @@ fn write_variants( write_header_(ctxt, H4, ~"Variants"); - for vec::each(docs) |variant| { + for docs.each |variant| { write_variant(ctxt, copy *variant); } @@ -465,7 +465,7 @@ fn write_trait(ctxt: &Ctxt, doc: doc::TraitDoc) { } fn write_methods(ctxt: &Ctxt, docs: &[doc::MethodDoc]) { - for vec::each(docs) |doc| { + for docs.each |doc| { write_method(ctxt, copy *doc); } } diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index b9a2ee7ccb7..e56b0fb60cd 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -26,8 +26,8 @@ pub type Writer = ~fn(v: WriteInstr); pub type WriterFactory = ~fn(page: doc::Page) -> Writer; pub trait WriterUtils { - fn put_str(&self, +str: ~str); - fn put_line(&self, +str: ~str); + fn put_str(&self, str: ~str); + fn put_line(&self, str: ~str); fn put_done(&self); } @@ -230,6 +230,7 @@ pub fn future_writer_factory( let markdown_ch = markdown_ch.clone(); do task::spawn || { let (writer, future) = future_writer(); + let mut future = future; writer_ch.send(writer); let s = future.get(); markdown_ch.send((copy page, s)); diff --git a/src/librustdoc/pass.rs b/src/librustdoc/pass.rs index 94db038bdec..b80f43a7bbd 100644 --- a/src/librustdoc/pass.rs +++ b/src/librustdoc/pass.rs @@ -17,7 +17,7 @@ use time; /// A single operation on the document model pub struct Pass { name: ~str, - f: @fn(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc + f: @fn(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc } pub fn run_passes( diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 0762fa4ad7f..5e43cb43960 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -11,6 +11,7 @@ use core::*; use core::cmp::Ord; use core::hash::Streaming; +use core::rt::io::Writer; use rustc::driver::{driver, session}; use rustc::driver::session::{lib_crate, unknown_crate}; use rustc::metadata::filesearch; @@ -367,9 +368,9 @@ pub fn error(msg: ~str) { } pub fn hash(data: ~str) -> ~str { - let hasher = &hash::default_state(); - - hasher.write_str(data); + let mut hasher = hash::default_state(); + let buffer = str::as_bytes_slice(data); + hasher.write(buffer); hasher.result_str() } diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 6c39fa1f9dc..08507fbf34e 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -484,7 +484,6 @@ mod tests { use core::cell::Cell; use core::task; - use core::vec; #[test] fn manually_share_arc() { @@ -673,8 +672,9 @@ mod tests { let mut children = ~[]; for 5.times { let arc3 = (*arc).clone(); - do task::task().future_result(|+r| children.push(r)).spawn - || { + let mut builder = task::task(); + builder.future_result(|r| children.push(r)); + do builder.spawn { do arc3.read |num| { assert!(*num >= 0); } @@ -682,11 +682,15 @@ mod tests { } // Wait for children to pass their asserts - for vec::each(children) |r| { r.recv(); } + for children.each |r| { + r.recv(); + } // Wait for writer to finish p.recv(); - do arc.read |num| { assert!(*num == 10); } + do arc.read |num| { + assert!(*num == 10); + } } #[test] fn test_rw_downgrade() { @@ -743,7 +747,7 @@ mod tests { assert!(*state == 42); *state = 31337; // send to other readers - for vec::each(reader_convos) |x| { + for reader_convos.each |x| { match *x { (ref rc, _) => rc.send(()), } @@ -752,7 +756,7 @@ mod tests { let read_mode = arc.downgrade(write_mode); do (&read_mode).read |state| { // complete handshake with other readers - for vec::each(reader_convos) |x| { + for reader_convos.each |x| { match *x { (_, ref rp) => rp.recv(), } diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 3a55d3e337c..fd9fba8c1d7 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -47,7 +47,7 @@ use core::vec; pub mod rusti { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { - fn move_val_init<T>(dst: &mut T, +src: T); + fn move_val_init<T>(dst: &mut T, src: T); fn needs_drop<T>() -> bool; } } diff --git a/src/libstd/base64.rs b/src/libstd/base64.rs index b26296c9aca..85ba2707863 100644 --- a/src/libstd/base64.rs +++ b/src/libstd/base64.rs @@ -156,31 +156,27 @@ impl FromBase64 for ~[u8] { let ch = self[i] as char; n <<= 6u; - if ch >= 'A' && ch <= 'Z' { - n |= (ch as uint) - 0x41u; - } else if ch >= 'a' && ch <= 'z' { - n |= (ch as uint) - 0x47u; - } else if ch >= '0' && ch <= '9' { - n |= (ch as uint) + 0x04u; - } else if ch == '+' { - n |= 0x3Eu; - } else if ch == '/' { - n |= 0x3Fu; - } else if ch == '=' { - match len - i { - 1u => { - r.push(((n >> 16u) & 0xFFu) as u8); - r.push(((n >> 8u ) & 0xFFu) as u8); - return copy r; - } - 2u => { - r.push(((n >> 10u) & 0xFFu) as u8); - return copy r; - } - _ => fail!(~"invalid base64 padding") + match ch { + 'A'..'Z' => n |= (ch as uint) - 0x41, + 'a'..'z' => n |= (ch as uint) - 0x47, + '0'..'9' => n |= (ch as uint) + 0x04, + '+' => n |= 0x3E, + '/' => n |= 0x3F, + '=' => { + match len - i { + 1u => { + r.push(((n >> 16u) & 0xFFu) as u8); + r.push(((n >> 8u ) & 0xFFu) as u8); + return copy r; + } + 2u => { + r.push(((n >> 10u) & 0xFFu) as u8); + return copy r; + } + _ => fail!(~"invalid base64 padding") + } } - } else { - fail!(~"invalid base64 character"); + _ => fail!(~"invalid base64 character") } i += 1u; diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index ceb67fcabfa..461fb61ed56 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -1426,7 +1426,7 @@ mod tests { #[bench] fn bench_uint_small(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut bitv = 0 as uint; do b.iter { bitv |= (1 << ((r.next() as uint) % uint::bits)); @@ -1435,7 +1435,7 @@ mod tests { #[bench] fn bench_small_bitv_small(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut bitv = SmallBitv::new(uint::bits); do b.iter { bitv.set((r.next() as uint) % uint::bits, true); @@ -1444,7 +1444,7 @@ mod tests { #[bench] fn bench_big_bitv_small(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut bitv = BigBitv::new(~[0]); do b.iter { bitv.set((r.next() as uint) % uint::bits, true); @@ -1453,7 +1453,7 @@ mod tests { #[bench] fn bench_big_bitv_big(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut storage = ~[]; storage.grow(bench_bits / uint::bits, &0); let mut bitv = BigBitv::new(storage); @@ -1464,7 +1464,7 @@ mod tests { #[bench] fn bench_bitv_big(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut bitv = Bitv::new(bench_bits, false); do b.iter { bitv.set((r.next() as uint) % bench_bits, true); @@ -1473,7 +1473,7 @@ mod tests { #[bench] fn bench_bitv_small(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut bitv = Bitv::new(uint::bits, false); do b.iter { bitv.set((r.next() as uint) % uint::bits, true); @@ -1482,7 +1482,7 @@ mod tests { #[bench] fn bench_bitv_set_small(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut bitv = BitvSet::new(); do b.iter { bitv.insert((r.next() as uint) % uint::bits); @@ -1491,7 +1491,7 @@ mod tests { #[bench] fn bench_bitv_set_big(b: &mut BenchHarness) { - let r = rng(); + let mut r = rng(); let mut bitv = BitvSet::new(); do b.iter { bitv.insert((r.next() as uint) % bench_bits); diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index d866ee6cedb..20ab2d61ecc 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -72,7 +72,7 @@ impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> { } impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> { - fn header(&self) -> *pipes::PacketHeader { + fn header(&mut self) -> *mut pipes::PacketHeader { self.port.header() } } diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index af433c6dd9d..5e4f708f52f 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -600,11 +600,18 @@ pub mod writer { use core::vec; // ebml writing + #[cfg(stage0)] pub struct Encoder { writer: @io::Writer, priv mut size_positions: ~[uint], } + #[cfg(not(stage0))] + pub struct Encoder { + writer: @io::Writer, + priv size_positions: ~[uint], + } + fn write_sized_vuint(w: @io::Writer, n: uint, size: uint) { match size { 1u => w.write(&[0x80u8 | (n as u8)]), @@ -625,9 +632,22 @@ pub mod writer { fail!(fmt!("vint to write too big: %?", n)); } + #[cfg(stage0)] + pub fn Encoder(w: @io::Writer) -> Encoder { + let size_positions: ~[uint] = ~[]; + Encoder { + writer: w, + mut size_positions: size_positions + } + } + + #[cfg(not(stage0))] pub fn Encoder(w: @io::Writer) -> Encoder { let size_positions: ~[uint] = ~[]; - Encoder { writer: w, mut size_positions: size_positions } + Encoder { + writer: w, + size_positions: size_positions + } } // FIXME (#2741): Provide a function to write the standard ebml header. diff --git a/src/libstd/fileinput.rs b/src/libstd/fileinput.rs index a24b11d71c6..90774d19595 100644 --- a/src/libstd/fileinput.rs +++ b/src/libstd/fileinput.rs @@ -145,7 +145,7 @@ struct FileInput_ { // "self.fi." -> "self." and renaming FileInput_. Documentation above // will likely have to be updated to use `let mut in = ...`. pub struct FileInput { - priv mut fi: FileInput_ + priv fi: @mut FileInput_ } impl FileInput { @@ -170,7 +170,7 @@ impl FileInput { pub fn from_vec_raw(files: ~[Option<Path>]) -> FileInput { FileInput{ - fi: FileInput_ { + fi: @mut FileInput_ { files: files, current_reader: None, state: FileInputState { diff --git a/src/libstd/flatpipes.rs b/src/libstd/flatpipes.rs index 874b96fd588..b712d6840ea 100644 --- a/src/libstd/flatpipes.rs +++ b/src/libstd/flatpipes.rs @@ -558,9 +558,11 @@ pub mod bytepipes { } } + // XXX: Remove `@mut` when this module is ported to the new I/O traits, + // which use `&mut self` properly. pub struct PipeBytePort { port: comm::Port<~[u8]>, - mut buf: ~[u8] + buf: @mut ~[u8] } pub struct PipeByteChan { @@ -569,13 +571,13 @@ pub mod bytepipes { impl BytePort for PipeBytePort { fn try_recv(&self, count: uint) -> Option<~[u8]> { - if vec::uniq_len(&const self.buf) >= count { - let mut bytes = ::core::util::replace(&mut self.buf, ~[]); - self.buf = bytes.slice(count, bytes.len()).to_owned(); + if vec::uniq_len(&const *self.buf) >= count { + let mut bytes = ::core::util::replace(&mut *self.buf, ~[]); + *self.buf = bytes.slice(count, bytes.len()).to_owned(); bytes.truncate(count); return Some(bytes); - } else if vec::uniq_len(&const self.buf) > 0 { - let mut bytes = ::core::util::replace(&mut self.buf, ~[]); + } else if vec::uniq_len(&const *self.buf) > 0 { + let mut bytes = ::core::util::replace(&mut *self.buf, ~[]); assert!(count > bytes.len()); match self.try_recv(count - bytes.len()) { Some(rest) => { @@ -584,11 +586,11 @@ pub mod bytepipes { } None => return None } - } else if vec::uniq_len(&const self.buf) == 0 { + } else if vec::uniq_len(&const *self.buf) == 0 { match self.port.try_recv() { Some(buf) => { assert!(!buf.is_empty()); - self.buf = buf; + *self.buf = buf; return self.try_recv(count); } None => return None @@ -609,7 +611,7 @@ pub mod bytepipes { fn new(p: Port<~[u8]>) -> PipeBytePort { PipeBytePort { port: p, - buf: ~[] + buf: @mut ~[] } } } @@ -643,7 +645,7 @@ mod test { chan.send(10); - let bytes = copy chan.byte_chan.writer.bytes; + let bytes = copy *chan.byte_chan.writer.bytes; let reader = BufReader::new(bytes); let port = serial::reader_port(reader); @@ -690,7 +692,7 @@ mod test { chan.send(10); - let bytes = copy chan.byte_chan.writer.bytes; + let bytes = copy *chan.byte_chan.writer.bytes; let reader = BufReader::new(bytes); let port = pod::reader_port(reader); @@ -926,7 +928,7 @@ mod test { test_try_recv_none3(pipe_port_loader); } - fn test_try_recv_none4<P:BytePort>(+loader: PortLoader<P>) { + fn test_try_recv_none4<P:BytePort>(loader: PortLoader<P>) { assert!(do task::try || { static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD]; // The control word is followed by a valid length, diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 5e3e64b2f1c..37eb1e02a80 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -28,10 +28,17 @@ use core::pipes::recv; use core::task; #[doc = "The future type"] +#[cfg(stage0)] pub struct Future<A> { priv mut state: FutureState<A>, } +#[doc = "The future type"] +#[cfg(not(stage0))] +pub struct Future<A> { + priv state: FutureState<A>, +} + // FIXME(#2829) -- futures should not be copyable, because they close // over ~fn's that have pipes and so forth within! #[unsafe_destructor] @@ -47,13 +54,14 @@ priv enum FutureState<A> { /// Methods on the `future` type pub impl<A:Copy> Future<A> { - fn get(&self) -> A { + fn get(&mut self) -> A { //! Get the value of the future *(self.get_ref()) } } pub impl<A> Future<A> { + #[cfg(stage0)] fn get_ref<'a>(&'a self) -> &'a A { /*! * Executes the future's closure and then returns a borrowed @@ -61,19 +69,53 @@ pub impl<A> Future<A> { * the future. */ unsafe { - match self.state { - Forced(ref mut v) => { return cast::transmute(v); } - Evaluating => fail!(~"Recursive forcing of future!"), - Pending(_) => {} + { + match self.state { + Forced(ref mut v) => { return cast::transmute(v); } + Evaluating => fail!(~"Recursive forcing of future!"), + Pending(_) => {} + } } + { + let mut state = Evaluating; + self.state <-> state; + match state { + Forced(_) | Evaluating => fail!(~"Logic error."), + Pending(f) => { + self.state = Forced(f()); + cast::transmute(self.get_ref()) + } + } + } + } + } - let mut state = Evaluating; - self.state <-> state; - match state { - Forced(_) | Evaluating => fail!(~"Logic error."), - Pending(f) => { - self.state = Forced(f()); - self.get_ref() + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn get_ref<'a>(&'a mut self) -> &'a A { + /*! + * Executes the future's closure and then returns a borrowed + * pointer to the result. The borrowed pointer lasts as long as + * the future. + */ + unsafe { + { + match self.state { + Forced(ref mut v) => { return cast::transmute(v); } + Evaluating => fail!(~"Recursive forcing of future!"), + Pending(_) => {} + } + } + { + let mut state = Evaluating; + self.state <-> state; + match state { + Forced(_) | Evaluating => fail!(~"Logic error."), + Pending(f) => { + self.state = Forced(f()); + cast::transmute(self.get_ref()) + } } } } @@ -142,15 +184,15 @@ pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> { #[allow(non_implicitly_copyable_typarams)] #[cfg(test)] mod test { - use future::*; + use core::cell::Cell; use core::comm::{oneshot, send_one}; use core::task; #[test] fn test_from_value() { - let f = from_value(~"snail"); + let mut f = from_value(~"snail"); assert!(f.get() == ~"snail"); } @@ -158,31 +200,31 @@ mod test { fn test_from_port() { let (po, ch) = oneshot(); send_one(ch, ~"whale"); - let f = from_port(po); + let mut f = from_port(po); assert!(f.get() == ~"whale"); } #[test] fn test_from_fn() { - let f = from_fn(|| ~"brail"); + let mut f = from_fn(|| ~"brail"); assert!(f.get() == ~"brail"); } #[test] fn test_interface_get() { - let f = from_value(~"fail"); + let mut f = from_value(~"fail"); assert!(f.get() == ~"fail"); } #[test] fn test_get_ref_method() { - let f = from_value(22); + let mut f = from_value(22); assert!(*f.get_ref() == 22); } #[test] fn test_spawn() { - let f = spawn(|| ~"bale"); + let mut f = spawn(|| ~"bale"); assert!(f.get() == ~"bale"); } @@ -190,15 +232,16 @@ mod test { #[should_fail] #[ignore(cfg(target_os = "win32"))] fn test_futurefail() { - let f = spawn(|| fail!()); + let mut f = spawn(|| fail!()); let _x: ~str = f.get(); } #[test] fn test_sendable_future() { let expected = ~"schlorf"; - let f = do spawn { copy expected }; - do task::spawn || { + let f = Cell(do spawn { copy expected }); + do task::spawn { + let mut f = f.take(); let actual = f.get(); assert!(actual == expected); } diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 781e44a8f3f..f684ebe8a3c 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -368,7 +368,7 @@ pub fn opt_count(mm: &Matches, nm: &str) -> uint { /// Returns true if any of several options were matched pub fn opts_present(mm: &Matches, names: &[~str]) -> bool { - for vec::each(names) |nm| { + for names.each |nm| { match find_opt(mm.opts, mkname(*nm)) { Some(id) if !mm.vals[id].is_empty() => return true, _ => (), @@ -395,7 +395,7 @@ pub fn opt_str(mm: &Matches, nm: &str) -> ~str { * option took an argument */ pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str { - for vec::each(names) |nm| { + for names.each |nm| { match opt_val(mm, *nm) { Val(copy s) => return s, _ => () diff --git a/src/libstd/io_util.rs b/src/libstd/io_util.rs index 50d2eb6a785..7d43663cc80 100644 --- a/src/libstd/io_util.rs +++ b/src/libstd/io_util.rs @@ -13,14 +13,14 @@ use core::io; pub struct BufReader { buf: ~[u8], - mut pos: uint + pos: @mut uint } pub impl BufReader { pub fn new(v: ~[u8]) -> BufReader { BufReader { buf: v, - pos: 0 + pos: @mut 0 } } @@ -29,13 +29,13 @@ pub impl BufReader { // I can't get the borrowing to work correctly let bytes_reader = BytesReader { bytes: ::core::util::id::<&[u8]>(self.buf), - pos: self.pos + pos: @mut *self.pos }; let res = f(&bytes_reader); // FIXME #4429: This isn't correct if f fails - self.pos = bytes_reader.pos; + *self.pos = *bytes_reader.pos; return res; } diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 3960a07dfce..c815c9dd480 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -220,11 +220,18 @@ impl serialize::Encoder for Encoder { } } +#[cfg(stage0)] pub struct PrettyEncoder { priv wr: @io::Writer, priv mut indent: uint, } +#[cfg(not(stage0))] +pub struct PrettyEncoder { + priv wr: @io::Writer, + priv indent: uint, +} + pub fn PrettyEncoder(wr: @io::Writer) -> PrettyEncoder { PrettyEncoder { wr: wr, @@ -838,10 +845,16 @@ pub fn from_str(s: &str) -> Result<Json, Error> { } } +#[cfg(stage0)] pub struct Decoder { priv mut stack: ~[Json], } +#[cfg(not(stage0))] +pub struct Decoder { + priv stack: ~[Json], +} + pub fn Decoder(json: Json) -> Decoder { Decoder { stack: ~[json] diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index aac0ff63166..9a0eb6d85db 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -425,7 +425,7 @@ mod test { let results = result::unwrap(ga_result); debug!("test_get_addr: Number of results for %s: %?", localhost_name, vec::len(results)); - for vec::each(results) |r| { + for results.each |r| { let ipv_prefix = match *r { Ipv4(_) => ~"IPv4", Ipv6(_) => ~"IPv6" diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 53eb6c5561b..bc4168ba7f8 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -71,14 +71,14 @@ pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket { * satisfy both the `io::Reader` and `io::Writer` traits. */ pub struct TcpSocketBuf { - data: @TcpBufferedSocketData, - mut end_of_stream: bool + data: @mut TcpBufferedSocketData, + end_of_stream: @mut bool } -pub fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf { +pub fn TcpSocketBuf(data: @mut TcpBufferedSocketData) -> TcpSocketBuf { TcpSocketBuf { data: data, - end_of_stream: false + end_of_stream: @mut false } } @@ -670,7 +670,7 @@ fn listen_common(host_ip: ip::IpAddr, &ip::Ipv4(_) => { false } &ip::Ipv6(_) => { true } }, - mut active: true + active: @mut true }; let server_data_ptr: *TcpListenFcData = &server_data; @@ -751,7 +751,7 @@ fn listen_common(host_ip: ip::IpAddr, debug!( "tcp::listen post-kill recv hl interact %?", loop_ptr); - (*server_data_ptr).active = false; + *(*server_data_ptr).active = false; uv::ll::close(server_stream_ptr, tcp_lfc_close_cb); } }; @@ -782,7 +782,7 @@ fn listen_common(host_ip: ip::IpAddr, debug!( "tcp::listen post-kill recv hl interact %?", loop_ptr); - (*server_data_ptr).active = false; + *(*server_data_ptr).active = false; uv::ll::close(server_stream_ptr, tcp_lfc_close_cb); } }; @@ -816,8 +816,8 @@ fn listen_common(host_ip: ip::IpAddr, * A buffered wrapper that you can cast as an `io::Reader` or `io::Writer` */ pub fn socket_buf(sock: TcpSocket) -> TcpSocketBuf { - TcpSocketBuf(@TcpBufferedSocketData { - sock: sock, mut buf: ~[], buf_off: 0 + TcpSocketBuf(@mut TcpBufferedSocketData { + sock: sock, buf: ~[], buf_off: 0 }) } @@ -902,12 +902,15 @@ impl io::Reader for TcpSocketBuf { // need to read in data from the socket. Note that the internal // buffer is of no use anymore as we read all bytes from it, // so we can throw it away. - let read_result = read(&self.data.sock, 0u); + let read_result = { + let data = &*self.data; + read(&data.sock, 0) + }; if read_result.is_err() { let err_data = read_result.get_err(); if err_data.err_name == ~"EOF" { - self.end_of_stream = true; + *self.end_of_stream = true; break; } else { debug!("ERROR sock_buf as io::reader.read err %? %?", @@ -917,8 +920,7 @@ impl io::Reader for TcpSocketBuf { // should show up in a later call to read(). break; } - } - else { + } else { self.data.buf = result::unwrap(read_result); self.data.buf_off = 0; } @@ -934,27 +936,29 @@ impl io::Reader for TcpSocketBuf { return c as int } - let read_result = read(&self.data.sock, 0u); + let read_result = { + let data = &*self.data; + read(&data.sock, 0) + }; if read_result.is_err() { let err_data = read_result.get_err(); if err_data.err_name == ~"EOF" { - self.end_of_stream = true; + *self.end_of_stream = true; return -1 } else { debug!("ERROR sock_buf as io::reader.read err %? %?", err_data.err_name, err_data.err_msg); fail!() } - } - else { + } else { self.data.buf = result::unwrap(read_result); self.data.buf_off = 0; } } } fn eof(&self) -> bool { - self.end_of_stream + *self.end_of_stream } fn seek(&self, dist: int, seek: io::SeekStyle) { debug!("tcp_socket_buf seek stub %? %?", dist, seek); @@ -1204,7 +1208,7 @@ struct TcpListenFcData { on_connect_cb: ~fn(*uv::ll::uv_tcp_t), iotask: IoTask, ipv6: bool, - mut active: bool, + active: @mut bool, } extern fn tcp_lfc_close_cb(handle: *uv::ll::uv_tcp_t) { @@ -1222,7 +1226,7 @@ extern fn tcp_lfc_on_connection_cb(handle: *uv::ll::uv_tcp_t, let server_data_ptr = uv::ll::get_data_for_uv_handle(handle) as *TcpListenFcData; let kill_ch = (*server_data_ptr).kill_ch.clone(); - if (*server_data_ptr).active { + if *(*server_data_ptr).active { match status { 0i32 => ((*server_data_ptr).on_connect_cb)(handle), _ => { @@ -1230,7 +1234,7 @@ extern fn tcp_lfc_on_connection_cb(handle: *uv::ll::uv_tcp_t, kill_ch.send( Some(uv::ll::get_last_err_data(loop_ptr) .to_tcp_err())); - (*server_data_ptr).active = false; + *(*server_data_ptr).active = false; } } } @@ -1430,8 +1434,8 @@ struct TcpSocketData { struct TcpBufferedSocketData { sock: TcpSocket, - mut buf: ~[u8], - mut buf_off: uint + buf: ~[u8], + buf_off: uint } #[cfg(test)] @@ -1959,7 +1963,7 @@ mod test { } fn tcp_write_single(sock: &TcpSocket, val: ~[u8]) { - let write_result_future = sock.write_future(val); + let mut write_result_future = sock.write_future(val); let write_result = write_result_future.get(); if result::is_err(&write_result) { debug!("tcp_write_single: write failed!"); diff --git a/src/libstd/par.rs b/src/libstd/par.rs index cfedbb66caa..cf0eba9d30c 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -73,10 +73,10 @@ fn map_slices<A:Copy + Owned,B:Copy + Owned>( info!("num_tasks: %?", (num_tasks, futures.len())); assert!((num_tasks == futures.len())); - let r = do futures.map() |ys| { + let r = do vec::map_consume(futures) |ys| { + let mut ys = ys; ys.get() }; - assert!((r.len() == futures.len())); r } } diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index 33fe1cfff8e..9bf7db07ac9 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -14,7 +14,7 @@ use core::old_iter::BaseIter; #[abi = "rust-intrinsic"] extern "rust-intrinsic" mod rusti { - fn move_val_init<T>(dst: &mut T, +src: T); + fn move_val_init<T>(dst: &mut T, src: T); fn init<T>() -> T; } diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index 6f72d8dc16d..815f03f4269 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -29,7 +29,7 @@ pub struct Rc<T> { priv ptr: *mut RcBox<T>, } -pub impl<'self, T: Owned> Rc<T> { +pub impl<T: Owned> Rc<T> { fn new(value: T) -> Rc<T> { unsafe { let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>; @@ -40,8 +40,8 @@ pub impl<'self, T: Owned> Rc<T> { } #[inline(always)] - fn borrow(&self) -> &'self T { - unsafe { cast::transmute_region(&(*self.ptr).value) } + fn borrow<'r>(&'r self) -> &'r T { + unsafe { cast::copy_lifetime(self, &(*self.ptr).value) } } } @@ -119,7 +119,7 @@ pub struct RcMut<T> { priv ptr: *mut RcMutBox<T>, } -pub impl<'self, T: Owned> RcMut<T> { +pub impl<T: Owned> RcMut<T> { fn new(value: T) -> RcMut<T> { unsafe { let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>; @@ -136,7 +136,7 @@ pub impl<'self, T: Owned> RcMut<T> { assert!((*self.ptr).borrow != Mutable); let previous = (*self.ptr).borrow; (*self.ptr).borrow = Immutable; - f(cast::transmute_region(&(*self.ptr).value)); + f(&(*self.ptr).value); (*self.ptr).borrow = previous; } } @@ -147,7 +147,7 @@ pub impl<'self, T: Owned> RcMut<T> { unsafe { assert!((*self.ptr).borrow == Nothing); (*self.ptr).borrow = Mutable; - f(cast::transmute_mut_region(&mut (*self.ptr).value)); + f(&mut (*self.ptr).value); (*self.ptr).borrow = Nothing; } } diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs index a8e0f7d062a..cd5845ac544 100644 --- a/src/libstd/sha1.rs +++ b/src/libstd/sha1.rs @@ -250,7 +250,7 @@ pub fn sha1() -> @Sha1 { fn result_str(&mut self) -> ~str { let rr = mk_result(self); let mut s = ~""; - for vec::each(rr) |b| { + for rr.each |b| { let hex = uint::to_str_radix(*b as uint, 16u); if hex.len() == 1 { s += "0"; @@ -378,7 +378,7 @@ mod tests { // Test that it works when accepting the message all at once let mut sh = sha1::sha1(); - for vec::each(tests) |t| { + for tests.each |t| { sh.input_str(t.input); let out = sh.result(); check_vec_eq(t.output, out); @@ -392,7 +392,7 @@ mod tests { // Test that it works when accepting the message in pieces - for vec::each(tests) |t| { + for tests.each |t| { let len = str::len(t.input); let mut left = len; while left > 0u { diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index a18e2f47a77..ae474e0c394 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -859,7 +859,7 @@ mod test_qsort { let immut_names = names; let pairs = vec::zip_slice(expected, immut_names); - for vec::each(pairs) |p| { + for pairs.each |p| { let (a, b) = *p; debug!("%d %d", a, b); assert!((a == b)); @@ -946,8 +946,10 @@ mod test_tim_sort { impl Ord for CVal { fn lt(&self, other: &CVal) -> bool { - let rng = rand::rng(); - if rng.gen::<float>() > 0.995 { fail!(~"It's happening!!!"); } + let mut rng = rand::rng(); + if rng.gen::<float>() > 0.995 { + fail!(~"It's happening!!!"); + } (*self).val < other.val } fn le(&self, other: &CVal) -> bool { (*self).val <= other.val } @@ -995,7 +997,7 @@ mod test_tim_sort { #[should_fail] #[cfg(unix)] fn crash_test() { - let rng = rand::rng(); + let mut rng = rand::rng(); let mut arr = do vec::from_fn(1000) |_i| { CVal { val: rng.gen() } }; @@ -1015,7 +1017,7 @@ mod test_tim_sort { #[test] fn test_bad_Ord_impl() { - let rng = rand::rng(); + let mut rng = rand::rng(); let mut arr = do vec::from_fn(500) |_i| { DVal { val: rng.gen() } }; @@ -1067,7 +1069,7 @@ mod big_tests { } } - let rng = rand::rng(); + let mut rng = rand::rng(); for uint::range(lo, hi) |i| { let n = 1 << i; @@ -1138,7 +1140,7 @@ mod big_tests { } } - let rng = rand::rng(); + let mut rng = rand::rng(); for uint::range(lo, hi) |i| { let n = 1 << i; diff --git a/src/libstd/sort_stage0.rs b/src/libstd/sort_stage0.rs index f3d30ecd5cd..044c616dcd3 100644 --- a/src/libstd/sort_stage0.rs +++ b/src/libstd/sort_stage0.rs @@ -852,7 +852,7 @@ mod test_qsort { let immut_names = names; let pairs = vec::zip_slice(expected, immut_names); - for vec::each(pairs) |p| { + for pairs.each |p| { let (a, b) = *p; debug!("%d %d", a, b); assert!((a == b)); diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 51e11669f44..931974d2454 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -28,7 +28,9 @@ not required in or otherwise suitable for the core library. #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; -#[allow(deprecated_mutable_fields)]; + +// Allow mutable fields only in stage0. +#[warn(deprecated_mutable_fields)]; pub mod uv_ll; diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index e86ec793188..17d051518a9 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -997,7 +997,7 @@ mod tests { } } } - for vec::each(sibling_convos) |p| { + for sibling_convos.each |p| { let _ = p.recv(); // wait for sibling to get in the mutex } do m2.lock { } diff --git a/src/libstd/task_pool.rs b/src/libstd/task_pool.rs index 661247df1c1..0c52e1ff80e 100644 --- a/src/libstd/task_pool.rs +++ b/src/libstd/task_pool.rs @@ -70,7 +70,9 @@ pub impl<T> TaskPool<T> { task::spawn(task_body); } Some(sched_mode) => { - task::task().sched_mode(sched_mode).spawn(task_body); + let mut task = task::task(); + task.sched_mode(sched_mode); + task.spawn(task_body); } } diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs index 10645e947e2..e02a7a33733 100644 --- a/src/libstd/tempfile.rs +++ b/src/libstd/tempfile.rs @@ -13,7 +13,7 @@ use core::rand::RngUtil; pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> { - let r = rand::rng(); + let mut r = rand::rng(); for 1000.times { let p = tmpdir.push(r.gen_str(16) + suffix); if os::make_dir(&p, 0x1c0) { // 700 diff --git a/src/libstd/term.rs b/src/libstd/term.rs index a79b9f4c849..236c7f668c2 100644 --- a/src/libstd/term.rs +++ b/src/libstd/term.rs @@ -13,7 +13,6 @@ use core::io; use core::option; use core::os; -use core::vec; // FIXME (#2807): Windows support. @@ -50,7 +49,7 @@ pub fn color_supported() -> bool { ~"screen-bce", ~"xterm-256color"]; return match os::getenv(~"TERM") { option::Some(ref env) => { - for vec::each(supported_terms) |term| { + for supported_terms.each |term| { if *term == *env { return true; } } false diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 95bfc80ac55..3b527efabd3 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -355,7 +355,7 @@ fn print_failures(st: &ConsoleTestState) { failures.push(name.to_str()); } sort::tim_sort(failures); - for vec::each(failures) |name| { + for failures.each |name| { st.out.write_line(fmt!(" %s", name.to_str())); } } @@ -556,9 +556,12 @@ pub fn run_test(force_ignore: bool, let testfn_cell = ::core::cell::Cell(testfn); do task::spawn { let mut result_future = None; // task::future_result(builder); - task::task().unlinked().future_result(|+r| { - result_future = Some(r); - }).spawn(testfn_cell.take()); + + let mut task = task::task(); + task.unlinked(); + task.future_result(|r| { result_future = Some(r) }); + task.spawn(testfn_cell.take()); + let task_result = result_future.unwrap().recv(); let test_result = calc_result(&desc, task_result == task::Success); @@ -688,7 +691,7 @@ pub mod bench { // not met, it may run as long as the Go algorithm. pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] { - let rng = rand::rng(); + let mut rng = rand::rng(); let mut magnitude = 10; let mut prev_madp = 0.0; @@ -925,7 +928,7 @@ mod tests { { fn testfn() { } let mut tests = ~[]; - for vec::each(names) |name| { + for names.each |name| { let test = TestDescAndFn { desc: TestDesc { name: DynTestName(*name), @@ -951,7 +954,7 @@ mod tests { let pairs = vec::zip(expected, filtered); - for vec::each(pairs) |p| { + for pairs.each |p| { match *p { (ref a, ref b) => { assert!((*a == b.desc.name.to_str())); diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 8889abe6472..31d8eb20a67 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -861,7 +861,6 @@ mod tests { use core::result; use core::result::{Err, Ok}; use core::str; - use core::vec; fn test_get_time() { static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z @@ -1028,7 +1027,7 @@ mod tests { } } - for vec::each([ + for [ ~"Sunday", ~"Monday", ~"Tuesday", @@ -1036,11 +1035,11 @@ mod tests { ~"Thursday", ~"Friday", ~"Saturday" - ]) |day| { + ].each |day| { assert!(test(*day, ~"%A")); } - for vec::each([ + for [ ~"Sun", ~"Mon", ~"Tue", @@ -1048,11 +1047,11 @@ mod tests { ~"Thu", ~"Fri", ~"Sat" - ]) |day| { + ].each |day| { assert!(test(*day, ~"%a")); } - for vec::each([ + for [ ~"January", ~"February", ~"March", @@ -1065,11 +1064,11 @@ mod tests { ~"October", ~"November", ~"December" - ]) |day| { + ].each |day| { assert!(test(*day, ~"%B")); } - for vec::each([ + for [ ~"Jan", ~"Feb", ~"Mar", @@ -1082,7 +1081,7 @@ mod tests { ~"Oct", ~"Nov", ~"Dec" - ]) |day| { + ].each |day| { assert!(test(*day, ~"%b")); } diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index b19b2f2889e..0d15bbb54d3 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -14,10 +14,11 @@ use uv; use uv::iotask; use uv::iotask::IoTask; -use core::libc; -use core::libc::c_void; use core::cast::transmute; +use core::cast; use core::comm::{stream, Chan, SharedChan, Port, select2i}; +use core::libc::c_void; +use core::libc; /** * Wait for timeout period then send provided value over a channel @@ -120,22 +121,28 @@ pub fn sleep(iotask: &IoTask, msecs: uint) { pub fn recv_timeout<T:Copy + Owned>(iotask: &IoTask, msecs: uint, wait_po: &Port<T>) - -> Option<T> { - let (timeout_po, timeout_ch) = stream::<()>(); + -> Option<T> { + let mut (timeout_po, timeout_ch) = stream::<()>(); delayed_send(iotask, msecs, &timeout_ch, ()); - // FIXME: This could be written clearer (#2618) - either::either( - |_| { - None - }, |_| { - Some(wait_po.recv()) - }, &select2i(&timeout_po, wait_po) - ) + + // XXX: Workaround due to ports and channels not being &mut. They should + // be. + unsafe { + let wait_po = cast::transmute_mut(wait_po); + + // FIXME: This could be written clearer (#2618) + either::either( + |_| { + None + }, |_| { + Some(wait_po.recv()) + }, &select2i(&mut timeout_po, wait_po) + ) + } } // INTERNAL API -extern fn delayed_send_cb(handle: *uv::ll::uv_timer_t, - status: libc::c_int) { +extern fn delayed_send_cb(handle: *uv::ll::uv_timer_t, status: libc::c_int) { unsafe { debug!( "delayed_send_cb handle %? status %?", handle, status); @@ -212,7 +219,7 @@ mod test { let hl_loop_clone = hl_loop.clone(); do task::spawn { use core::rand::*; - let rng = rng(); + let mut rng = rng(); for old_iter::repeat(times) { sleep(&hl_loop_clone, rng.next() as uint % maxms); } @@ -269,7 +276,8 @@ mod test { let hl_loop = uv::global_loop::get(); for old_iter::repeat(times as uint) { - let expected = rand::rng().gen_str(16u); + let mut rng = rand::rng(); + let expected = rng.gen_str(16u); let (test_po, test_ch) = stream::<~str>(); let hl_loop_clone = hl_loop.clone(); do task::spawn() { diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index c8ab48e65c0..06ac1a71bac 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -848,7 +848,7 @@ mod test_treemap { check_equal(ctrl, &map); assert!(map.find(&5).is_none()); - let rng = rand::IsaacRng::new_seeded(&[42]); + let mut rng = rand::IsaacRng::new_seeded(&[42]); for 3.times { for 90.times { diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs index c8311cff2cf..97df64d5266 100644 --- a/src/libstd/uv_global_loop.rs +++ b/src/libstd/uv_global_loop.rs @@ -62,7 +62,9 @@ fn get_monitor_task_gl() -> IoTask { } }; if installed { - do task().unlinked().spawn() { + let mut task = task(); + task.unlinked(); + do task.spawn { unsafe { debug!("global monitor task starting"); // As a weak task the runtime will notify us @@ -88,7 +90,9 @@ fn get_monitor_task_gl() -> IoTask { } fn spawn_loop() -> IoTask { - let builder = do task().add_wrapper |task_body| { + let mut builder = task(); + + do builder.add_wrapper |task_body| { let result: ~fn() = || { // The I/O loop task also needs to be weak so it doesn't keep // the runtime alive @@ -107,7 +111,8 @@ fn spawn_loop() -> IoTask { }; result }; - let builder = builder.unlinked(); + + builder.unlinked(); spawn_iotask(builder) } diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index 79a40559971..2922f403f34 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -36,11 +36,11 @@ impl Clone for IoTask { } } -pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask { - +pub fn spawn_iotask(mut task: task::TaskBuilder) -> IoTask { let (iotask_port, iotask_chan) = stream(); - do task.sched_mode(task::SingleThreaded).spawn { + task.sched_mode(task::SingleThreaded); + do task.spawn { debug!("entering libuv task"); run_loop(&iotask_chan); debug!("libuv task exiting"); diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index afc7b9c8106..5cccf2c348d 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -780,23 +780,24 @@ extern mod rustrt { // FIXME ref #2064 unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in) -> libc::c_int; + after_cb: *u8, + addr: *sockaddr_in) + -> libc::c_int; // FIXME ref #2064 unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, - ++addr: *sockaddr_in) -> libc::c_int; + addr: *sockaddr_in) -> libc::c_int; // FIXME ref #2064 unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in6) -> libc::c_int; + after_cb: *u8, + addr: *sockaddr_in6) -> libc::c_int; // FIXME ref #2064 unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, - ++addr: *sockaddr_in6) -> libc::c_int; + addr: *sockaddr_in6) -> libc::c_int; unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, - ++name: *sockaddr_in) -> libc::c_int; + name: *sockaddr_in) -> libc::c_int; unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, - ++name: *sockaddr_in6) ->libc::c_int; + name: *sockaddr_in6) ->libc::c_int; unsafe fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int, cb: *u8) -> libc::c_int; @@ -804,7 +805,7 @@ extern mod rustrt { -> libc::c_int; unsafe fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void, - ++buf_in: *uv_buf_t, + buf_in: *uv_buf_t, buf_cnt: libc::c_int, cb: *u8) -> libc::c_int; @@ -843,7 +844,7 @@ extern mod rustrt { unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6; unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8; - unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t); + unsafe fn rust_uv_free_base_of_buf(buf: uv_buf_t); unsafe fn rust_uv_get_stream_handle_from_connect_req( connect_req: *uv_connect_t) -> *uv_stream_t; @@ -864,8 +865,8 @@ extern mod rustrt { -> *libc::c_void; unsafe fn rust_uv_set_data_for_req(req: *libc::c_void, data: *libc::c_void); - unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; - unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t; + unsafe fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8; + unsafe fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> libc::size_t; // sizeof testing helpers unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; @@ -1258,7 +1259,7 @@ mod test { extern fn on_read_cb(stream: *uv_stream_t, nread: libc::ssize_t, - ++buf: uv_buf_t) { + buf: uv_buf_t) { unsafe { let nread = nread as int; debug!("CLIENT entering on_read_cb nred: %d", @@ -1444,7 +1445,7 @@ mod test { extern fn on_server_read_cb(client_stream_ptr: *uv_stream_t, nread: libc::ssize_t, - ++buf: uv_buf_t) { + buf: uv_buf_t) { unsafe { let nread = nread as int; if (nread > 0) { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2216226ecb3..c8fc04eaea1 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1168,7 +1168,7 @@ pub type struct_field = spanned<struct_field_>; #[auto_decode] #[deriving(Eq)] pub enum struct_field_kind { - named_field(ident, struct_mutability, visibility), + named_field(ident, visibility), unnamed_field // element of a tuple-like struct } @@ -1221,17 +1221,6 @@ pub enum item_ { #[auto_encode] #[auto_decode] #[deriving(Eq)] -pub enum struct_mutability { struct_mutable, struct_immutable } - -impl to_bytes::IterBytes for struct_mutability { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[auto_encode] -#[auto_decode] -#[deriving(Eq)] pub struct foreign_item { ident: ident, attrs: ~[attribute], @@ -1291,6 +1280,21 @@ mod test { #[test] fn test_marksof () { let stopname = uints_to_name(&~[12,14,78]); + assert_eq!(s,~[]); + xorPush(&mut s,14); + assert_eq!(s,~[14]); + xorPush(&mut s,15); + assert_eq!(s,~[14,15]); + xorPush (&mut s,16); + assert_eq! (s,~[14,15,16]); + xorPush (&mut s,16); + assert_eq! (s,~[14,15]); + xorPush (&mut s,15); + assert_eq! (s,~[14]); + } + + #[test] fn test_marksof () { + let stopname = uints_to_name(&~[12,14,78]); let name1 = uints_to_name(&~[4,9,7]); assert_eq!(marksof (MT,stopname),~[]); assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]); @@ -1347,3 +1351,12 @@ mod test { } */ +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// End: +// diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index a6094903d7b..77277dea814 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -285,7 +285,7 @@ pub fn split_trait_methods(trait_methods: &[trait_method]) pub fn struct_field_visibility(field: ast::struct_field) -> visibility { match field.node.kind { - ast::named_field(_, _, visibility) => visibility, + ast::named_field(_, visibility) => visibility, ast::unnamed_field => ast::public } } @@ -461,7 +461,7 @@ pub fn id_visitor(vfn: @fn(node_id)) -> visit::vt<()> { } } - for vec::each(d.inputs) |arg| { + for d.inputs.each |arg| { vfn(arg.id) } }, diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index bdf0a2a1dd0..5bd4f89a3b3 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -914,19 +914,15 @@ struct field { fn mk_struct_fields(fields: &[@ast::struct_field]) -> ~[field] { do fields.map |field| { - let (ident, mutbl) = match field.node.kind { - ast::named_field(ident, mutbl, _) => (ident, mutbl), - _ => fail!(~"[auto_encode] does not support \ - unnamed fields") + let ident = match field.node.kind { + ast::named_field(ident, _) => ident, + _ => fail!(~"[auto_encode] does not support unnamed fields") }; field { span: field.span, ident: ident, - mutbl: match mutbl { - ast::struct_mutable => ast::m_mutbl, - ast::struct_immutable => ast::m_imm, - }, + mutbl: ast::m_imm, } } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 4c876669f47..3097cb799a2 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -11,6 +11,7 @@ use ast; use codemap; use codemap::span; +use fold; use ext::base::ext_ctxt; use ext::build; @@ -54,43 +55,52 @@ pub fn mk_binary(cx: @ext_ctxt, sp: span, op: ast::binop, cx.next_id(); // see ast_util::op_expr_callee_id mk_expr(cx, sp, ast::expr_binary(op, lhs, rhs)) } + +pub fn mk_deref(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr { + mk_unary(cx, sp, ast::deref, e) +} pub fn mk_unary(cx: @ext_ctxt, sp: span, op: ast::unop, e: @ast::expr) -> @ast::expr { cx.next_id(); // see ast_util::op_expr_callee_id mk_expr(cx, sp, ast::expr_unary(op, e)) } pub fn mk_raw_path(sp: span, idents: ~[ast::ident]) -> @ast::Path { - mk_raw_path_(sp, idents, ~[]) + mk_raw_path_(sp, idents, None, ~[]) } pub fn mk_raw_path_(sp: span, idents: ~[ast::ident], + rp: Option<@ast::Lifetime>, types: ~[@ast::Ty]) -> @ast::Path { @ast::Path { span: sp, global: false, idents: idents, - rp: None, + rp: rp, types: types } } pub fn mk_raw_path_global(sp: span, idents: ~[ast::ident]) -> @ast::Path { - mk_raw_path_global_(sp, idents, ~[]) + mk_raw_path_global_(sp, idents, None, ~[]) } pub fn mk_raw_path_global_(sp: span, idents: ~[ast::ident], + rp: Option<@ast::Lifetime>, types: ~[@ast::Ty]) -> @ast::Path { @ast::Path { span: sp, global: true, idents: idents, - rp: None, + rp: rp, types: types } } +pub fn mk_path_raw(cx: @ext_ctxt, sp: span, path: @ast::Path)-> @ast::expr { + mk_expr(cx, sp, ast::expr_path(path)) +} pub fn mk_path(cx: @ext_ctxt, sp: span, idents: ~[ast::ident]) -> @ast::expr { - mk_expr(cx, sp, ast::expr_path(mk_raw_path(sp, idents))) + mk_path_raw(cx, sp, mk_raw_path(sp, idents)) } pub fn mk_path_global(cx: @ext_ctxt, sp: span, idents: ~[ast::ident]) -> @ast::expr { - mk_expr(cx, sp, ast::expr_path(mk_raw_path_global(sp, idents))) + mk_path_raw(cx, sp, mk_raw_path_global(sp, idents)) } pub fn mk_access_(cx: @ext_ctxt, sp: span, p: @ast::expr, m: ast::ident) -> @ast::expr { @@ -354,44 +364,69 @@ pub fn mk_stmt(cx: @ext_ctxt, span: span, expr: @ast::expr) -> @ast::stmt { let stmt_ = ast::stmt_semi(expr, cx.next_id()); @codemap::spanned { node: stmt_, span: span } } + +pub fn mk_ty_mt(ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt { + ast::mt { + ty: ty, + mutbl: mutbl + } +} + +pub fn mk_ty(cx: @ext_ctxt, + span: span, + ty: ast::ty_) -> @ast::Ty { + @ast::Ty { + id: cx.next_id(), + span: span, + node: ty + } +} + pub fn mk_ty_path(cx: @ext_ctxt, span: span, idents: ~[ ast::ident ]) -> @ast::Ty { let ty = build::mk_raw_path(span, idents); - let ty = ast::ty_path(ty, cx.next_id()); - let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span }; - ty + mk_ty_path_path(cx, span, ty) } + pub fn mk_ty_path_global(cx: @ext_ctxt, span: span, idents: ~[ ast::ident ]) -> @ast::Ty { let ty = build::mk_raw_path_global(span, idents); - let ty = ast::ty_path(ty, cx.next_id()); - let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span }; - ty + mk_ty_path_path(cx, span, ty) +} + +pub fn mk_ty_path_path(cx: @ext_ctxt, + span: span, + path: @ast::Path) + -> @ast::Ty { + let ty = ast::ty_path(path, cx.next_id()); + mk_ty(cx, span, ty) } + pub fn mk_ty_rptr(cx: @ext_ctxt, span: span, ty: @ast::Ty, + lifetime: Option<@ast::Lifetime>, mutbl: ast::mutability) -> @ast::Ty { - @ast::Ty { - id: cx.next_id(), - span: span, - node: ast::ty_rptr( - None, - ast::mt { ty: ty, mutbl: mutbl } - ), - } + mk_ty(cx, span, + ast::ty_rptr(lifetime, mk_ty_mt(ty, mutbl))) +} +pub fn mk_ty_uniq(cx: @ext_ctxt, span: span, ty: @ast::Ty) -> @ast::Ty { + mk_ty(cx, span, ast::ty_uniq(mk_ty_mt(ty, ast::m_imm))) +} +pub fn mk_ty_box(cx: @ext_ctxt, span: span, + ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty { + mk_ty(cx, span, ast::ty_box(mk_ty_mt(ty, mutbl))) } + + + pub fn mk_ty_infer(cx: @ext_ctxt, span: span) -> @ast::Ty { - @ast::Ty { - id: cx.next_id(), - node: ast::ty_infer, - span: span, - } + mk_ty(cx, span, ast::ty_infer) } pub fn mk_trait_ref_global(cx: @ext_ctxt, span: span, @@ -482,3 +517,20 @@ pub fn mk_unreachable(cx: @ext_ctxt, span: span) -> @ast::expr { pub fn mk_unreachable_arm(cx: @ext_ctxt, span: span) -> ast::arm { mk_arm(cx, span, ~[mk_pat_wild(cx, span)], mk_unreachable(cx, span)) } + +// +// Duplication functions +// +// These functions just duplicate AST nodes. +// + +pub fn duplicate_expr(cx: @ext_ctxt, expr: @ast::expr) -> @ast::expr { + let folder = fold::default_ast_fold(); + let folder = @fold::AstFoldFns { + new_id: |_| cx.next_id(), + ..*folder + }; + let folder = fold::make_fold(folder); + folder.fold_expr(expr) +} + diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index d996bca60a3..1c33fe35070 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -13,7 +13,6 @@ use codemap::span; use ext::base::ext_ctxt; use ext::build; use ext::deriving::generic::*; -use core::option::{None,Some}; pub fn expand_deriving_clone(cx: @ext_ctxt, @@ -22,13 +21,16 @@ pub fn expand_deriving_clone(cx: @ext_ctxt, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { - path: ~[~"core", ~"clone", ~"Clone"], + path: Path::new(~[~"core", ~"clone", ~"Clone"]), additional_bounds: ~[], + generics: LifetimeBounds::empty(), methods: ~[ MethodDef { name: ~"clone", - nargs: 0, - output_type: None, // return Self + generics: LifetimeBounds::empty(), + self_ty: borrowed_explicit_self(), + args: ~[], + ret_ty: Self, const_nonmatching: false, combine_substructure: cs_clone } @@ -66,7 +68,8 @@ fn cs_clone(cx: @ext_ctxt, span: span, ctor_ident = ~[ variant.node.name ]; all_fields = af; }, - EnumNonMatching(*) => cx.bug("Non-matching enum variants in `deriving(Clone)`") + EnumNonMatching(*) => cx.span_bug(span, "Non-matching enum variants in `deriving(Clone)`"), + StaticEnum(*) | StaticStruct(*) => cx.span_bug(span, "Static method in `deriving(Clone)`") } match all_fields { diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index c0060cc67dc..e431e1f78bf 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -8,15 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use ast::{meta_item, item, expr}; use codemap::span; use ext::base::ext_ctxt; use ext::build; use ext::deriving::generic::*; -use core::option::Some; - pub fn expand_deriving_eq(cx: @ext_ctxt, span: span, mitem: @meta_item, @@ -24,28 +21,32 @@ pub fn expand_deriving_eq(cx: @ext_ctxt, // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different fn cs_eq(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr { - cs_and(|cx, span, _| build::mk_bool(cx, span, false), + cs_and(|cx, span, _, _| build::mk_bool(cx, span, false), cx, span, substr) } fn cs_ne(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr { - cs_or(|cx, span, _| build::mk_bool(cx, span, true), + cs_or(|cx, span, _, _| build::mk_bool(cx, span, true), cx, span, substr) } + macro_rules! md ( ($name:expr, $f:ident) => { MethodDef { name: $name, - output_type: Some(~[~"bool"]), - nargs: 1, + generics: LifetimeBounds::empty(), + self_ty: borrowed_explicit_self(), + args: ~[borrowed_self()], + ret_ty: Literal(Path::new(~[~"bool"])), const_nonmatching: true, combine_substructure: $f }, } - ) + ); let trait_def = TraitDef { - path: ~[~"core", ~"cmp", ~"Eq"], + path: Path::new(~[~"core", ~"cmp", ~"Eq"]), additional_bounds: ~[], + generics: LifetimeBounds::empty(), methods: ~[ md!(~"eq", cs_eq), md!(~"ne", cs_ne) diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 398e27eb3e3..5998fc7145d 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -14,29 +14,33 @@ use codemap::span; use ext::base::ext_ctxt; use ext::build; use ext::deriving::generic::*; -use core::option::Some; - -macro_rules! md { - ($name:expr, $less:expr, $equal:expr) => { - MethodDef { - name: $name, - output_type: Some(~[~"bool"]), - nargs: 1, - const_nonmatching: false, - combine_substructure: |cx, span, substr| - cs_ord($less, $equal, cx, span, substr) - } - } -} pub fn expand_deriving_ord(cx: @ext_ctxt, span: span, mitem: @meta_item, in_items: ~[@item]) -> ~[@item] { + macro_rules! md ( + ($name:expr, $less:expr, $equal:expr) => { + MethodDef { + name: $name, + generics: LifetimeBounds::empty(), + self_ty: borrowed_explicit_self(), + args: ~[borrowed_self()], + ret_ty: Literal(Path::new(~[~"bool"])), + const_nonmatching: false, + combine_substructure: |cx, span, substr| + cs_ord($less, $equal, cx, span, substr) + } + } + ); + + + let trait_def = TraitDef { - path: ~[~"core", ~"cmp", ~"Ord"], + path: Path::new(~[~"core", ~"cmp", ~"Ord"]), // XXX: Ord doesn't imply Eq yet - additional_bounds: ~[~[~"core", ~"cmp", ~"Eq"]], + additional_bounds: ~[Literal(Path::new(~[~"core", ~"cmp", ~"Eq"]))], + generics: LifetimeBounds::empty(), methods: ~[ md!(~"lt", true, false), md!(~"le", true, true), @@ -97,19 +101,19 @@ fn cs_ord(less: bool, equal: bool, } let cmp = build::mk_method_call(cx, span, - self_f, cx.ident_of(~"eq"), other_fs); + self_f, cx.ident_of(~"eq"), other_fs.to_owned()); let subexpr = build::mk_simple_block(cx, span, subexpr); let elseif = expr_if(cmp, subexpr, Some(false_blk_expr)); let elseif = build::mk_expr(cx, span, elseif); let cmp = build::mk_method_call(cx, span, - self_f, binop, other_fs); + self_f, binop, other_fs.to_owned()); let if_ = expr_if(cmp, true_blk, Some(elseif)); build::mk_expr(cx, span, if_) }, base, - |cx, span, args| { + |cx, span, args, _| { // nonmatching enums, order by the order the variants are // written match args { diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index fc8ec103a60..068a7bc06b1 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -15,26 +15,27 @@ use ext::base::ext_ctxt; use ext::build; use ext::deriving::generic::*; -use core::option::Some; - pub fn expand_deriving_totaleq(cx: @ext_ctxt, span: span, mitem: @meta_item, in_items: ~[@item]) -> ~[@item] { fn cs_equals(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr { - cs_and(|cx, span, _| build::mk_bool(cx, span, false), + cs_and(|cx, span, _, _| build::mk_bool(cx, span, false), cx, span, substr) } let trait_def = TraitDef { - path: ~[~"core", ~"cmp", ~"TotalEq"], + path: Path::new(~[~"core", ~"cmp", ~"TotalEq"]), additional_bounds: ~[], + generics: LifetimeBounds::empty(), methods: ~[ MethodDef { name: ~"equals", - output_type: Some(~[~"bool"]), - nargs: 1, + generics: LifetimeBounds::empty(), + self_ty: borrowed_explicit_self(), + args: ~[borrowed_self()], + ret_ty: Literal(Path::new(~[~"bool"])), const_nonmatching: true, combine_substructure: cs_equals } diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index a098a7463d3..ac873c5bd12 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -14,20 +14,22 @@ use ext::base::ext_ctxt; use ext::build; use ext::deriving::generic::*; use core::cmp::{Ordering, Equal, Less, Greater}; -use core::option::Some; pub fn expand_deriving_totalord(cx: @ext_ctxt, span: span, mitem: @meta_item, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { - path: ~[~"core", ~"cmp", ~"TotalOrd"], + path: Path::new(~[~"core", ~"cmp", ~"TotalOrd"]), additional_bounds: ~[], + generics: LifetimeBounds::empty(), methods: ~[ MethodDef { name: ~"cmp", - output_type: Some(~[~"core", ~"cmp", ~"Ordering"]), - nargs: 1, + generics: LifetimeBounds::empty(), + self_ty: borrowed_explicit_self(), + args: ~[borrowed_self()], + ret_ty: Literal(Path::new(~[~"core", ~"cmp", ~"Ordering"])), const_nonmatching: false, combine_substructure: cs_cmp } @@ -64,7 +66,7 @@ pub fn cs_cmp(cx: @ext_ctxt, span: span, build::mk_call_global(cx, span, lexical_ord, ~[old, new]) }, ordering_const(cx, span, Equal), - |cx, span, list| { + |cx, span, list, _| { match list { // an earlier nonmatching variant is Less than a // later one diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index fe270abc2e4..2bdfe51c50e 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -66,6 +66,7 @@ fn create_derived_decodable_impl( cx.ident_of(~"serialize"), cx.ident_of(~"Decodable") ], + None, ~[ build::mk_simple_ty_path(cx, span, cx.ident_of(~"__D")) ] @@ -77,7 +78,7 @@ fn create_derived_decodable_impl( generics, methods, trait_path, - generic_ty_params, + Generics { ty_params: generic_ty_params, lifetimes: opt_vec::Empty }, opt_vec::Empty ) } @@ -96,6 +97,7 @@ fn create_decode_method( cx, span, build::mk_simple_ty_path(cx, span, cx.ident_of(~"__D")), + None, ast::m_mutbl ); let d_ident = cx.ident_of(~"__d"); @@ -278,7 +280,7 @@ fn expand_deriving_decodable_struct_method( let mut fields = ~[]; for struct_def.fields.each |struct_field| { match struct_field.node.kind { - named_field(ident, _, _) => { + named_field(ident, _) => { fields.push(create_read_struct_field(cx, span, i, ident)); } unnamed_field => { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 8f8139790ad..54e5687f415 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -66,6 +66,7 @@ fn create_derived_encodable_impl( cx.ident_of(~"serialize"), cx.ident_of(~"Encodable") ], + None, ~[ build::mk_simple_ty_path(cx, span, cx.ident_of(~"__E")) ] @@ -77,7 +78,7 @@ fn create_derived_encodable_impl( generics, methods, trait_path, - generic_ty_params, + Generics { ty_params: generic_ty_params, lifetimes: opt_vec::Empty }, opt_vec::Empty ) } @@ -94,6 +95,7 @@ fn create_encode_method( cx, span, build::mk_simple_ty_path(cx, span, cx.ident_of(~"__E")), + None, ast::m_mutbl ); let e_arg = build::mk_arg(cx, span, cx.ident_of(~"__e"), e_arg_type); @@ -209,7 +211,7 @@ fn expand_deriving_encodable_struct_method( let mut statements = ~[]; for struct_def.fields.each |struct_field| { match struct_field.node.kind { - named_field(ident, _, _) => { + named_field(ident, _) => { // Create the accessor for this field. let self_field = build::mk_access( cx, @@ -303,7 +305,7 @@ fn expand_deriving_encodable_enum_method( // Create the arms of the match in the method body. let arms = do enum_definition.variants.mapi |i, variant| { // Create the matching pattern. - let pat = create_enum_variant_pattern(cx, span, variant, ~"__self"); + let (pat, fields) = create_enum_variant_pattern(cx, span, variant, ~"__self", ast::m_imm); // Feed the discriminant to the encode function. let mut stmts = ~[]; @@ -311,11 +313,7 @@ fn expand_deriving_encodable_enum_method( // Feed each argument in this variant to the encode function // as well. let variant_arg_len = variant_arg_count(cx, span, variant); - for uint::range(0, variant_arg_len) |j| { - // Create the expression for this field. - let field_ident = cx.ident_of(~"__self_" + j.to_str()); - let field = build::mk_path(cx, span, ~[ field_ident ]); - + for fields.eachi |j, &(_, field)| { // Call the substructure method. let expr = call_substructure_encode_method(cx, span, field); diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 05941f4cbd6..d785f3816de 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -16,23 +16,22 @@ access to the fields of the 4 different sorts of structs and enum variants, as well as creating the method and impl ast instances. Supported features (fairly exhaustive): -- Methods taking any number of parameters of type `&Self`, including - none other than `self`. (`MethodDef.nargs`) -- Methods returning `Self` or a non-parameterised type - (e.g. `bool` or `core::cmp::Ordering`). (`MethodDef.output_type`) -- Generating `impl`s for types with type parameters +- Methods taking any number of parameters of any type, and returning + any type, other than vectors, bottom and closures. +- Generating `impl`s for types with type parameters and lifetimes (e.g. `Option<T>`), the parameters are automatically given the - current trait as a bound. + current trait as a bound. (This includes separate type parameters + and lifetimes for methods.) - Additional bounds on the type parameters, e.g. the `Ord` instance requires an explicit `Eq` bound at the moment. (`TraitDef.additional_bounds`) -(Key unsupported things: methods with arguments of non-`&Self` type, -traits with parameters, methods returning parameterised types, static -methods.) +Unsupported: FIXME #6257: calling methods on borrowed pointer fields, +e.g. deriving TotalEq/TotalOrd/Clone don't work on `struct A(&int)`, +because of how the auto-dereferencing happens. The most important thing for implementers is the `Substructure` and -`SubstructureFields` objects. The latter groups 3 possibilities of the +`SubstructureFields` objects. The latter groups 5 possibilities of the arguments: - `Struct`, when `Self` is a struct (including tuple structs, e.g @@ -42,42 +41,57 @@ arguments: - `EnumNonMatching` when `Self` is an enum and the arguments are not the same variant (e.g. `None`, `Some(1)` and `None`). If `const_nonmatching` is true, this will contain an empty list. +- `StaticEnum` and `StaticStruct` for static methods, where the type + being derived upon is either a enum or struct respectively. (Any + argument with type Self is just grouped among the non-self + arguments.) In the first two cases, the values from the corresponding fields in all the arguments are grouped together. In the `EnumNonMatching` case this isn't possible (different variants have different fields), so the -fields are grouped by which argument they come from. +fields are grouped by which argument they come from. There are no +fields with values in the static cases, so these are treated entirely +differently. -All of the cases have `Option<ident>` in several places associated +The non-static cases have `Option<ident>` in several places associated with field `expr`s. This represents the name of the field it is associated with. It is only not `None` when the associated field has an identifier in the source code. For example, the `x`s in the following snippet - struct A { x : int } +~~~ +struct A { x : int } - struct B(int); +struct B(int); - enum C { - C0(int), - C1 { x: int } - } +enum C { + C0(int), + C1 { x: int } +} The `int`s in `B` and `C0` don't have an identifier, so the `Option<ident>`s would be `None` for them. +In the static cases, the structure is summarised, either into the +number of fields or a list of field idents (for tuple structs and +record structs, respectively), or a list of these, for enums (one for +each variant). For empty struct and empty enum variants, it is +represented as a count of 0. + # Examples The following simplified `Eq` is used for in-code examples: - trait Eq { - fn eq(&self, other: &Self); - } - impl Eq for int { - fn eq(&self, other: &int) -> bool { - *self == *other - } +~~~ +trait Eq { + fn eq(&self, other: &Self); +} +impl Eq for int { + fn eq(&self, other: &int) -> bool { + *self == *other } +} +~~~ Some examples of the values of `SubstructureFields` follow, using the above `Eq`, `A`, `B` and `C`. @@ -86,65 +100,85 @@ above `Eq`, `A`, `B` and `C`. When generating the `expr` for the `A` impl, the `SubstructureFields` is - Struct(~[(Some(<ident of x>), - <expr for self.x>, - ~[<expr for other.x])]) +~~~ +Struct(~[(Some(<ident of x>), + <expr for &self.x>, + ~[<expr for &other.x])]) +~~~ For the `B` impl, called with `B(a)` and `B(b)`, - Struct(~[(None, - <expr for a> - ~[<expr for b>])]) +~~~ +Struct(~[(None, + <expr for &a> + ~[<expr for &b>])]) +~~~ ## Enums When generating the `expr` for a call with `self == C0(a)` and `other == C0(b)`, the SubstructureFields is - EnumMatching(0, <ast::variant for C0>, - ~[None, - <expr for a>, - ~[<expr for b>]]) +~~~ +EnumMatching(0, <ast::variant for C0>, + ~[None, + <expr for &a>, + ~[<expr for &b>]]) +~~~ For `C1 {x}` and `C1 {x}`, - EnumMatching(1, <ast::variant for C1>, - ~[Some(<ident of x>), - <expr for self.x>, - ~[<expr for other.x>]]) +~~~ +EnumMatching(1, <ast::variant for C1>, + ~[Some(<ident of x>), + <expr for &self.x>, + ~[<expr for &other.x>]]) +~~~ For `C0(a)` and `C1 {x}` , - EnumNonMatching(~[(0, <ast::variant for B0>, - ~[(None, <expr for a>)]), - (1, <ast::variant for B1>, - ~[(Some(<ident of x>), - <expr for other.x>)])]) +~~~ +EnumNonMatching(~[(0, <ast::variant for B0>, + ~[(None, <expr for &a>)]), + (1, <ast::variant for B1>, + ~[(Some(<ident of x>), + <expr for &other.x>)])]) +~~~ + +(and vice versa, but with the order of the outermost list flipped.) -(and vice verse, but with the order of the outermost list flipped.) +## Static + +A static method on the above would result in, + +~~~~ +StaticStruct(<ast::struct_def of A>, Right(~[<ident of x>])) + +StaticStruct(<ast::struct_def of B>, Left(1)) + +StaticEnum(<ast::enum_def of C>, ~[(<ident of C0>, Left(1)), + (<ident of C1>, Right(~[<ident of x>]))]) +~~~ */ use ast; +use ast::{enum_def, expr, ident, Generics, struct_def}; -use ast::{ - and, binop, deref, enum_def, expr, expr_match, ident, impure_fn, - item, Generics, m_imm, meta_item, method, named_field, or, - pat_wild, public, struct_def, sty_region, ty_rptr, ty_path, - variant}; - -use ast_util; use ext::base::ext_ctxt; use ext::build; use ext::deriving::*; use codemap::{span,respan}; use opt_vec; +pub use self::ty::*; +mod ty; + pub fn expand_deriving_generic(cx: @ext_ctxt, span: span, - _mitem: @meta_item, - in_items: ~[@item], - trait_def: &TraitDef) -> ~[@item] { + _mitem: @ast::meta_item, + in_items: ~[@ast::item], + trait_def: &TraitDef) -> ~[@ast::item] { let expand_enum: ExpandDerivingEnumDefFn = |cx, span, enum_def, type_ident, generics| { trait_def.expand_enum_def(cx, span, enum_def, type_ident, generics) @@ -160,25 +194,38 @@ pub fn expand_deriving_generic(cx: @ext_ctxt, } pub struct TraitDef<'self> { - /// Path of the trait - path: ~[~str], - /// Additional bounds required of any type parameters, other than - /// the current trait - additional_bounds: ~[~[~str]], + /// Path of the trait, including any type parameters + path: Path, + /// Additional bounds required of any type parameters of the type, + /// other than the current trait + additional_bounds: ~[Ty], + + /// Any extra lifetimes and/or bounds, e.g. `D: std::serialize::Decoder` + generics: LifetimeBounds, + methods: ~[MethodDef<'self>] } + pub struct MethodDef<'self> { /// name of the method name: ~str, - /// The path of return type of the method, e.g. `~[~"core", - /// ~"cmp", ~"Eq"]`. `None` for `Self`. - output_type: Option<~[~str]>, - /// Number of arguments other than `self` (all of type `&Self`) - nargs: uint, + /// List of generics, e.g. `R: core::rand::Rng` + generics: LifetimeBounds, + + /// Whether there is a self argument (outer Option) i.e. whether + /// this is a static function, and whether it is a pointer (inner + /// Option) + self_ty: Option<Option<PtrTy>>, + + /// Arguments other than the self argument + args: ~[Ty], + + /// Return type + ret_ty: Ty, /// if the value of the nonmatching enums is independent of the - /// actual enums, i.e. can use _ => .. match. + /// actual enum variants, i.e. can use _ => .. match. const_nonmatching: bool, combine_substructure: CombineSubstructureFunc<'self> @@ -186,18 +233,24 @@ pub struct MethodDef<'self> { /// All the data about the data structure/method being derived upon. pub struct Substructure<'self> { + /// ident of self type_ident: ident, + /// ident of the method method_ident: ident, - fields: &'self SubstructureFields + /// dereferenced access to any Self or Ptr(Self, _) arguments + self_args: &'self [@expr], + /// verbatim access to any other arguments + nonself_args: &'self [@expr], + fields: &'self SubstructureFields<'self> } /// A summary of the possible sets of fields. See above for details /// and examples -pub enum SubstructureFields { +pub enum SubstructureFields<'self> { /** - Vec of `(field ident, self, [others])` where the field ident is - the ident of the current field (`None` for all fields in tuple - structs) + Vec of `(field ident, self_or_other)` where the field + ident is the ident of the current field (`None` for all fields in tuple + structs). */ Struct(~[(Option<ident>, @expr, ~[@expr])]), @@ -206,17 +259,23 @@ pub enum SubstructureFields { fields: `(field ident, self, [others])`, where the field ident is only non-`None` in the case of a struct variant. */ - EnumMatching(uint, variant, ~[(Option<ident>, @expr, ~[@expr])]), + EnumMatching(uint, ast::variant, ~[(Option<ident>, @expr, ~[@expr])]), /** non-matching variants of the enum, [(variant index, ast::variant, [field ident, fields])] (i.e. all fields for self are in the first tuple, for other1 are in the second tuple, etc.) */ - EnumNonMatching(~[(uint, variant, ~[(Option<ident>, @expr)])]) + EnumNonMatching(~[(uint, ast::variant, ~[(Option<ident>, @expr)])]), + + /// A static method where Self is a struct + StaticStruct(&'self ast::struct_def, Either<uint, ~[ident]>), + /// A static method where Self is an enum + StaticEnum(&'self ast::enum_def, ~[(ident, Either<uint, ~[ident]>)]) } + /** Combine the values of all the fields together. The last argument is all the fields of all the structures, see above for details. @@ -225,31 +284,34 @@ pub type CombineSubstructureFunc<'self> = &'self fn(@ext_ctxt, span, &Substructure) -> @expr; /** -Deal with non-matching enum variants, the argument is a list +Deal with non-matching enum variants, the arguments are a list representing each variant: (variant index, ast::variant instance, -[variant fields]) +[variant fields]), and a list of the nonself args of the type */ pub type EnumNonMatchFunc<'self> = - &'self fn(@ext_ctxt, span, ~[(uint, variant, ~[(Option<ident>, @expr)])]) -> @expr; - + &'self fn(@ext_ctxt, span, + ~[(uint, ast::variant, + ~[(Option<ident>, @expr)])], + &[@expr]) -> @expr; impl<'self> TraitDef<'self> { fn create_derived_impl(&self, cx: @ext_ctxt, span: span, type_ident: ident, generics: &Generics, - methods: ~[@method]) -> @item { - let trait_path = build::mk_raw_path_global( - span, - do self.path.map |&s| { cx.ident_of(s) }); + methods: ~[@ast::method]) -> @ast::item { + let trait_path = self.path.to_path(cx, span, type_ident, generics); + + let trait_generics = self.generics.to_generics(cx, span, type_ident, generics); let additional_bounds = opt_vec::from( - do self.additional_bounds.map |v| { - do v.map |&s| { cx.ident_of(s) } + do self.additional_bounds.map |p| { + p.to_path(cx, span, type_ident, generics) }); + create_derived_impl(cx, span, type_ident, generics, methods, trait_path, - opt_vec::Empty, + trait_generics, additional_bounds) } @@ -257,22 +319,28 @@ impl<'self> TraitDef<'self> { span: span, struct_def: &struct_def, type_ident: ident, - generics: &Generics) - -> @item { - let is_tuple = is_struct_tuple(struct_def); - + generics: &Generics) -> @ast::item { let methods = do self.methods.map |method_def| { - let body = if is_tuple { - method_def.expand_struct_tuple_method_body(cx, span, - struct_def, - type_ident) + let (self_ty, self_args, nonself_args, tys) = + method_def.split_self_nonself_args(cx, span, type_ident, generics); + + let body = if method_def.is_static() { + method_def.expand_static_struct_method_body( + cx, span, + struct_def, + type_ident, + self_args, nonself_args) } else { method_def.expand_struct_method_body(cx, span, struct_def, - type_ident) + type_ident, + self_args, nonself_args) }; - method_def.create_method(cx, span, type_ident, generics, body) + method_def.create_method(cx, span, + type_ident, generics, + self_ty, tys, + body) }; self.create_derived_impl(cx, span, type_ident, generics, methods) @@ -282,13 +350,28 @@ impl<'self> TraitDef<'self> { cx: @ext_ctxt, span: span, enum_def: &enum_def, type_ident: ident, - generics: &Generics) -> @item { + generics: &Generics) -> @ast::item { let methods = do self.methods.map |method_def| { - let body = method_def.expand_enum_method_body(cx, span, - enum_def, - type_ident); + let (self_ty, self_args, nonself_args, tys) = + method_def.split_self_nonself_args(cx, span, type_ident, generics); + + let body = if method_def.is_static() { + method_def.expand_static_enum_method_body( + cx, span, + enum_def, + type_ident, + self_args, nonself_args) + } else { + method_def.expand_enum_method_body(cx, span, + enum_def, + type_ident, + self_args, nonself_args) + }; - method_def.create_method(cx, span, type_ident, generics, body) + method_def.create_method(cx, span, + type_ident, generics, + self_ty, tys, + body) }; self.create_derived_impl(cx, span, type_ident, generics, methods) @@ -300,266 +383,241 @@ impl<'self> MethodDef<'self> { cx: @ext_ctxt, span: span, type_ident: ident, + self_args: &[@expr], + nonself_args: &[@expr], fields: &SubstructureFields) -> @expr { let substructure = Substructure { type_ident: type_ident, method_ident: cx.ident_of(self.name), + self_args: self_args, + nonself_args: nonself_args, fields: fields }; (self.combine_substructure)(cx, span, &substructure) } - fn get_output_type_path(&self, cx: @ext_ctxt, span: span, - generics: &Generics, type_ident: ident) -> @ast::Path { - match self.output_type { - None => { // Self, add any type parameters - let out_ty_params = do vec::build |push| { - for generics.ty_params.each |ty_param| { - push(build::mk_ty_path(cx, span, ~[ ty_param.ident ])); - } - }; + fn get_ret_ty(&self, cx: @ext_ctxt, span: span, + generics: &Generics, type_ident: ident) -> @ast::Ty { + self.ret_ty.to_ty(cx, span, type_ident, generics) + } + + fn is_static(&self) -> bool { + self.self_ty.is_none() + } + + fn split_self_nonself_args(&self, cx: @ext_ctxt, span: span, + type_ident: ident, generics: &Generics) + -> (ast::self_ty, ~[@expr], ~[@expr], ~[(ident, @ast::Ty)]) { + + let mut self_args = ~[], nonself_args = ~[], arg_tys = ~[]; + let mut ast_self_ty = respan(span, ast::sty_static); + let mut nonstatic = false; + + match self.self_ty { + Some(self_ptr) => { + let (self_expr, self_ty) = ty::get_explicit_self(cx, span, self_ptr); - build::mk_raw_path_(span, ~[ type_ident ], out_ty_params) + ast_self_ty = self_ty; + self_args.push(self_expr); + nonstatic = true; } - Some(str_path) => { - let p = do str_path.map |&s| { cx.ident_of(s) }; - build::mk_raw_path_global(span, p) + _ => {} + } + + for self.args.eachi |i, ty| { + let ast_ty = ty.to_ty(cx, span, type_ident, generics); + let ident = cx.ident_of(fmt!("__arg_%u", i)); + arg_tys.push((ident, ast_ty)); + + let arg_expr = build::mk_path(cx, span, ~[ident]); + + match *ty { + // for static methods, just treat any Self + // arguments as a normal arg + Self if nonstatic => { + self_args.push(arg_expr); + } + Ptr(~Self, _) if nonstatic => { + self_args.push(build::mk_deref(cx, span, arg_expr)) + } + _ => { + nonself_args.push(arg_expr); + } } } + + (ast_self_ty, self_args, nonself_args, arg_tys) } fn create_method(&self, cx: @ext_ctxt, span: span, type_ident: ident, - generics: &Generics, body: @expr) -> @method { - // Create the `Self` type of the `other` parameters. - let arg_path_type = create_self_type_with_params(cx, - span, - type_ident, - generics); - let arg_type = ty_rptr( - None, - ast::mt { ty: arg_path_type, mutbl: m_imm } - ); - let arg_type = @ast::Ty { - id: cx.next_id(), - node: arg_type, - span: span, - }; - - // create the arguments - let other_idents = create_other_idents(cx, self.nargs); - let args = do other_idents.map |&id| { - build::mk_arg(cx, span, id, arg_type) + generics: &Generics, + self_ty: ast::self_ty, + arg_types: ~[(ident, @ast::Ty)], + body: @expr) -> @ast::method { + // create the generics that aren't for Self + let fn_generics = self.generics.to_generics(cx, span, type_ident, generics); + + let args = do arg_types.map |&(id, ty)| { + build::mk_arg(cx, span, id, ty) }; - let output_type = self.get_output_type_path(cx, span, generics, type_ident); - let output_type = ty_path(output_type, cx.next_id()); - let output_type = @ast::Ty { - id: cx.next_id(), - node: output_type, - span: span, - }; + let ret_type = self.get_ret_ty(cx, span, generics, type_ident); let method_ident = cx.ident_of(self.name); - let fn_decl = build::mk_fn_decl(args, output_type); + let fn_decl = build::mk_fn_decl(args, ret_type); let body_block = build::mk_simple_block(cx, span, body); + // Create the method. - let self_ty = respan(span, sty_region(None, m_imm)); @ast::method { ident: method_ident, attrs: ~[], - generics: ast_util::empty_generics(), + generics: fn_generics, self_ty: self_ty, - purity: impure_fn, + purity: ast::impure_fn, decl: fn_decl, body: body_block, id: cx.next_id(), span: span, self_id: cx.next_id(), - vis: public + vis: ast::public } } /** - ``` + ~~~ #[deriving(Eq)] - struct A(int, int); + struct A { x: int, y: int } // equivalent to: - impl Eq for A { - fn eq(&self, __other_1: &A) -> bool { + fn eq(&self, __arg_1: &A) -> bool { match *self { - (ref self_1, ref self_2) => { - match *__other_1 { - (ref __other_1_1, ref __other_1_2) => { - self_1.eq(__other_1_1) && self_2.eq(__other_1_2) + A {x: ref __self_0_0, y: ref __self_0_1} => { + match *__arg_1 { + A {x: ref __self_1_0, y: ref __self_1_1} => { + __self_0_0.eq(__self_1_0) && __self_0_1.eq(__self_1_1) } } } } } } - ``` + ~~~ */ - fn expand_struct_tuple_method_body(&self, - cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident) -> @expr { - let self_str = ~"self"; - let other_strs = create_other_strs(self.nargs); - let num_fields = struct_def.fields.len(); - - - let fields = do struct_def.fields.mapi |i, _| { - let other_fields = do other_strs.map |&other_str| { - let other_field_ident = cx.ident_of(fmt!("%s_%u", other_str, i)); - build::mk_path(cx, span, ~[ other_field_ident ]) - }; - - let self_field_ident = cx.ident_of(fmt!("%s_%u", self_str, i)); - let self_field = build::mk_path(cx, span, ~[ self_field_ident ]); + fn expand_struct_method_body(&self, + cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + self_args: &[@expr], + nonself_args: &[@expr]) + -> @expr { - (None, self_field, other_fields) + let mut raw_fields = ~[], // ~[[fields of self], [fields of next Self arg], [etc]] + patterns = ~[]; + for uint::range(0, self_args.len()) |i| { + let (pat, ident_expr) = create_struct_pattern(cx, span, + type_ident, struct_def, + fmt!("__self_%u", i), ast::m_imm); + patterns.push(pat); + raw_fields.push(ident_expr); }; - let mut match_body = self.call_substructure_method(cx, span, type_ident, &Struct(fields)); - - let type_path = build::mk_raw_path(span, ~[type_ident]); - - // create the matches from inside to out (i.e. other_{self.nargs} to other_1) - for other_strs.each_reverse |&other_str| { - match_body = create_deref_match(cx, span, type_path, - other_str, num_fields, - match_body) - } - - // create the match on self - return create_deref_match(cx, span, type_path, - ~"self", num_fields, match_body); - - /** - Creates a match expression against a tuple that needs to - be dereferenced, but nothing else + // transpose raw_fields + let fields = match raw_fields { + [self_arg, .. rest] => { + do self_arg.mapi |i, &(opt_id, field)| { + let other_fields = do rest.map |l| { + match &l[i] { + &(_, ex) => ex + } + }; + (opt_id, field, other_fields) + } + } + [] => { cx.span_bug(span, ~"No self arguments to non-static \ + method in generic `deriving`") } + }; - ``` - match *`to_match` { - (`to_match`_1, ..., `to_match`_`num_fields`) => `match_body` - } - ``` - */ - fn create_deref_match(cx: @ext_ctxt, - span: span, - type_path: @ast::Path, - to_match: ~str, - num_fields: uint, - match_body: @expr) -> @expr { - let match_subpats = create_subpatterns(cx, span, to_match, num_fields); + // body of the inner most destructuring match + let mut body = self.call_substructure_method( + cx, span, + type_ident, + self_args, + nonself_args, + &Struct(fields)); + + // make a series of nested matches, to destructure the + // structs. This is actually right-to-left, but it shoudn't + // matter. + for vec::each2(self_args, patterns) |&arg_expr, &pat| { let match_arm = ast::arm { - pats: ~[ build::mk_pat_enum(cx, span, type_path, match_subpats) ], + pats: ~[ pat ], guard: None, - body: build::mk_simple_block(cx, span, match_body), + body: build::mk_simple_block(cx, span, body) }; - let deref_expr = build::mk_unary(cx, span, deref, - build::mk_path(cx, span, - ~[ cx.ident_of(to_match)])); - let match_expr = build::mk_expr(cx, span, expr_match(deref_expr, ~[match_arm])); - - match_expr + body = build::mk_expr(cx, span, ast::expr_match(arg_expr, ~[match_arm])) } + body } - /** - ``` - #[deriving(Eq)] - struct A { x: int, y: int } - - // equivalent to: - - impl Eq for A { - fn eq(&self, __other_1: &A) -> bool { - self.x.eq(&__other_1.x) && - self.y.eq(&__other_1.y) - } - } - ``` - */ - fn expand_struct_method_body(&self, - cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident) + fn expand_static_struct_method_body(&self, + cx: @ext_ctxt, + span: span, + struct_def: &struct_def, + type_ident: ident, + self_args: &[@expr], + nonself_args: &[@expr]) -> @expr { - let self_ident = cx.ident_of(~"self"); - let other_idents = create_other_idents(cx, self.nargs); - - let fields = do struct_def.fields.map |struct_field| { - match struct_field.node.kind { - named_field(ident, _, _) => { - // Create the accessor for this field in the other args. - let other_fields = do other_idents.map |&id| { - build::mk_access(cx, span, ~[id], ident) - }; - let other_field_refs = do other_fields.map |&other_field| { - build::mk_addr_of(cx, span, other_field) - }; - - // Create the accessor for this field in self. - let self_field = - build::mk_access( - cx, span, - ~[ self_ident ], - ident); + let summary = summarise_struct(cx, span, struct_def); - (Some(ident), self_field, other_field_refs) - } - unnamed_field => { - cx.span_unimpl(span, ~"unnamed fields with `deriving_generic`"); - } - } - }; - - self.call_substructure_method(cx, span, type_ident, &Struct(fields)) + self.call_substructure_method(cx, span, + type_ident, + self_args, nonself_args, + &StaticStruct(struct_def, summary)) } /** - ``` + ~~~ #[deriving(Eq)] enum A { A1 A2(int) } - // is equivalent to + // is equivalent to (with const_nonmatching == false) impl Eq for A { - fn eq(&self, __other_1: &A) { + fn eq(&self, __arg_1: &A) { match *self { - A1 => match *__other_1 { - A1 => true, - A2(ref __other_1_1) => false + A1 => match *__arg_1 { + A1 => true + A2(ref __arg_1_1) => false }, - A2(self_1) => match *__other_1 { + A2(self_1) => match *__arg_1 { A1 => false, - A2(ref __other_1_1) => self_1.eq(__other_1_1) + A2(ref __arg_1_1) => self_1.eq(__arg_1_1) } } } } - ``` + ~~~ */ fn expand_enum_method_body(&self, cx: @ext_ctxt, span: span, enum_def: &enum_def, - type_ident: ident) + type_ident: ident, + self_args: &[@expr], + nonself_args: &[@expr]) -> @expr { self.build_enum_match(cx, span, enum_def, type_ident, + self_args, nonself_args, None, ~[], 0) } @@ -567,13 +625,13 @@ impl<'self> MethodDef<'self> { /** Creates the nested matches for an enum definition recursively, i.e. - ``` + ~~~ match self { Variant1 => match other { Variant1 => matching, Variant2 => nonmatching, ... }, Variant2 => match other { Variant1 => nonmatching, Variant2 => matching, ... }, ... } - ``` + ~~~ It acts in the most naive way, so every branch (and subbranch, subsubbranch, etc) exists, not just the ones where all the variants in @@ -589,15 +647,17 @@ impl<'self> MethodDef<'self> { cx: @ext_ctxt, span: span, enum_def: &enum_def, type_ident: ident, + self_args: &[@expr], + nonself_args: &[@expr], matching: Option<uint>, - matches_so_far: ~[(uint, variant, + matches_so_far: ~[(uint, ast::variant, ~[(Option<ident>, @expr)])], match_count: uint) -> @expr { - if match_count == self.nargs + 1 { + if match_count == self_args.len() { // we've matched against all arguments, so make the final // expression at the bottom of the match tree match matches_so_far { - [] => cx.bug(~"no self match on an enum in `deriving_generic`"), + [] => cx.span_bug(span, ~"no self match on an enum in generic `deriving`"), _ => { // we currently have a vec of vecs, where each // subvec is the fields of one of the arguments, @@ -637,16 +697,17 @@ impl<'self> MethodDef<'self> { substructure = EnumNonMatching(matches_so_far); } } - self.call_substructure_method(cx, span, type_ident, &substructure) + self.call_substructure_method(cx, span, type_ident, + self_args, nonself_args, + &substructure) } } } else { // there are still matches to create - let (current_match_ident, current_match_str) = if match_count == 0 { - (cx.ident_of(~"self"), ~"__self") + let current_match_str = if match_count == 0 { + ~"__self" } else { - let s = fmt!("__other_%u", matches_so_far.len() - 1); - (cx.ident_of(s), s) + fmt!("__arg_%u", match_count) }; let mut arms = ~[]; @@ -654,80 +715,50 @@ impl<'self> MethodDef<'self> { // this is used as a stack let mut matches_so_far = matches_so_far; - macro_rules! mk_arm( - ($pat:expr, $expr:expr) => { - { - let blk = build::mk_simple_block(cx, span, $expr); - let arm = ast::arm { - pats: ~[$ pat ], - guard: None, - body: blk - }; - arm - } - } - ) - // the code for nonmatching variants only matters when // we've seen at least one other variant already if self.const_nonmatching && match_count > 0 { // make a matching-variant match, and a _ match. let index = match matching { Some(i) => i, - None => cx.span_bug(span, ~"Non-matching variants when required to\ - be matching in `deriving_generic`") + None => cx.span_bug(span, ~"Non-matching variants when required to \ + be matching in generic `deriving`") }; // matching-variant match let variant = &enum_def.variants[index]; - let pattern = create_enum_variant_pattern(cx, span, - variant, - current_match_str); - - let idents = do vec::build |push| { - for each_variant_arg_ident(cx, span, variant) |i, field_id| { - let id = cx.ident_of(fmt!("%s_%u", current_match_str, i)); - push((field_id, build::mk_path(cx, span, ~[ id ]))); - } - }; + let (pattern, idents) = create_enum_variant_pattern(cx, span, + variant, + current_match_str, + ast::m_imm); matches_so_far.push((index, *variant, idents)); let arm_expr = self.build_enum_match(cx, span, enum_def, type_ident, + self_args, nonself_args, matching, matches_so_far, match_count + 1); matches_so_far.pop(); - let arm = mk_arm!(pattern, arm_expr); - arms.push(arm); + arms.push(build::mk_arm(cx, span, ~[ pattern ], arm_expr)); if enum_def.variants.len() > 1 { - // _ match, if necessary - let wild_pat = @ast::pat { - id: cx.next_id(), - node: pat_wild, - span: span - }; - let wild_expr = self.call_substructure_method(cx, span, type_ident, + self_args, nonself_args, &EnumNonMatching(~[])); - let wild_arm = mk_arm!(wild_pat, wild_expr); + let wild_arm = build::mk_arm(cx, span, + ~[ build::mk_pat_wild(cx, span) ], + wild_expr); arms.push(wild_arm); } } else { // create an arm matching on each variant for enum_def.variants.eachi |index, variant| { - let pattern = create_enum_variant_pattern(cx, span, - variant, - current_match_str); - - let idents = do vec::build |push| { - for each_variant_arg_ident(cx, span, variant) |i, field_id| { - let id = cx.ident_of(fmt!("%s_%u", current_match_str, i)); - push((field_id, build::mk_path(cx, span, ~[ id ]))); - } - }; + let (pattern, idents) = create_enum_variant_pattern(cx, span, + variant, + current_match_str, + ast::m_imm); matches_so_far.push((index, *variant, idents)); let new_matching = @@ -739,44 +770,71 @@ impl<'self> MethodDef<'self> { let arm_expr = self.build_enum_match(cx, span, enum_def, type_ident, + self_args, nonself_args, new_matching, matches_so_far, match_count + 1); matches_so_far.pop(); - let arm = mk_arm!(pattern, arm_expr); + let arm = build::mk_arm(cx, span, ~[ pattern ], arm_expr); arms.push(arm); } } - let deref_expr = build::mk_unary(cx, span, deref, - build::mk_path(cx, span, - ~[ current_match_ident ])); - let match_expr = build::mk_expr(cx, span, - expr_match(deref_expr, arms)); - match_expr + // match foo { arm, arm, arm, ... } + build::mk_expr(cx, span, + ast::expr_match(self_args[match_count], arms)) } } + + fn expand_static_enum_method_body(&self, + cx: @ext_ctxt, + span: span, + enum_def: &enum_def, + type_ident: ident, + self_args: &[@expr], + nonself_args: &[@expr]) + -> @expr { + let summary = do enum_def.variants.map |v| { + let ident = v.node.name; + let summary = match v.node.kind { + ast::tuple_variant_kind(ref args) => Left(args.len()), + ast::struct_variant_kind(struct_def) => { + summarise_struct(cx, span, struct_def) + } + }; + (ident, summary) + }; + self.call_substructure_method(cx, + span, type_ident, + self_args, nonself_args, + &StaticEnum(enum_def, summary)) + } } -/// Create variable names (as strings) to refer to the non-self -/// parameters -fn create_other_strs(n: uint) -> ~[~str] { - do vec::build |push| { - for uint::range(0, n) |i| { - push(fmt!("__other_%u", i)); +fn summarise_struct(cx: @ext_ctxt, span: span, + struct_def: &struct_def) -> Either<uint, ~[ident]> { + let mut named_idents = ~[]; + let mut unnamed_count = 0; + for struct_def.fields.each |field| { + match field.node.kind { + ast::named_field(ident, _) => named_idents.push(ident), + ast::unnamed_field => unnamed_count += 1, } } -} -/// Like `create_other_strs`, but returns idents for the strings -fn create_other_idents(cx: @ext_ctxt, n: uint) -> ~[ident] { - do create_other_strs(n).map |&s| { - cx.ident_of(s) + + match (unnamed_count > 0, named_idents.is_empty()) { + (true, false) => cx.span_bug(span, + "A struct with named and unnamed \ + fields in generic `deriving`"), + // named fields + (_, false) => Right(named_idents), + // tuple structs (includes empty structs) + (_, _) => Left(unnamed_count) } } - /* helpful premade recipes */ /** @@ -786,7 +844,7 @@ left-to-right (`true`) or right-to-left (`false`). pub fn cs_fold(use_foldl: bool, f: &fn(@ext_ctxt, span, old: @expr, - self_f: @expr, other_fs: ~[@expr]) -> @expr, + self_f: @expr, other_fs: &[@expr]) -> @expr, base: @expr, enum_nonmatch_f: EnumNonMatchFunc, cx: @ext_ctxt, span: span, @@ -803,7 +861,11 @@ pub fn cs_fold(use_foldl: bool, } } }, - EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span, all_enums) + EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span, + all_enums, substructure.nonself_args), + StaticEnum(*) | StaticStruct(*) => { + cx.span_bug(span, "Static function in `deriving`") + } } } @@ -812,11 +874,12 @@ pub fn cs_fold(use_foldl: bool, Call the method that is being derived on all the fields, and then process the collected results. i.e. -``` -f(cx, span, ~[self_1.method(__other_1_1, __other_2_1), - self_2.method(__other_1_2, __other_2_2)]) -``` +~~~ +f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1), + self_2.method(__arg_1_2, __arg_2_2)]) +~~~ */ +#[inline(always)] pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr, enum_nonmatch_f: EnumNonMatchFunc, cx: @ext_ctxt, span: span, @@ -833,7 +896,11 @@ pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr, f(cx, span, called) }, - EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span, all_enums) + EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span, + all_enums, substructure.nonself_args), + StaticEnum(*) | StaticStruct(*) => { + cx.span_bug(span, "Static function in `deriving`") + } } } @@ -842,6 +909,7 @@ Fold together the results of calling the derived method on all the fields. `use_foldl` controls whether this is done left-to-right (`true`) or right-to-left (`false`). */ +#[inline(always)] pub fn cs_same_method_fold(use_foldl: bool, f: &fn(@ext_ctxt, span, @expr, @expr) -> @expr, base: @expr, @@ -869,7 +937,8 @@ pub fn cs_same_method_fold(use_foldl: bool, Use a given binop to combine the result of calling the derived method on all the fields. */ -pub fn cs_binop(binop: binop, base: @expr, +#[inline(always)] +pub fn cs_binop(binop: ast::binop, base: @expr, enum_nonmatch_f: EnumNonMatchFunc, cx: @ext_ctxt, span: span, substructure: &Substructure) -> @expr { @@ -887,18 +956,20 @@ pub fn cs_binop(binop: binop, base: @expr, } /// cs_binop with binop == or +#[inline(always)] pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc, cx: @ext_ctxt, span: span, substructure: &Substructure) -> @expr { - cs_binop(or, build::mk_bool(cx, span, false), + cs_binop(ast::or, build::mk_bool(cx, span, false), enum_nonmatch_f, cx, span, substructure) } /// cs_binop with binop == and +#[inline(always)] pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc, cx: @ext_ctxt, span: span, substructure: &Substructure) -> @expr { - cs_binop(and, build::mk_bool(cx, span, true), + cs_binop(ast::and, build::mk_bool(cx, span, true), enum_nonmatch_f, cx, span, substructure) } diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index f03306ea07a..3d66506d6ca 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,25 +8,37 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast; -use ast::*; +use ast::{meta_item, item, expr}; +use codemap::span; use ext::base::ext_ctxt; use ext::build; -use ext::deriving::*; -use codemap::{span, spanned}; -use ast_util; -use opt_vec; +use ext::deriving::generic::*; pub fn expand_deriving_iter_bytes(cx: @ext_ctxt, span: span, - _mitem: @meta_item, - in_items: ~[@item]) - -> ~[@item] { - expand_deriving(cx, - span, - in_items, - expand_deriving_iter_bytes_struct_def, - expand_deriving_iter_bytes_enum_def) + mitem: @meta_item, + in_items: ~[@item]) -> ~[@item] { + let trait_def = TraitDef { + path: Path::new(~[~"core", ~"to_bytes", ~"IterBytes"]), + additional_bounds: ~[], + generics: LifetimeBounds::empty(), + methods: ~[ + MethodDef { + name: ~"iter_bytes", + generics: LifetimeBounds::empty(), + self_ty: borrowed_explicit_self(), + args: ~[ + Literal(Path::new(~[~"bool"])), + Literal(Path::new(~[~"core", ~"to_bytes", ~"Cb"])) + ], + ret_ty: nil_ty(), + const_nonmatching: false, + combine_substructure: iter_bytes_substructure + } + ] + }; + + expand_deriving_generic(cx, span, mitem, in_items, &trait_def) } pub fn expand_deriving_obsolete(cx: @ext_ctxt, @@ -39,217 +51,43 @@ pub fn expand_deriving_obsolete(cx: @ext_ctxt, in_items } -fn create_derived_iter_bytes_impl(cx: @ext_ctxt, - span: span, - type_ident: ident, - generics: &Generics, - method: @method) - -> @item { - let methods = [ method ]; - let trait_path = ~[ - cx.ident_of(~"core"), - cx.ident_of(~"to_bytes"), - cx.ident_of(~"IterBytes") - ]; - let trait_path = build::mk_raw_path_global(span, trait_path); - create_derived_impl(cx, span, type_ident, generics, methods, trait_path, - opt_vec::Empty, opt_vec::Empty) -} - -// Creates a method from the given set of statements conforming to the -// signature of the `iter_bytes` method. -fn create_iter_bytes_method(cx: @ext_ctxt, - span: span, - statements: ~[@stmt]) - -> @method { - // Create the `lsb0` parameter. - let bool_ident = cx.ident_of(~"bool"); - let lsb0_arg_type = build::mk_simple_ty_path(cx, span, bool_ident); - let lsb0_ident = cx.ident_of(~"__lsb0"); - let lsb0_arg = build::mk_arg(cx, span, lsb0_ident, lsb0_arg_type); - - // Create the `f` parameter. - let core_ident = cx.ident_of(~"core"); - let to_bytes_ident = cx.ident_of(~"to_bytes"); - let cb_ident = cx.ident_of(~"Cb"); - let core_to_bytes_cb_ident = ~[ core_ident, to_bytes_ident, cb_ident ]; - let f_arg_type = build::mk_ty_path(cx, span, core_to_bytes_cb_ident); - let f_ident = cx.ident_of(~"__f"); - let f_arg = build::mk_arg(cx, span, f_ident, f_arg_type); - - // Create the type of the return value. - let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span }; - - // Create the function declaration. - let inputs = ~[ lsb0_arg, f_arg ]; - let fn_decl = build::mk_fn_decl(inputs, output_type); - - // Create the body block. - let body_block = build::mk_block_(cx, span, statements); - - // Create the method. - let self_ty = spanned { node: sty_region(None, m_imm), span: span }; - let method_ident = cx.ident_of(~"iter_bytes"); - @ast::method { - ident: method_ident, - attrs: ~[], - generics: ast_util::empty_generics(), - self_ty: self_ty, - purity: impure_fn, - decl: fn_decl, - body: body_block, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: public - } -} - -fn call_substructure_iter_bytes_method(cx: @ext_ctxt, - span: span, - self_field: @expr) - -> @stmt { - // Gather up the parameters we want to chain along. - let lsb0_ident = cx.ident_of(~"__lsb0"); - let f_ident = cx.ident_of(~"__f"); - let lsb0_expr = build::mk_path(cx, span, ~[ lsb0_ident ]); - let f_expr = build::mk_path(cx, span, ~[ f_ident ]); - - // Call the substructure method. - let iter_bytes_ident = cx.ident_of(~"iter_bytes"); - let self_call = build::mk_method_call(cx, - span, - self_field, - iter_bytes_ident, - ~[ lsb0_expr, f_expr ]); - - // Create a statement out of this expression. - build::mk_stmt(cx, span, self_call) -} - -fn expand_deriving_iter_bytes_struct_def(cx: @ext_ctxt, - span: span, - struct_def: &struct_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the method. - let method = expand_deriving_iter_bytes_struct_method(cx, - span, - struct_def); - - // Create the implementation. - return create_derived_iter_bytes_impl(cx, - span, - type_ident, - generics, - method); -} - -fn expand_deriving_iter_bytes_enum_def(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def, - type_ident: ident, - generics: &Generics) - -> @item { - // Create the method. - let method = expand_deriving_iter_bytes_enum_method(cx, - span, - enum_definition); - - // Create the implementation. - return create_derived_iter_bytes_impl(cx, - span, - type_ident, - generics, - method); -} - -fn expand_deriving_iter_bytes_struct_method(cx: @ext_ctxt, - span: span, - struct_def: &struct_def) - -> @method { - let self_ident = cx.ident_of(~"self"); - - // Create the body of the method. - let mut statements = ~[]; - for struct_def.fields.each |struct_field| { - match struct_field.node.kind { - named_field(ident, _, _) => { - // Create the accessor for this field. - let self_field = build::mk_access(cx, - span, - ~[ self_ident ], - ident); - - // Call the substructure method. - let stmt = call_substructure_iter_bytes_method(cx, - span, - self_field); - statements.push(stmt); - } - unnamed_field => { - cx.span_unimpl(span, - ~"unnamed fields with `deriving(IterBytes)`"); - } - } - } - - // Create the method itself. - return create_iter_bytes_method(cx, span, statements); -} - -fn expand_deriving_iter_bytes_enum_method(cx: @ext_ctxt, - span: span, - enum_definition: &enum_def) - -> @method { - // Create the arms of the match in the method body. - let arms = do enum_definition.variants.mapi |i, variant| { - // Create the matching pattern. - let pat = create_enum_variant_pattern(cx, span, variant, ~"__self"); - - // Determine the discriminant. We will feed this value to the byte - // iteration function. - let discriminant; - match variant.node.disr_expr { - Some(copy disr_expr) => discriminant = disr_expr, - None => discriminant = build::mk_uint(cx, span, i), - } - - // Feed the discriminant to the byte iteration function. - let mut stmts = ~[]; - let discrim_stmt = call_substructure_iter_bytes_method(cx, - span, - discriminant); - stmts.push(discrim_stmt); - - // Feed each argument in this variant to the byte iteration function - // as well. - for uint::range(0, variant_arg_count(cx, span, variant)) |j| { - // Create the expression for this field. - let field_ident = cx.ident_of(~"__self_" + j.to_str()); - let field = build::mk_path(cx, span, ~[ field_ident ]); - - // Call the substructure method. - let stmt = call_substructure_iter_bytes_method(cx, span, field); - stmts.push(stmt); +fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr { + let lsb0_f = match substr.nonself_args { + [l, f] => ~[l, f], + _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`") + }; + let iter_bytes_ident = substr.method_ident; + let call_iterbytes = |thing_expr| { + build::mk_stmt( + cx, span, + build::mk_method_call(cx, span, + thing_expr, iter_bytes_ident, + copy lsb0_f)) + }; + let mut stmts = ~[]; + let fields; + match *substr.fields { + Struct(ref fs) => { + fields = fs } + EnumMatching(copy index, ref variant, ref fs) => { + // Determine the discriminant. We will feed this value to the byte + // iteration function. + let discriminant = match variant.node.disr_expr { + Some(copy d)=> d, + None => build::mk_uint(cx, span, index) + }; - // Create the pattern body. - let match_body_block = build::mk_block_(cx, span, stmts); + stmts.push(call_iterbytes(discriminant)); - // Create the arm. - ast::arm { - pats: ~[ pat ], - guard: None, - body: match_body_block, + fields = fs; } - }; + _ => cx.span_bug(span, "Impossible substructure in `deriving(IterBytes)`") + } - // Create the method body. - let self_match_expr = expand_enum_or_struct_match(cx, span, arms); - let self_match_stmt = build::mk_stmt(cx, span, self_match_expr); + for fields.each |&(_, field, _)| { + stmts.push(call_iterbytes(field)); + } - // Create the method. - create_iter_bytes_method(cx, span, ~[ self_match_stmt ]) + build::mk_block(cx, span, ~[], stmts, None) } diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 5aeeef2b17a..2bd45e1466c 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -12,14 +12,7 @@ /// #[deriving(IterBytes)] extensions. use ast; -use ast::{Ty, bind_by_ref, deref, enum_def}; -use ast::{expr, expr_match, ident, item, item_}; -use ast::{item_enum, item_impl, item_struct, Generics}; -use ast::{m_imm, meta_item, method}; -use ast::{named_field, pat, pat_ident, public}; -use ast::{struct_def, struct_variant_kind}; -use ast::{tuple_variant_kind}; -use ast::{ty_path, unnamed_field, variant}; +use ast::{Ty, enum_def, expr, ident, item, Generics, meta_item, struct_def}; use ext::base::ext_ctxt; use ext::build; use codemap::{span, respan}; @@ -30,6 +23,8 @@ pub mod clone; pub mod iter_bytes; pub mod encodable; pub mod decodable; +pub mod rand; +pub mod to_str; #[path="cmp/eq.rs"] pub mod eq; @@ -78,23 +73,25 @@ pub fn expand_meta_deriving(cx: @ext_ctxt, meta_name_value(tname, _) | meta_list(tname, _) | meta_word(tname) => { + macro_rules! expand(($func:path) => ($func(cx, titem.span, + titem, in_items))); match *tname { - ~"Clone" => clone::expand_deriving_clone(cx, - titem.span, titem, in_items), - ~"IterBytes" => iter_bytes::expand_deriving_iter_bytes(cx, - titem.span, titem, in_items), - ~"Encodable" => encodable::expand_deriving_encodable(cx, - titem.span, titem, in_items), - ~"Decodable" => decodable::expand_deriving_decodable(cx, - titem.span, titem, in_items), - ~"Eq" => eq::expand_deriving_eq(cx, titem.span, - titem, in_items), - ~"TotalEq" => totaleq::expand_deriving_totaleq(cx, titem.span, - titem, in_items), - ~"Ord" => ord::expand_deriving_ord(cx, titem.span, - titem, in_items), - ~"TotalOrd" => totalord::expand_deriving_totalord(cx, titem.span, - titem, in_items), + ~"Clone" => expand!(clone::expand_deriving_clone), + + ~"IterBytes" => expand!(iter_bytes::expand_deriving_iter_bytes), + + ~"Encodable" => expand!(encodable::expand_deriving_encodable), + ~"Decodable" => expand!(decodable::expand_deriving_decodable), + + ~"Eq" => expand!(eq::expand_deriving_eq), + ~"TotalEq" => expand!(totaleq::expand_deriving_totaleq), + ~"Ord" => expand!(ord::expand_deriving_ord), + ~"TotalOrd" => expand!(totalord::expand_deriving_totalord), + + ~"Rand" => expand!(rand::expand_deriving_rand), + + ~"ToStr" => expand!(to_str::expand_deriving_to_str), + tname => { cx.span_err(titem.span, fmt!("unknown \ `deriving` trait: `%s`", tname)); @@ -118,14 +115,14 @@ pub fn expand_deriving(cx: @ext_ctxt, for in_items.each |item| { result.push(copy *item); match item.node { - item_struct(struct_def, ref generics) => { + ast::item_struct(struct_def, ref generics) => { result.push(expand_deriving_struct_def(cx, span, struct_def, item.ident, generics)); } - item_enum(ref enum_definition, ref generics) => { + ast::item_enum(ref enum_definition, ref generics) => { result.push(expand_deriving_enum_def(cx, span, enum_definition, @@ -138,7 +135,7 @@ pub fn expand_deriving(cx: @ext_ctxt, result } -fn create_impl_item(cx: @ext_ctxt, span: span, item: item_) -> @item { +fn create_impl_item(cx: @ext_ctxt, span: span, item: ast::item_) -> @item { let doc_attr = respan(span, ast::lit_str(@~"Automatically derived.")); let doc_attr = respan(span, ast::meta_name_value(@~"doc", doc_attr)); @@ -154,7 +151,7 @@ fn create_impl_item(cx: @ext_ctxt, span: span, item: item_) -> @item { attrs: ~[doc_attr], id: cx.next_id(), node: item, - vis: public, + vis: ast::public, span: span, } } @@ -173,22 +170,29 @@ pub fn create_self_type_with_params(cx: @ext_ctxt, self_ty_params.push(self_ty_param); } + let lifetime = if generics.lifetimes.is_empty() { + None + } else { + Some(@*generics.lifetimes.get(0)) + }; + + // Create the type of `self`. let self_type = build::mk_raw_path_(span, ~[ type_ident ], + lifetime, self_ty_params); - let self_type = ty_path(self_type, cx.next_id()); - @ast::Ty { id: cx.next_id(), node: self_type, span: span } + build::mk_ty_path_path(cx, span, self_type) } pub fn create_derived_impl(cx: @ext_ctxt, span: span, type_ident: ident, generics: &Generics, - methods: &[@method], + methods: &[@ast::method], trait_path: @ast::Path, - mut impl_ty_params: opt_vec::OptVec<ast::TyParam>, - bounds_paths: opt_vec::OptVec<~[ident]>) + mut impl_generics: Generics, + bounds_paths: opt_vec::OptVec<@ast::Path>) -> @item { /*! * @@ -204,21 +208,22 @@ pub fn create_derived_impl(cx: @ext_ctxt, */ // Copy the lifetimes - let impl_lifetimes = generics.lifetimes.map(|l| { - build::mk_lifetime(cx, l.span, l.ident) - }); + for generics.lifetimes.each |l| { + impl_generics.lifetimes.push(copy *l) + }; // Create the type parameters. for generics.ty_params.each |ty_param| { + // extra restrictions on the generics parameters to the type being derived upon let mut bounds = do bounds_paths.map |&bound_path| { - build::mk_trait_ty_param_bound_global(cx, span, bound_path) + build::mk_trait_ty_param_bound_(cx, bound_path) }; let this_trait_bound = build::mk_trait_ty_param_bound_(cx, trait_path); bounds.push(this_trait_bound); - impl_ty_params.push(build::mk_ty_param(cx, ty_param.ident, @bounds)); + impl_generics.ty_params.push(build::mk_ty_param(cx, ty_param.ident, @bounds)); } // Create the reference to the trait. @@ -231,8 +236,7 @@ pub fn create_derived_impl(cx: @ext_ctxt, generics); // Create the impl item. - let impl_item = item_impl(Generics {lifetimes: impl_lifetimes, - ty_params: impl_ty_params}, + let impl_item = ast::item_impl(impl_generics, Some(trait_ref), self_type, methods.map(|x| *x)); @@ -240,106 +244,128 @@ pub fn create_derived_impl(cx: @ext_ctxt, } pub fn create_subpatterns(cx: @ext_ctxt, - span: span, - prefix: ~str, - n: uint) - -> ~[@pat] { - let mut subpats = ~[]; - for uint::range(0, n) |_i| { - // Create the subidentifier. - let index = subpats.len(); - let ident = cx.ident_of(fmt!("%s_%u", prefix, index)); - - // Create the subpattern. - let subpath = build::mk_raw_path(span, ~[ ident ]); - let subpat = pat_ident(bind_by_ref(m_imm), subpath, None); - let subpat = build::mk_pat(cx, span, subpat); - subpats.push(subpat); + span: span, + field_paths: ~[@ast::Path], + mutbl: ast::mutability) + -> ~[@ast::pat] { + do field_paths.map |&path| { + build::mk_pat(cx, span, + ast::pat_ident(ast::bind_by_ref(mutbl), path, None)) } - return subpats; } -pub fn is_struct_tuple(struct_def: &struct_def) -> bool { - struct_def.fields.len() > 0 && struct_def.fields.all(|f| { - match f.node.kind { - named_field(*) => false, - unnamed_field => true - } - }) +#[deriving(Eq)] // dogfooding! +enum StructType { + Unknown, Record, Tuple +} + +pub fn create_struct_pattern(cx: @ext_ctxt, + span: span, + struct_ident: ident, + struct_def: &struct_def, + prefix: ~str, + mutbl: ast::mutability) + -> (@ast::pat, ~[(Option<ident>, @expr)]) { + if struct_def.fields.is_empty() { + return ( + build::mk_pat_ident_with_binding_mode( + cx, span, struct_ident, ast::bind_infer), + ~[]); + } + + let matching_path = build::mk_raw_path(span, ~[ struct_ident ]); + + let mut paths = ~[], ident_expr = ~[]; + + let mut struct_type = Unknown; + + for struct_def.fields.eachi |i, struct_field| { + let opt_id = match struct_field.node.kind { + ast::named_field(ident, _) if (struct_type == Unknown || + struct_type == Record) => { + struct_type = Record; + Some(ident) + } + ast::unnamed_field if (struct_type == Unknown || + struct_type == Tuple) => { + struct_type = Tuple; + None + } + _ => { + cx.span_bug(span, "A struct with named and unnamed fields in `deriving`"); + } + }; + let path = build::mk_raw_path(span, + ~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]); + paths.push(path); + ident_expr.push((opt_id, build::mk_path_raw(cx, span, path))); + } + + let subpats = create_subpatterns(cx, span, paths, mutbl); + + // struct_type is definitely not Unknown, since struct_def.fields + // must be nonempty to reach here + let pattern = if struct_type == Record { + let field_pats = do vec::build |push| { + for vec::each2(subpats, ident_expr) |&pat, &(id, _)| { + // id is guaranteed to be Some + push(ast::field_pat { ident: id.get(), pat: pat }) + } + }; + build::mk_pat_struct(cx, span, matching_path, field_pats) + } else { + build::mk_pat_enum(cx, span, matching_path, subpats) + }; + + (pattern, ident_expr) } pub fn create_enum_variant_pattern(cx: @ext_ctxt, - span: span, - variant: &variant, - prefix: ~str) - -> @pat { + span: span, + variant: &ast::variant, + prefix: ~str, + mutbl: ast::mutability) + -> (@ast::pat, ~[(Option<ident>, @expr)]) { + let variant_ident = variant.node.name; match variant.node.kind { - tuple_variant_kind(ref variant_args) => { - if variant_args.len() == 0 { - return build::mk_pat_ident_with_binding_mode( - cx, span, variant_ident, ast::bind_infer); + ast::tuple_variant_kind(ref variant_args) => { + if variant_args.is_empty() { + return (build::mk_pat_ident_with_binding_mode( + cx, span, variant_ident, ast::bind_infer), ~[]); } let matching_path = build::mk_raw_path(span, ~[ variant_ident ]); - let subpats = create_subpatterns(cx, - span, - prefix, - variant_args.len()); - return build::mk_pat_enum(cx, span, matching_path, subpats); - } - struct_variant_kind(struct_def) => { - let matching_path = build::mk_raw_path(span, ~[ variant_ident ]); - let subpats = create_subpatterns(cx, - span, - prefix, - struct_def.fields.len()); - - let field_pats = do struct_def.fields.mapi |i, struct_field| { - let ident = match struct_field.node.kind { - named_field(ident, _, _) => ident, - unnamed_field => { - cx.span_bug(span, ~"unexpected unnamed field"); - } - }; - ast::field_pat { ident: ident, pat: subpats[i] } - }; + let mut paths = ~[], ident_expr = ~[]; + for uint::range(0, variant_args.len()) |i| { + let path = build::mk_raw_path(span, + ~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]); - build::mk_pat_struct(cx, span, matching_path, field_pats) - } - } -} + paths.push(path); + ident_expr.push((None, build::mk_path_raw(cx, span, path))); + } -pub fn variant_arg_count(_cx: @ext_ctxt, _span: span, variant: &variant) -> uint { - match variant.node.kind { - tuple_variant_kind(ref args) => args.len(), - struct_variant_kind(ref struct_def) => struct_def.fields.len(), - } -} + let subpats = create_subpatterns(cx, span, paths, mutbl); -/// Iterate through the idents of the variant arguments. The field is -/// unnamed (i.e. it's not a struct-like enum), then `None`. -pub fn each_variant_arg_ident(_cx: @ext_ctxt, _span: span, - variant: &variant, it: &fn(uint, Option<ident>) -> bool) { - match variant.node.kind { - tuple_variant_kind(ref args) => { - for uint::range(0, args.len()) |i| { - if !it(i, None) { break } - } + (build::mk_pat_enum(cx, span, matching_path, subpats), + ident_expr) } - struct_variant_kind(ref struct_def) => { - for struct_def.fields.eachi |i, f| { - let id = match f.node.kind { - named_field(ident, _, _) => Some(ident), - unnamed_field => None - }; - if !it(i, id) { break } - } + ast::struct_variant_kind(struct_def) => { + create_struct_pattern(cx, span, + variant_ident, struct_def, + prefix, + mutbl) } } } +pub fn variant_arg_count(_cx: @ext_ctxt, _span: span, variant: &ast::variant) -> uint { + match variant.node.kind { + ast::tuple_variant_kind(ref args) => args.len(), + ast::struct_variant_kind(ref struct_def) => struct_def.fields.len(), + } +} pub fn expand_enum_or_struct_match(cx: @ext_ctxt, span: span, @@ -347,7 +373,7 @@ pub fn expand_enum_or_struct_match(cx: @ext_ctxt, -> @expr { let self_ident = cx.ident_of(~"self"); let self_expr = build::mk_path(cx, span, ~[ self_ident ]); - let self_expr = build::mk_unary(cx, span, deref, self_expr); - let self_match_expr = expr_match(self_expr, arms); + let self_expr = build::mk_unary(cx, span, ast::deref, self_expr); + let self_match_expr = ast::expr_match(self_expr, arms); build::mk_expr(cx, span, self_match_expr) } diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs new file mode 100644 index 00000000000..604686f442f --- /dev/null +++ b/src/libsyntax/ext/deriving/rand.rs @@ -0,0 +1,141 @@ +// Copyright 2012-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. + +use ast; +use ast::{meta_item, item, expr, ident}; +use codemap::span; +use ext::base::ext_ctxt; +use ext::build; +use ext::deriving::generic::*; + +pub fn expand_deriving_rand(cx: @ext_ctxt, + span: span, + mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + let trait_def = TraitDef { + path: Path::new(~[~"core", ~"rand", ~"Rand"]), + additional_bounds: ~[], + generics: LifetimeBounds::empty(), + methods: ~[ + MethodDef { + name: ~"rand", + generics: LifetimeBounds { + lifetimes: ~[], + bounds: ~[(~"R", + ~[ Path::new(~[~"core", ~"rand", ~"Rng"]) ])] + }, + self_ty: None, + args: ~[ + Ptr(~Literal(Path::new_local(~"R")), + Borrowed(None, ast::m_mutbl)) + ], + ret_ty: Self, + const_nonmatching: false, + combine_substructure: rand_substructure + } + ] + }; + + expand_deriving_generic(cx, span, mitem, in_items, &trait_def) +} + +fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr { + let rng = match substr.nonself_args { + [rng] => ~[ rng ], + _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`") + }; + let rand_ident = ~[ + cx.ident_of(~"core"), + cx.ident_of(~"rand"), + cx.ident_of(~"Rand"), + cx.ident_of(~"rand") + ]; + let rand_call = || { + build::mk_call_global(cx, + span, + copy rand_ident, + ~[ build::duplicate_expr(cx, rng[0]) ]) + }; + + return match *substr.fields { + StaticStruct(_, ref summary) => { + rand_thing(cx, span, substr.type_ident, summary, rand_call) + } + StaticEnum(_, ref variants) => { + if variants.is_empty() { + cx.span_fatal(span, "`Rand` cannot be derived for enums with no variants"); + } + + let variant_count = build::mk_uint(cx, span, variants.len()); + + // need to specify the uint-ness of the random number + let u32_ty = build::mk_ty_path(cx, span, ~[cx.ident_of(~"uint")]); + let r_ty = build::mk_ty_path(cx, span, ~[cx.ident_of(~"R")]); + let rand_name = build::mk_raw_path_(span, copy rand_ident, None, ~[ u32_ty, r_ty ]); + let rand_name = build::mk_path_raw(cx, span, rand_name); + + let rv_call = build::mk_call_(cx, + span, + rand_name, + ~[ build::duplicate_expr(cx, rng[0]) ]); + + // rand() % variants.len() + let rand_variant = build::mk_binary(cx, span, ast::rem, + rv_call, variant_count); + + let mut arms = do variants.mapi |i, id_sum| { + let i_expr = build::mk_uint(cx, span, i); + let pat = build::mk_pat_lit(cx, span, i_expr); + + match *id_sum { + (ident, ref summary) => { + build::mk_arm(cx, span, + ~[ pat ], + rand_thing(cx, span, ident, summary, rand_call)) + } + } + }; + + // _ => {} at the end. Should never occur + arms.push(build::mk_unreachable_arm(cx, span)); + + build::mk_expr(cx, span, + ast::expr_match(rand_variant, arms)) + } + _ => cx.bug("Non-static method in `deriving(Rand)`") + }; + + fn rand_thing(cx: @ext_ctxt, span: span, + ctor_ident: ident, + summary: &Either<uint, ~[ident]>, + rand_call: &fn() -> @expr) -> @expr { + let ctor_ident = ~[ ctor_ident ]; + match *summary { + Left(copy count) => { + if count == 0 { + build::mk_path(cx, span, ctor_ident) + } else { + let exprs = vec::from_fn(count, |_| rand_call()); + build::mk_call(cx, span, ctor_ident, exprs) + } + } + Right(ref fields) => { + let rand_fields = do fields.map |ident| { + build::Field { + ident: *ident, + ex: rand_call() + } + }; + build::mk_struct_e(cx, span, ctor_ident, rand_fields) + } + } + } +} diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs new file mode 100644 index 00000000000..2c7d449585f --- /dev/null +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -0,0 +1,54 @@ +// Copyright 2012-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. + +use ast::{meta_item, item, expr}; +use codemap::span; +use ext::base::ext_ctxt; +use ext::build; +use ext::deriving::generic::*; + +pub fn expand_deriving_to_str(cx: @ext_ctxt, + span: span, + mitem: @meta_item, + in_items: ~[@item]) + -> ~[@item] { + let trait_def = TraitDef { + path: Path::new(~[~"core", ~"to_str", ~"ToStr"]), + additional_bounds: ~[], + generics: LifetimeBounds::empty(), + methods: ~[ + MethodDef { + name: ~"to_str", + generics: LifetimeBounds::empty(), + self_ty: borrowed_explicit_self(), + args: ~[], + ret_ty: Ptr(~Literal(Path::new_local(~"str")), Owned), + const_nonmatching: false, + combine_substructure: to_str_substructure + } + ] + }; + + expand_deriving_generic(cx, span, mitem, in_items, &trait_def) +} + +fn to_str_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr { + match substr.self_args { + [self_obj] => { + let self_addr = build::mk_addr_of(cx, span, self_obj); + build::mk_call_global(cx, span, + ~[cx.ident_of(~"core"), + cx.ident_of(~"sys"), + cx.ident_of(~"log_str")], + ~[self_addr]) + } + _ => cx.span_bug(span, ~"Invalid number of arguments in `deriving(ToStr)`") + } +} \ No newline at end of file diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs new file mode 100644 index 00000000000..6195a3a6424 --- /dev/null +++ b/src/libsyntax/ext/deriving/ty.rs @@ -0,0 +1,242 @@ +// 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. + +/*! +A mini version of ast::Ty, which is easier to use, and features an +explicit `Self` type to use when specifying impls to be derived. +*/ + +use ast; +use ast::{expr,Generics,ident}; +use ext::base::ext_ctxt; +use ext::build; +use codemap::{span,respan}; +use opt_vec; + +/// The types of pointers +#[deriving(Eq)] +pub enum PtrTy { + Owned, // ~ + Managed(ast::mutability), // @[mut] + Borrowed(Option<~str>, ast::mutability), // &['lifetime] [mut] +} + +/// A path, e.g. `::core::option::Option::<int>` (global). Has support +/// for type parameters and a lifetime. +#[deriving(Eq)] +pub struct Path { + path: ~[~str], + lifetime: Option<~str>, + params: ~[~Ty], + global: bool +} + +pub impl Path { + fn new(path: ~[~str]) -> Path { + Path::new_(path, None, ~[], true) + } + fn new_local(path: ~str) -> Path { + Path::new_(~[ path ], None, ~[], false) + } + fn new_(path: ~[~str], lifetime: Option<~str>, params: ~[~Ty], global: bool) -> Path { + Path { + path: path, + lifetime: lifetime, + params: params, + global: global + } + } + + fn to_ty(&self, cx: @ext_ctxt, span: span, + self_ty: ident, self_generics: &Generics) -> @ast::Ty { + build::mk_ty_path_path(cx, span, + self.to_path(cx, span, + self_ty, self_generics)) + } + fn to_path(&self, cx: @ext_ctxt, span: span, + self_ty: ident, self_generics: &Generics) -> @ast::Path { + let idents = self.path.map(|s| cx.ident_of(*s) ); + let lt = mk_lifetime(cx, span, self.lifetime); + let tys = self.params.map(|t| t.to_ty(cx, span, self_ty, self_generics)); + + if self.global { + build::mk_raw_path_global_(span, idents, lt, tys) + } else { + build::mk_raw_path_(span, idents, lt, tys) + } + } +} + +/// A type. Supports pointers (except for *), Self, and literals +#[deriving(Eq)] +pub enum Ty { + Self, + // &/~/@ Ty + Ptr(~Ty, PtrTy), + // mod::mod::Type<[lifetime], [Params...]>, including a plain type + // parameter, and things like `int` + Literal(Path), + // includes nil + Tuple(~[Ty]) +} + +pub fn borrowed_ptrty() -> PtrTy { + Borrowed(None, ast::m_imm) +} +pub fn borrowed(ty: ~Ty) -> Ty { + Ptr(ty, borrowed_ptrty()) +} + +pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> { + Some(Some(borrowed_ptrty())) +} + +pub fn borrowed_self() -> Ty { + borrowed(~Self) +} + +pub fn nil_ty() -> Ty { + Tuple(~[]) +} + +fn mk_lifetime(cx: @ext_ctxt, span: span, lt: Option<~str>) -> Option<@ast::Lifetime> { + match lt { + Some(s) => Some(@build::mk_lifetime(cx, span, cx.ident_of(s))), + None => None + } +} + +pub impl Ty { + fn to_ty(&self, cx: @ext_ctxt, span: span, + self_ty: ident, self_generics: &Generics) -> @ast::Ty { + match *self { + Ptr(ref ty, ref ptr) => { + let raw_ty = ty.to_ty(cx, span, self_ty, self_generics); + match *ptr { + Owned => { + build::mk_ty_uniq(cx, span, raw_ty) + } + Managed(copy mutbl) => { + build::mk_ty_box(cx, span, raw_ty, mutbl) + } + Borrowed(copy lt, copy mutbl) => { + let lt = mk_lifetime(cx, span, lt); + build::mk_ty_rptr(cx, span, raw_ty, lt, mutbl) + } + } + } + Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) } + Self => { + build::mk_ty_path_path(cx, span, self.to_path(cx, span, self_ty, self_generics)) + } + Tuple(ref fields) => { + let ty = if fields.is_empty() { + ast::ty_nil + } else { + ast::ty_tup(fields.map(|f| f.to_ty(cx, span, self_ty, self_generics))) + }; + + build::mk_ty(cx, span, ty) + } + } + } + + fn to_path(&self, cx: @ext_ctxt, span: span, + self_ty: ident, self_generics: &Generics) -> @ast::Path { + match *self { + Self => { + let self_params = do self_generics.ty_params.map |ty_param| { + build::mk_ty_path(cx, span, ~[ ty_param.ident ]) + }; + let lifetime = if self_generics.lifetimes.is_empty() { + None + } else { + Some(@*self_generics.lifetimes.get(0)) + }; + + build::mk_raw_path_(span, ~[self_ty], lifetime, + opt_vec::take_vec(self_params)) + } + Literal(ref p) => { + p.to_path(cx, span, self_ty, self_generics) + } + Ptr(*) => { cx.span_bug(span, ~"Pointer in a path in generic `deriving`") } + Tuple(*) => { cx.span_bug(span, ~"Tuple in a path in generic `deriving`") } + } + } +} + + +fn mk_ty_param(cx: @ext_ctxt, span: span, name: ~str, bounds: ~[Path], + self_ident: ident, self_generics: &Generics) -> ast::TyParam { + let bounds = opt_vec::from( + do bounds.map |b| { + let path = b.to_path(cx, span, self_ident, self_generics); + build::mk_trait_ty_param_bound_(cx, path) + }); + build::mk_ty_param(cx, cx.ident_of(name), @bounds) +} + +fn mk_generics(lifetimes: ~[ast::Lifetime], ty_params: ~[ast::TyParam]) -> Generics { + Generics { + lifetimes: opt_vec::from(lifetimes), + ty_params: opt_vec::from(ty_params) + } +} + +/// Lifetimes and bounds on type paramers +pub struct LifetimeBounds { + lifetimes: ~[~str], + bounds: ~[(~str, ~[Path])] +} + +pub impl LifetimeBounds { + fn empty() -> LifetimeBounds { + LifetimeBounds { + lifetimes: ~[], bounds: ~[] + } + } + fn to_generics(&self, cx: @ext_ctxt, span: span, + self_ty: ident, self_generics: &Generics) -> Generics { + let lifetimes = do self.lifetimes.map |<| { + build::mk_lifetime(cx, span, cx.ident_of(lt)) + }; + let ty_params = do self.bounds.map |&(name, bounds)| { + mk_ty_param(cx, span, name, bounds, self_ty, self_generics) + }; + mk_generics(lifetimes, ty_params) + } +} + + +pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: Option<PtrTy>) + -> (@expr, ast::self_ty) { + let self_path = build::mk_path(cx, span, ~[cx.ident_of(~"self")]); + match self_ptr { + None => { + (self_path, respan(span, ast::sty_value)) + } + Some(ptr) => { + let self_ty = respan( + span, + match ptr { + Owned => ast::sty_uniq(ast::m_imm), + Managed(mutbl) => ast::sty_box(mutbl), + Borrowed(lt, mutbl) => { + let lt = lt.map(|s| @build::mk_lifetime(cx, span, + cx.ident_of(*s))); + ast::sty_region(lt, mutbl) + } + }); + let self_expr = build::mk_deref(cx, span, self_path); + (self_expr, self_ty) + } + } +} diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index e876972fe68..7ac3ea4789d 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -64,6 +64,7 @@ impl gen_send for message { let mut body = ~"{\n"; body += fmt!("use super::%s;\n", name); + body += ~"let mut pipe = pipe;\n"; if this.proto.is_bounded() { let (sp, rp) = match (this.dir, next.dir) { @@ -73,12 +74,12 @@ impl gen_send for message { (recv, recv) => (~"c", ~"s") }; - body += ~"let b = pipe.reuse_buffer();\n"; + body += ~"let mut b = pipe.reuse_buffer();\n"; body += fmt!("let %s = ::core::pipes::SendPacketBuffered(\ - &(b.buffer.data.%s));\n", + &mut (b.buffer.data.%s));\n", sp, next.name); body += fmt!("let %s = ::core::pipes::RecvPacketBuffered(\ - &(b.buffer.data.%s));\n", + &mut (b.buffer.data.%s));\n", rp, next.name); } else { @@ -366,7 +367,7 @@ impl gen_init for protocol { fmt!("data.%s.set_buffer(buffer)", s.name))), ext_cx.parse_expr(fmt!( - "::core::ptr::to_unsafe_ptr(&(data.%s))", + "::core::ptr::to_mut_unsafe_ptr(&mut (data.%s))", self.states[0].name)))); quote_expr!({ @@ -410,10 +411,8 @@ impl gen_init for protocol { @spanned { node: ast::struct_field_ { - kind: ast::named_field( - cx.ident_of(s.name), - ast::struct_immutable, - ast::inherited), + kind: ast::named_field(cx.ident_of(s.name), + ast::inherited), id: cx.next_id(), ty: fty, attrs: ~[], diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 229a8664d0c..d181dd87e38 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -859,3 +859,4 @@ impl AstFoldExtensions for @ast_fold { pub fn make_fold(afp: ast_fold_fns) -> @ast_fold { afp as @ast_fold } + diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 810efd39177..0543295eb4e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -45,7 +45,7 @@ use ast::{pat_tup, pat_uniq, pat_wild, private}; use ast::{rem, required}; use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; -use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract}; +use ast::{struct_variant_kind, subtract}; use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value}; use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok}; use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box}; @@ -390,8 +390,8 @@ pub impl Parser { // parse a ty_closure type fn parse_ty_closure(&self, sigil: ast::Sigil, - region: Option<@ast::Lifetime>) -> ty_ - { + region: Option<@ast::Lifetime>) + -> ty_ { /* (&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T @@ -773,20 +773,17 @@ pub impl Parser { return ty_rptr(opt_lifetime, mt); } - // parse an optional mode. - // XXX: Remove after snapshot. + // parse an optional, obsolete argument mode. fn parse_arg_mode(&self) { if self.eat(&token::BINOP(token::MINUS)) { self.obsolete(*self.span, ObsoleteMode); } else if self.eat(&token::ANDAND) { - // Ignore. + self.obsolete(*self.span, ObsoleteMode); } else if self.eat(&token::BINOP(token::PLUS)) { if self.eat(&token::BINOP(token::PLUS)) { - // ++ mode is obsolete, but we need a snapshot - // to stop parsing it. - // Ignore. + self.obsolete(*self.span, ObsoleteMode); } else { - // Ignore. + self.obsolete(*self.span, ObsoleteMode); } } else { // Ignore. @@ -2528,10 +2525,10 @@ pub impl Parser { fn parse_name_and_ty(&self, pr: visibility, attrs: ~[attribute]) -> @struct_field { - let mut is_mutbl = struct_immutable; let lo = self.span.lo; if self.eat_keyword(&~"mut") { - is_mutbl = struct_mutable; + // Do nothing, for backwards compatibility. + // XXX: Remove after snapshot. } if !is_plain_ident(&*self.token) { self.fatal(~"expected ident"); @@ -2540,7 +2537,7 @@ pub impl Parser { self.expect(&token::COLON); let ty = self.parse_ty(false); @spanned(lo, self.last_span.hi, ast::struct_field_ { - kind: named_field(name, is_mutbl, pr), + kind: named_field(name, pr), id: self.get_id(), ty: ty, attrs: attrs, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6f3d6604d5b..f12fb21992e 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -703,14 +703,11 @@ pub fn print_struct(s: @ps, for struct_def.fields.each |field| { match field.node.kind { ast::unnamed_field => fail!(~"unexpected unnamed field"), - ast::named_field(ident, mutability, visibility) => { + ast::named_field(ident, visibility) => { hardbreak_if_not_bol(s); maybe_print_comment(s, field.span.lo); print_outer_attributes(s, field.node.attrs); print_visibility(s, visibility); - if mutability == ast::struct_mutable { - word_nbsp(s, ~"mut"); - } print_ident(s, ident); word_nbsp(s, ~":"); print_type(s, field.node.ty); diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index e3a87277622..23084c34209 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -84,7 +84,7 @@ pub impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> { * for another case of this. */ macro_rules! interner_key ( () => (cast::transmute::<(uint, uint), - &fn(+v: @@::parse::token::ident_interner)>( + &fn(v: @@::parse::token::ident_interner)>( (-3 as uint, 0u))) ) diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 885b40c0a50..90328928122 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -829,13 +829,6 @@ rust_get_rt_env() { return task->kernel->env; } -typedef void *(*nullary_fn)(); - -extern "C" CDECL void -rust_call_nullary_fn(nullary_fn f) { - f(); -} - #ifndef _WIN32 pthread_key_t sched_key; #else diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 1c3f6370ded..6be41251f1b 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -222,7 +222,6 @@ rust_uv_ip4_addrp rust_uv_ip6_addrp rust_uv_free_ip4_addr rust_uv_free_ip6_addr -rust_call_nullary_fn rust_initialize_global_state rust_dbg_next_port rust_new_memory_region diff --git a/src/test/auxiliary/cci_class_6.rs b/src/test/auxiliary/cci_class_6.rs index b09606ea1e2..7ad617cebdb 100644 --- a/src/test/auxiliary/cci_class_6.rs +++ b/src/test/auxiliary/cci_class_6.rs @@ -23,7 +23,7 @@ pub mod kitties { fn meow_count(&mut self) -> uint { self.meows } } - pub fn cat<U>(in_x : uint, in_y : int, +in_info: ~[U]) -> cat<U> { + pub fn cat<U>(in_x : uint, in_y : int, in_info: ~[U]) -> cat<U> { cat { meows: in_x, how_hungry: in_y, diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index e216215ace7..cb494ec9d20 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -103,7 +103,7 @@ fn main() { let mut rand = vec::with_capacity(n_keys); { - let rng = core::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]); + let mut rng = core::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]); let mut set = HashSet::new(); while set.len() != n_keys { let next = rng.next() as uint; diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index b3e3d295c0f..bae21c6d4a3 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -31,8 +31,13 @@ fn timed(result: &mut float, op: &fn()) { } pub impl Results { - fn bench_int<T:Set<uint>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint, - rand_cap: uint, f: &fn() -> T) { + fn bench_int<T:Set<uint>, + R: rand::Rng>( + &mut self, + rng: &mut R, + num_keys: uint, + rand_cap: uint, + f: &fn() -> T) { { let mut set = f(); do timed(&mut self.sequential_ints) { @@ -69,8 +74,12 @@ pub impl Results { } } - fn bench_str<T:Set<~str>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint, - f: &fn() -> T) { + fn bench_str<T:Set<~str>, + R:rand::Rng>( + &mut self, + rng: &mut R, + num_keys: uint, + f: &fn() -> T) { { let mut set = f(); do timed(&mut self.sequential_strings) { @@ -155,25 +164,25 @@ fn main() { let max = 200000; { - let rng = rand::IsaacRng::new_seeded(seed); + let mut rng = rand::IsaacRng::new_seeded(seed); let mut results = empty_results(); - results.bench_int(&rng, num_keys, max, || HashSet::new::<uint>()); - results.bench_str(&rng, num_keys, || HashSet::new::<~str>()); + results.bench_int(&mut rng, num_keys, max, || HashSet::new::<uint>()); + results.bench_str(&mut rng, num_keys, || HashSet::new::<~str>()); write_results("core::hashmap::HashSet", &results); } { - let rng = rand::IsaacRng::new_seeded(seed); + let mut rng = rand::IsaacRng::new_seeded(seed); let mut results = empty_results(); - results.bench_int(&rng, num_keys, max, || TreeSet::new::<uint>()); - results.bench_str(&rng, num_keys, || TreeSet::new::<~str>()); + results.bench_int(&mut rng, num_keys, max, || TreeSet::new::<uint>()); + results.bench_str(&mut rng, num_keys, || TreeSet::new::<~str>()); write_results("std::treemap::TreeSet", &results); } { - let rng = rand::IsaacRng::new_seeded(seed); + let mut rng = rand::IsaacRng::new_seeded(seed); let mut results = empty_results(); - results.bench_int(&rng, num_keys, max, || BitvSet::new()); + results.bench_int(&mut rng, num_keys, max, || BitvSet::new()); write_results("std::bitv::BitvSet", &results); } } diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index 1af3538a021..95a83af93d5 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -33,12 +33,15 @@ fn main() { fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) { let mut run_test = false; - if os::getenv(~"RUST_BENCH").is_some() { run_test = true } - else if argv.len() > 0 { + if os::getenv(~"RUST_BENCH").is_some() { + run_test = true + } else if argv.len() > 0 { run_test = argv.contains(&~"all") || argv.contains(&name) } - if !run_test { return } + if !run_test { + return + } let start = precise_time_s(); test(); @@ -69,7 +72,7 @@ fn read_line() { } fn vec_plus() { - let r = rand::rng(); + let mut r = rand::rng(); let mut v = ~[]; let mut i = 0; @@ -86,7 +89,7 @@ fn vec_plus() { } fn vec_append() { - let r = rand::rng(); + let mut r = rand::rng(); let mut v = ~[]; let mut i = 0; @@ -103,7 +106,7 @@ fn vec_append() { } fn vec_push_all() { - let r = rand::rng(); + let mut r = rand::rng(); let mut v = ~[]; for uint::range(0, 1500) |i| { diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index c8555ab1286..1842a8ff42e 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -32,19 +32,20 @@ type graph = ~[~[node_id]]; type bfs_result = ~[node_id]; fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] { - let r = rand::XorShiftRng::new(); - - fn choose_edge<R: rand::Rng>(i: node_id, j: node_id, scale: uint, r: &R) - -> (node_id, node_id) { + let mut r = rand::XorShiftRng::new(); + fn choose_edge<R: rand::Rng>(i: node_id, + j: node_id, + scale: uint, + r: &mut R) + -> (node_id, node_id) { let A = 0.57; let B = 0.19; let C = 0.19; if scale == 0u { (i, j) - } - else { + } else { let i = i * 2i64; let j = j * 2i64; let scale = scale - 1u; @@ -73,7 +74,7 @@ fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] { } do vec::from_fn((1u << scale) * edgefactor) |_i| { - choose_edge(0i64, 0i64, scale, &r) + choose_edge(0i64, 0i64, scale, &mut r) } } @@ -103,7 +104,7 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph { fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] { let mut keys = HashSet::new(); - let r = rand::rng(); + let mut r = rand::rng(); while keys.len() < n { let k = r.gen_uint_range(0u, graph.len()); @@ -272,7 +273,7 @@ fn pbfs(graph: &arc::ARC<graph>, key: node_id) -> bfs_result { colors = do par::mapi(*color_vec) { let colors = arc::clone(&color); let graph = arc::clone(graph); - let result: ~fn(+x: uint, +y: &color) -> color = |i, c| { + let result: ~fn(x: uint, y: &color) -> color = |i, c| { let colors = arc::get(&colors); let graph = arc::get(&graph); match *c { @@ -394,7 +395,7 @@ fn validate(edges: ~[(node_id, node_id)], let status = do par::alli(tree) { let edges = copy edges; - let result: ~fn(+x: uint, v: &i64) -> bool = |u, v| { + let result: ~fn(x: uint, v: &i64) -> bool = |u, v| { let u = u as node_id; if *v == -1i64 || u == root { true diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 6cda0a1945a..95758b3fe64 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -65,15 +65,15 @@ fn run(args: &[~str]) { let mut worker_results = ~[]; for uint::range(0, workers) |_i| { let to_child = to_child.clone(); - do task::task().future_result(|+r| { - worker_results.push(r); - }).spawn || { + let mut builder = task::task(); + builder.future_result(|r| worker_results.push(r)); + do builder.spawn { for uint::range(0, size / workers) |_i| { //error!("worker %?: sending %? bytes", i, num_bytes); to_child.send(bytes(num_bytes)); } //error!("worker %? exiting", i); - }; + } } do task::spawn || { server(&from_parent, &to_parent); diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index a8fb29a47e2..e213a44b49a 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -62,9 +62,9 @@ fn run(args: &[~str]) { for uint::range(0, workers) |_i| { let (from_parent_, to_child) = stream(); from_parent.add(from_parent_); - do task::task().future_result(|+r| { - worker_results.push(r); - }).spawn || { + let mut builder = task::task(); + builder.future_result(|r| worker_results.push(r)); + do builder.spawn { for uint::range(0, size / workers) |_i| { //error!("worker %?: sending %? bytes", i, num_bytes); to_child.send(bytes(num_bytes)); diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index 853b057277d..2d234634cc8 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -45,10 +45,7 @@ fn init() -> (pipe,pipe) { } -fn thread_ring(i: uint, - count: uint, - +num_chan: pipe, - +num_port: pipe) { +fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { let mut num_chan = Some(num_chan); let mut num_port = Some(num_port); // Send/Receive lots of messages. @@ -103,7 +100,9 @@ fn main() { thread_ring(0, msg_per_task, num_chan.take(), num_port); // synchronize - for futures.each |f| { f.get() }; + for futures.each_mut |f| { + f.get() + } let stop = time::precise_time_s(); diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs index 1288ac29078..aef5c18499a 100644 --- a/src/test/bench/msgsend-ring-pipes.rs +++ b/src/test/bench/msgsend-ring-pipes.rs @@ -35,8 +35,8 @@ macro_rules! move_out ( fn thread_ring(i: uint, count: uint, - +num_chan: ring::client::num, - +num_port: ring::server::num) { + num_chan: ring::client::num, + num_port: ring::server::num) { let mut num_chan = Some(num_chan); let mut num_port = Some(num_port); // Send/Receive lots of messages. @@ -96,7 +96,9 @@ fn main() { thread_ring(0, msg_per_task, num_chan.take(), num_port); // synchronize - for futures.each |f| { f.get() }; + for futures.each_mut |f| { + let _ = f.get(); + } let stop = time::precise_time_s(); diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index 2cf0fbfc397..02415c4bcfc 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -46,10 +46,7 @@ fn init() -> (pipe,pipe) { } -fn thread_ring(i: uint, - count: uint, - +num_chan: pipe, - +num_port: pipe) { +fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { let mut num_chan = Some(num_chan); let mut num_port = Some(num_port); // Send/Receive lots of messages. @@ -104,7 +101,9 @@ fn main() { thread_ring(0, msg_per_task, num_chan.take(), num_port); // synchronize - for futures.each |f| { f.get() }; + for futures.each_mut |f| { + let _ = f.get(); + } let stop = time::precise_time_s(); diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 0da3a2e5d68..992ce73a4bf 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -13,7 +13,7 @@ fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v } #[inline(always)] fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) } -fn random_gradient<R:Rng>(r: &R) -> Vec2 { +fn random_gradient<R:Rng>(r: &mut R) -> Vec2 { let v = 2.0 * float::consts::pi * r.gen(); Vec2 { x: float::cos(v) as f32, @@ -33,11 +33,15 @@ struct Noise2DContext { pub impl Noise2DContext { fn new() -> Noise2DContext { - let r = rand::rng(); + let mut r = rand::rng(); let mut rgradients = [ Vec2 { x: 0.0, y: 0.0 }, ..256 ]; - for int::range(0, 256) |i| { rgradients[i] = random_gradient(&r); } + for int::range(0, 256) |i| { + rgradients[i] = random_gradient(&mut r); + } let mut permutations = [ 0, ..256 ]; - for int::range(0, 256) |i| { permutations[i] = i; } + for int::range(0, 256) |i| { + permutations[i] = i; + } r.shuffle_mut(permutations); Noise2DContext { @@ -53,7 +57,11 @@ pub impl Noise2DContext { } #[inline] - fn get_gradients(&self, gradients: &mut [Vec2, ..4], origins: &mut [Vec2, ..4], x: f32, y: f32) { + fn get_gradients(&self, + gradients: &mut [Vec2, ..4], + origins: &mut [Vec2, ..4], + x: f32, + y: f32) { let x0f = f32::floor(x); let y0f = f32::floor(y); let x0 = x0f as int; diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs index 09e663325ed..cfad253cfed 100644 --- a/src/test/bench/pingpong.rs +++ b/src/test/bench/pingpong.rs @@ -117,8 +117,9 @@ pub fn spawn_service_recv<T:Owned,Tb:Owned>( client } -fn switch<T:Owned,Tb:Owned,U>(+endp: core::pipes::RecvPacketBuffered<T, Tb>, - f: &fn(+v: Option<T>) -> U) -> U { +fn switch<T:Owned,Tb:Owned,U>(endp: core::pipes::RecvPacketBuffered<T, Tb>, + f: &fn(v: Option<T>) -> U) + -> U { f(core::pipes::try_recv(endp)) } diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 0fcf8341ac8..7316b68f8bd 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -63,7 +63,10 @@ fn make_random_fasta(wr: @io::Writer, genelist: ~[AminoAcids], n: int) { wr.write_line(~">" + id + ~" " + desc); - let rng = @mut MyRandom {last: rand::rng().next()}; + let mut rng = rand::rng(); + let rng = @mut MyRandom { + last: rng.next() + }; let mut op: ~str = ~""; for uint::range(0u, n as uint) |_i| { str::push_char(&mut op, select_random(myrandom_next(rng, 100u32), diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index acb8a6bcbee..b7ae331c8f3 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -26,7 +26,6 @@ use core::int::range; use core::comm::*; use core::io::WriterUtil; -use core::result; use core::result::{Ok, Err}; fn fib(n: int) -> int { @@ -67,7 +66,7 @@ fn parse_opts(argv: ~[~str]) -> Config { } } -fn stress_task(&&id: int) { +fn stress_task(id: int) { let mut i = 0; loop { let n = 15; @@ -80,13 +79,15 @@ fn stress_task(&&id: int) { fn stress(num_tasks: int) { let mut results = ~[]; for range(0, num_tasks) |i| { - do task::task().future_result(|+r| { - results.push(r); - }).spawn { + let mut builder = task::task(); + builder.future_result(|r| results.push(r)); + do builder.spawn { stress_task(i); } } - for results.each |r| { r.recv(); } + for results.each |r| { + r.recv(); + } } fn main() { diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs index 90c9d6b33e4..6015f21be72 100644 --- a/src/test/bench/task-perf-linked-failure.rs +++ b/src/test/bench/task-perf-linked-failure.rs @@ -46,9 +46,12 @@ fn grandchild_group(num_tasks: uint) { // Master grandchild task exits early. } -fn spawn_supervised_blocking(myname: &str, +f: ~fn()) { +fn spawn_supervised_blocking(myname: &str, f: ~fn()) { let mut res = None; - task::task().future_result(|+r| res = Some(r)).supervised().spawn(f); + let mut builder = task::task(); + builder.future_result(|r| res = Some(r)); + builder.supervised(); + builder.spawn(f); error!("%s group waiting", myname); let x = res.unwrap().recv(); assert!(x == task::Success); diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs index 8c5bbe257bd..e6da898a034 100644 --- a/src/test/bench/task-perf-spawnalot.rs +++ b/src/test/bench/task-perf-spawnalot.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(&&n: uint) { +fn f(n: uint) { let mut i = 0u; while i < n { task::try(|| g() ); diff --git a/src/test/compile-fail/block-coerce-no.rs b/src/test/compile-fail/block-coerce-no.rs index bdde5144b04..df9eb9fdda6 100644 --- a/src/test/compile-fail/block-coerce-no.rs +++ b/src/test/compile-fail/block-coerce-no.rs @@ -12,9 +12,9 @@ // other tycons. fn coerce(b: &fn()) -> extern fn() { - fn lol(+f: extern fn(+v: &fn()) -> extern fn(), - +g: &fn()) -> extern fn() { return f(g); } - fn fn_id(+f: extern fn()) -> extern fn() { return f } + fn lol(f: extern fn(v: &fn()) -> extern fn(), + g: &fn()) -> extern fn() { return f(g); } + fn fn_id(f: extern fn()) -> extern fn() { return f } return lol(fn_id, b); //~^ ERROR mismatched types } diff --git a/src/test/compile-fail/borrowck-pat-enum.rs b/src/test/compile-fail/borrowck-pat-enum.rs index c50357e8b9c..f1cca89b227 100644 --- a/src/test/compile-fail/borrowck-pat-enum.rs +++ b/src/test/compile-fail/borrowck-pat-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn match_ref(&&v: Option<int>) -> int { +fn match_ref(v: Option<int>) -> int { match v { Some(ref i) => { *i @@ -17,7 +17,7 @@ fn match_ref(&&v: Option<int>) -> int { } } -fn match_ref_unused(&&v: Option<int>) { +fn match_ref_unused(v: Option<int>) { match v { Some(_) => {} None => {} diff --git a/src/test/compile-fail/borrowck-unary-move.rs b/src/test/compile-fail/borrowck-unary-move.rs index 107e478004a..cf752986511 100644 --- a/src/test/compile-fail/borrowck-unary-move.rs +++ b/src/test/compile-fail/borrowck-unary-move.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo(+x: ~int) -> int { +fn foo(x: ~int) -> int { let y = &*x; free(x); //~ ERROR cannot move out of `*x` because it is borrowed *y } -fn free(+_x: ~int) { +fn free(_x: ~int) { } fn main() { diff --git a/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs b/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs index 9019d338d09..fa34c056794 100644 --- a/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs +++ b/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs @@ -18,7 +18,7 @@ impl Drop for X { } } -fn unwrap(+x: X) -> ~str { +fn unwrap(x: X) -> ~str { let X { x: y } = x; //~ ERROR deconstructing struct not allowed in pattern y } diff --git a/src/test/compile-fail/elided-test.rs b/src/test/compile-fail/elided-test.rs index eaae721e0e5..b62214b12f9 100644 --- a/src/test/compile-fail/elided-test.rs +++ b/src/test/compile-fail/elided-test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: entry function not found +// error-pattern: main function not found // Since we're not compiling a test runner this function should be elided // and the build will fail because main doesn't exist diff --git a/src/test/compile-fail/issue-2766-a.rs b/src/test/compile-fail/issue-2766-a.rs index 5e3eb9ef09b..5b55cc772fd 100644 --- a/src/test/compile-fail/issue-2766-a.rs +++ b/src/test/compile-fail/issue-2766-a.rs @@ -15,10 +15,10 @@ pub mod stream { use core::pipes; pub impl<T:Owned> Stream<T> { - pub fn recv() -> extern fn(+v: Stream<T>) -> ::stream::Stream<T> { + pub fn recv() -> extern fn(v: Stream<T>) -> ::stream::Stream<T> { // resolve really should report just one error here. // Change the test case when it changes. - pub fn recv(+pipe: Stream<T>) -> ::stream::Stream<T> { //~ ERROR attempt to use a type argument out of scope + pub fn recv(pipe: Stream<T>) -> ::stream::Stream<T> { //~ ERROR attempt to use a type argument out of scope //~^ ERROR use of undeclared type name //~^^ ERROR attempt to use a type argument out of scope //~^^^ ERROR use of undeclared type name diff --git a/src/test/compile-fail/issue-2995.rs b/src/test/compile-fail/issue-2995.rs index 5c48416667f..3e771eef970 100644 --- a/src/test/compile-fail/issue-2995.rs +++ b/src/test/compile-fail/issue-2995.rs @@ -11,3 +11,5 @@ fn bad (p: *int) { let _q: &int = p as ∫ //~ ERROR non-scalar cast } + +fn main() { } \ No newline at end of file diff --git a/src/test/compile-fail/issue-3296.rs b/src/test/compile-fail/issue-3296.rs index 00425825e3f..062ee8fd01e 100644 --- a/src/test/compile-fail/issue-3296.rs +++ b/src/test/compile-fail/issue-3296.rs @@ -18,7 +18,7 @@ struct Foo { a: () } -fn deserialize_foo<__D: std::serialization::deserializer>(&&__d: __D) { +fn deserialize_foo<__D: std::serialization::deserializer>(__d: __D) { } fn main() { let des = Deserializer(); let foo = deserialize_foo(des); } diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs index fdc0392a74c..23d3fff01cf 100644 --- a/src/test/compile-fail/liveness-use-after-send.rs +++ b/src/test/compile-fail/liveness-use-after-send.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn send<T:Owned>(ch: _chan<T>, +data: T) { +fn send<T:Owned>(ch: _chan<T>, data: T) { debug!(ch); debug!(data); fail!(); diff --git a/src/test/compile-fail/multiple-main.rs b/src/test/compile-fail/main-wrong-location.rs index ef8cd58abf9..90ef7843d4b 100644 --- a/src/test/compile-fail/multiple-main.rs +++ b/src/test/compile-fail/main-wrong-location.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() { -} - -mod foo { - fn main() { //~ ERROR multiple 'main' functions - } -} +mod m { + // An inferred main entry point (that doesn't use #[main]) + // must appear at the top of the crate + fn main() { } //~ NOTE here is a function named 'main' +} \ No newline at end of file diff --git a/src/test/compile-fail/missing-main.rs b/src/test/compile-fail/missing-main.rs index 4f1b604b507..4bfdaf69480 100644 --- a/src/test/compile-fail/missing-main.rs +++ b/src/test/compile-fail/missing-main.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:entry function not found +// error-pattern:main function not found fn mian() { } diff --git a/src/test/compile-fail/mutable-huh-ptr-assign.rs b/src/test/compile-fail/mutable-huh-ptr-assign.rs index 6b3fd4f7153..c907eb4be49 100644 --- a/src/test/compile-fail/mutable-huh-ptr-assign.rs +++ b/src/test/compile-fail/mutable-huh-ptr-assign.rs @@ -11,7 +11,7 @@ extern mod std; fn main() { - unsafe fn f(&&v: *const int) { + unsafe fn f(v: *const int) { *v = 1 //~ ERROR cannot assign } diff --git a/src/test/compile-fail/simd-type.rs b/src/test/compile-fail/simd-type.rs new file mode 100644 index 00000000000..8387b2bc723 --- /dev/null +++ b/src/test/compile-fail/simd-type.rs @@ -0,0 +1,13 @@ +#[simd] +struct vec4<T>(T, T, T, T); //~ ERROR SIMD vector cannot be generic + +#[simd] +struct empty; //~ ERROR SIMD vector cannot be empty + +#[simd] +struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous + +#[simd] +struct int4(int, int, int, int); //~ ERROR SIMD vector element type should be machine type + +fn main() {} diff --git a/src/test/compile-fail/tag-variant-disr-dup.rs b/src/test/compile-fail/tag-variant-disr-dup.rs index be53b6a0ba3..216779fac7c 100644 --- a/src/test/compile-fail/tag-variant-disr-dup.rs +++ b/src/test/compile-fail/tag-variant-disr-dup.rs @@ -19,3 +19,5 @@ enum color { black = 0x000000, white = 0x000000, } + +fn main() { } \ No newline at end of file diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index a3c51e2b7b1..003e8ccf309 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -21,7 +21,7 @@ impl Drop for r { } } -fn f<T>(+_i: ~[T], +_j: ~[T]) { +fn f<T>(_i: ~[T], _j: ~[T]) { } fn main() { diff --git a/src/test/run-fail/morestack3.rs b/src/test/run-fail/morestack3.rs index 14fc40a43cc..012e9d19b12 100644 --- a/src/test/run-fail/morestack3.rs +++ b/src/test/run-fail/morestack3.rs @@ -14,7 +14,7 @@ extern mod std; -fn getbig_and_fail(&&i: int) { +fn getbig_and_fail(i: int) { let _r = and_then_get_big_again(5); if i != 0 { getbig_and_fail(i - 1); diff --git a/src/test/run-fail/morestack4.rs b/src/test/run-fail/morestack4.rs index e4585393703..6fc187491cf 100644 --- a/src/test/run-fail/morestack4.rs +++ b/src/test/run-fail/morestack4.rs @@ -14,7 +14,7 @@ extern mod std; -fn getbig_and_fail(&&i: int) { +fn getbig_and_fail(i: int) { let r = and_then_get_big_again(5); if i != 0 { getbig_and_fail(i - 1); diff --git a/src/test/run-fail/unwind-move.rs b/src/test/run-fail/unwind-move.rs index 51e2eaa44fa..8f1b34d17cd 100644 --- a/src/test/run-fail/unwind-move.rs +++ b/src/test/run-fail/unwind-move.rs @@ -9,7 +9,7 @@ // except according to those terms. // error-pattern:fail -fn f(+_a: @int) { +fn f(_a: @int) { fail!(); } diff --git a/src/test/run-pass/argument-passing.rs b/src/test/run-pass/argument-passing.rs index d61c1214633..8c84187ff6f 100644 --- a/src/test/run-pass/argument-passing.rs +++ b/src/test/run-pass/argument-passing.rs @@ -10,9 +10,11 @@ // xfail-fast -struct X { x: int } +struct X { + x: int +} -fn f1(a: &mut X, b: &mut int, +c: int) -> int { +fn f1(a: &mut X, b: &mut int, c: int) -> int { let r = a.x + *b + c; a.x = 0; *b = 10; diff --git a/src/test/run-pass/auto-ref-sliceable.rs b/src/test/run-pass/auto-ref-sliceable.rs index 03e847e237d..f74d78f99d0 100644 --- a/src/test/run-pass/auto-ref-sliceable.rs +++ b/src/test/run-pass/auto-ref-sliceable.rs @@ -9,11 +9,11 @@ // except according to those terms. trait Pushable<T> { - fn push_val(&mut self, +t: T); + fn push_val(&mut self, t: T); } impl<T> Pushable<T> for ~[T] { - fn push_val(&mut self, +t: T) { + fn push_val(&mut self, t: T) { self.push(t); } } diff --git a/src/test/run-pass/bind-by-move.rs b/src/test/run-pass/bind-by-move.rs index d3d0e48f5b0..8752102c3a5 100644 --- a/src/test/run-pass/bind-by-move.rs +++ b/src/test/run-pass/bind-by-move.rs @@ -11,7 +11,7 @@ // xfail-fast extern mod std; use std::arc; -fn dispose(+_x: arc::ARC<bool>) { unsafe { } } +fn dispose(_x: arc::ARC<bool>) { unsafe { } } pub fn main() { let p = arc::ARC(true); diff --git a/src/test/run-pass/borrowck-lend-args.rs b/src/test/run-pass/borrowck-lend-args.rs index 0d51993e226..a912e1ef65c 100644 --- a/src/test/run-pass/borrowck-lend-args.rs +++ b/src/test/run-pass/borrowck-lend-args.rs @@ -10,7 +10,7 @@ fn borrow(_v: &int) {} -fn borrow_from_arg_imm_ref(&&v: ~int) { +fn borrow_from_arg_imm_ref(v: ~int) { borrow(v); } @@ -18,7 +18,7 @@ fn borrow_from_arg_mut_ref(v: &mut ~int) { borrow(*v); } -fn borrow_from_arg_copy(+v: ~int) { +fn borrow_from_arg_copy(v: ~int) { borrow(v); } diff --git a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs index 6929a98d9e1..8f66faab014 100644 --- a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs +++ b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs @@ -14,7 +14,7 @@ fn want_slice(v: &[int]) -> int { return sum; } -fn has_mut_vec(+v: ~[int]) -> int { +fn has_mut_vec(v: ~[int]) -> int { want_slice(v) } diff --git a/src/test/run-pass/borrowck-newtype-issue-2573.rs b/src/test/run-pass/borrowck-newtype-issue-2573.rs index 7724836b5db..5f0c7cad619 100644 --- a/src/test/run-pass/borrowck-newtype-issue-2573.rs +++ b/src/test/run-pass/borrowck-newtype-issue-2573.rs @@ -25,7 +25,7 @@ impl frob for foo { } // Override default mode so that we are passing by value -fn really_impure(++bar: baz) { +fn really_impure(bar: baz) { bar.baz = 3; } diff --git a/src/test/run-pass/capture_nil.rs b/src/test/run-pass/capture_nil.rs index 99d8fab4bba..817891c1146 100644 --- a/src/test/run-pass/capture_nil.rs +++ b/src/test/run-pass/capture_nil.rs @@ -26,7 +26,7 @@ use core::comm::*; -fn foo(&&x: ()) -> Port<()> { +fn foo(x: ()) -> Port<()> { let (p, c) = stream::<()>(); do task::spawn() { c.send(x); diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/run-pass/child-outlives-parent.rs index 50c6b821143..4eb3cea3a25 100644 --- a/src/test/run-pass/child-outlives-parent.rs +++ b/src/test/run-pass/child-outlives-parent.rs @@ -12,6 +12,8 @@ extern mod std; -fn child2(&&s: ~str) { } +fn child2(s: ~str) { } -pub fn main() { let x = task::spawn(|| child2(~"hi") ); } +pub fn main() { + let x = task::spawn(|| child2(~"hi")); +} diff --git a/src/test/run-pass/class-poly-methods.rs b/src/test/run-pass/class-poly-methods.rs index adcab8b40aa..9774d8d1488 100644 --- a/src/test/run-pass/class-poly-methods.rs +++ b/src/test/run-pass/class-poly-methods.rs @@ -22,7 +22,7 @@ pub impl<U> cat<U> { fn meow_count(&mut self) -> uint { self.meows } } -fn cat<U>(in_x : uint, in_y : int, +in_info: ~[U]) -> cat<U> { +fn cat<U>(in_x : uint, in_y : int, in_info: ~[U]) -> cat<U> { cat { meows: in_x, how_hungry: in_y, diff --git a/src/test/run-pass/cleanup-copy-mode.rs b/src/test/run-pass/cleanup-copy-mode.rs index b334f32f344..cb378da13ea 100644 --- a/src/test/run-pass/cleanup-copy-mode.rs +++ b/src/test/run-pass/cleanup-copy-mode.rs @@ -9,7 +9,7 @@ // except according to those terms. // xfail-win32 -fn adder(+x: @int, +y: @int) -> int { return *x + *y; } +fn adder(x: @int, y: @int) -> int { return *x + *y; } fn failer() -> @int { fail!(); } pub fn main() { assert!(result::is_err(&task::try(|| { diff --git a/src/test/run-pass/deriving-rand.rs b/src/test/run-pass/deriving-rand.rs new file mode 100644 index 00000000000..dd4664e7446 --- /dev/null +++ b/src/test/run-pass/deriving-rand.rs @@ -0,0 +1,39 @@ +// xfail-fast #6330 +// 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. + +#[deriving(Rand)] +struct A; + +#[deriving(Rand)] +struct B(int, int); + +#[deriving(Rand)] +struct C { + x: f64, + y: (u8, u8) +} + +#[deriving(Rand)] +enum D { + D0, + D1(uint), + D2 { x: (), y: () } +} + +fn main() { + // check there's no segfaults + for 20.times { + rand::random::<A>(); + rand::random::<B>(); + rand::random::<C>(); + rand::random::<D>(); + } +} \ No newline at end of file diff --git a/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs b/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs new file mode 100644 index 00000000000..b0b03d8419b --- /dev/null +++ b/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs @@ -0,0 +1,32 @@ +// xfail-test FIXME #6257 + +// 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. + +use core::cmp::{Less,Equal,Greater}; + +#[deriving(TotalEq,TotalOrd)] +struct A<'self> { + x: &'self int +} + +fn main() { + let a = A { x: &1 }, b = A { x: &2 }; + + assert!(a.equals(&a)); + assert!(b.equals(&b)); + + + assert_eq!(a.cmp(&a), Equal); + assert_eq!(b.cmp(&b), Equal); + + assert_eq!(a.cmp(&b), Less); + assert_eq!(b.cmp(&a), Greater); +} diff --git a/src/test/run-pass/deriving-self-lifetime.rs b/src/test/run-pass/deriving-self-lifetime.rs new file mode 100644 index 00000000000..549a9b398a2 --- /dev/null +++ b/src/test/run-pass/deriving-self-lifetime.rs @@ -0,0 +1,33 @@ +// 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. + +#[deriving(Eq,Ord)] +struct A<'self> { + x: &'self int +} + +fn main() { + let a = A { x: &1 }, b = A { x: &2 }; + + assert_eq!(a, a); + assert_eq!(b, b); + + + assert!(a < b); + assert!(b > a); + + assert!(a <= b); + assert!(a <= a); + assert!(b <= b); + + assert!(b >= a); + assert!(b >= b); + assert!(a >= a); +} diff --git a/src/test/run-pass/deriving-to-str.rs b/src/test/run-pass/deriving-to-str.rs new file mode 100644 index 00000000000..4b98f9a73c5 --- /dev/null +++ b/src/test/run-pass/deriving-to-str.rs @@ -0,0 +1,45 @@ +// xfail-fast #6330 +// 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. + +#[deriving(Rand,ToStr)] +struct A; + +#[deriving(Rand,ToStr)] +struct B(int, int); + +#[deriving(Rand,ToStr)] +struct C { + x: f64, + y: (u8, u8) +} + +#[deriving(Rand,ToStr)] +enum D { + D0, + D1(uint), + D2 { x: (), y: () } +} + +fn main() { + macro_rules! t( + ($ty:ty) => {{ + let x =rand::random::<$ty>(); + assert_eq!(x.to_str(), fmt!("%?", x)); + }} + ); + + for 20.times { + t!(A); + t!(B); + t!(C); + t!(D); + } +} \ No newline at end of file diff --git a/src/test/run-pass/dupe-first-attr.rc b/src/test/run-pass/dupe-first-attr.rc index d39a2aa4476..9bd63a8d646 100644 --- a/src/test/run-pass/dupe-first-attr.rc +++ b/src/test/run-pass/dupe-first-attr.rc @@ -25,3 +25,5 @@ mod hello; #[cfg(target_os = "android")] mod hello; + +fn main() { } \ No newline at end of file diff --git a/src/test/run-pass/extern-pass-TwoU64s-ref.rs b/src/test/run-pass/extern-pass-TwoU64s-ref.rs index 2b18dba90f7..19b99eaccc9 100644 --- a/src/test/run-pass/extern-pass-TwoU64s-ref.rs +++ b/src/test/run-pass/extern-pass-TwoU64s-ref.rs @@ -16,7 +16,7 @@ struct TwoU64s { } pub extern { - pub fn rust_dbg_extern_identity_TwoU64s(&&u: TwoU64s) -> TwoU64s; + pub fn rust_dbg_extern_identity_TwoU64s(u: TwoU64s) -> TwoU64s; } pub fn main() { diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs index f9b0ccbb548..1cd709ee91b 100644 --- a/src/test/run-pass/extern-pub.rs +++ b/src/test/run-pass/extern-pub.rs @@ -1,7 +1,7 @@ extern { - pub unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc, - ++v: **vec::raw::VecRepr, - ++n: libc::size_t); + pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + v: **vec::raw::VecRepr, + n: libc::size_t); } pub fn main() { diff --git a/src/test/run-pass/fn-bare-spawn.rs b/src/test/run-pass/fn-bare-spawn.rs index 857a8cdb3d0..b78bd488bc6 100644 --- a/src/test/run-pass/fn-bare-spawn.rs +++ b/src/test/run-pass/fn-bare-spawn.rs @@ -14,7 +14,7 @@ fn spawn<T:Owned>(val: T, f: extern fn(T)) { f(val); } -fn f(+i: int) { +fn f(i: int) { assert!(i == 100); } diff --git a/src/test/run-pass/foreign-struct.rs b/src/test/run-pass/foreign-struct.rs index 9ac17c27ed4..2dbc60e9a14 100644 --- a/src/test/run-pass/foreign-struct.rs +++ b/src/test/run-pass/foreign-struct.rs @@ -18,7 +18,7 @@ mod bindgen { #[nolink] pub extern { - pub fn printf(++v: void); + pub fn printf(v: void); } } diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs index adc085d2108..cce3d8066ec 100644 --- a/src/test/run-pass/intrinsic-alignment.rs +++ b/src/test/run-pass/intrinsic-alignment.rs @@ -22,6 +22,7 @@ mod rusti { #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] mod m { + #[main] #[cfg(target_arch = "x86")] pub fn main() { unsafe { @@ -30,6 +31,7 @@ mod m { } } + #[main] #[cfg(target_arch = "x86_64")] pub fn main() { unsafe { @@ -41,6 +43,7 @@ mod m { #[cfg(target_os = "win32")] mod m { + #[main] #[cfg(target_arch = "x86")] pub fn main() { unsafe { @@ -52,6 +55,7 @@ mod m { #[cfg(target_os = "android")] mod m { + #[main] #[cfg(target_arch = "arm")] pub fn main() { unsafe { diff --git a/src/test/run-pass/intrinsic-move-val.rs b/src/test/run-pass/intrinsic-move-val.rs index 966061a8085..9f683d20898 100644 --- a/src/test/run-pass/intrinsic-move-val.rs +++ b/src/test/run-pass/intrinsic-move-val.rs @@ -11,8 +11,8 @@ mod rusti { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { - pub fn move_val_init<T>(dst: &mut T, +src: T); - pub fn move_val<T>(dst: &mut T, +src: T); + pub fn move_val_init<T>(dst: &mut T, src: T); + pub fn move_val<T>(dst: &mut T, src: T); } } diff --git a/src/test/run-pass/issue-2633-2.rs b/src/test/run-pass/issue-2633-2.rs index 2c3b4b71bb8..71a491b8a39 100644 --- a/src/test/run-pass/issue-2633-2.rs +++ b/src/test/run-pass/issue-2633-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn a_val(&&x: ~int, +y: ~int) -> int { +fn a_val(x: ~int, y: ~int) -> int { *x + *y } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index f54d3d39831..acd26a88a73 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -53,23 +53,23 @@ pub mod pipes { // We should consider moving this to ::core::unsafe, although I // suspect graydon would want us to use void pointers instead. - pub unsafe fn uniquify<T>(+x: *T) -> ~T { + pub unsafe fn uniquify<T>(x: *T) -> ~T { unsafe { cast::transmute(x) } } - pub fn swap_state_acq(+dst: &mut state, src: state) -> state { + pub fn swap_state_acq(dst: &mut state, src: state) -> state { unsafe { transmute(rusti::atomic_xchg_acq(transmute(dst), src as int)) } } - pub fn swap_state_rel(+dst: &mut state, src: state) -> state { + pub fn swap_state_rel(dst: &mut state, src: state) -> state { unsafe { transmute(rusti::atomic_xchg_rel(transmute(dst), src as int)) } } - pub fn send<T:Owned>(mut p: send_packet<T>, +payload: T) { + pub fn send<T:Owned>(mut p: send_packet<T>, payload: T) { let mut p = p.unwrap(); let mut p = unsafe { uniquify(p) }; assert!((*p).payload.is_none()); @@ -229,7 +229,7 @@ pub mod pingpong { pub struct ping(::pipes::send_packet<pong>); pub struct pong(::pipes::send_packet<ping>); - pub fn liberate_ping(+p: ping) -> ::pipes::send_packet<pong> { + pub fn liberate_ping(p: ping) -> ::pipes::send_packet<pong> { unsafe { let addr : *::pipes::send_packet<pong> = match &p { &ping(ref x) => { cast::transmute(x) } @@ -240,7 +240,7 @@ pub mod pingpong { } } - pub fn liberate_pong(+p: pong) -> ::pipes::send_packet<ping> { + pub fn liberate_pong(p: pong) -> ::pipes::send_packet<ping> { unsafe { let addr : *::pipes::send_packet<ping> = match &p { &pong(ref x) => { cast::transmute(x) } @@ -262,14 +262,14 @@ pub mod pingpong { pub type ping = ::pipes::send_packet<pingpong::ping>; pub type pong = ::pipes::recv_packet<pingpong::pong>; - pub fn do_ping(+c: ping) -> pong { + pub fn do_ping(c: ping) -> pong { let (sp, rp) = ::pipes::entangle(); ::pipes::send(c, pingpong::ping(sp)); rp } - pub fn do_pong(+c: pong) -> (ping, ()) { + pub fn do_pong(c: pong) -> (ping, ()) { let packet = ::pipes::recv(c); if packet.is_none() { fail!(~"sender closed the connection") @@ -284,7 +284,7 @@ pub mod pingpong { pub type ping = ::pipes::recv_packet<pingpong::ping>; pub type pong = ::pipes::send_packet<pingpong::pong>; - pub fn do_ping(+c: ping) -> (pong, ()) { + pub fn do_ping(c: ping) -> (pong, ()) { let packet = ::pipes::recv(c); if packet.is_none() { fail!(~"sender closed the connection") @@ -292,7 +292,7 @@ pub mod pingpong { (pingpong::liberate_ping(packet.unwrap()), ()) } - pub fn do_pong(+c: pong) -> ping { + pub fn do_pong(c: pong) -> ping { let (sp, rp) = ::pipes::entangle(); ::pipes::send(c, pingpong::pong(sp)); rp @@ -300,14 +300,14 @@ pub mod pingpong { } } -fn client(+chan: pingpong::client::ping) { +fn client(chan: pingpong::client::ping) { let chan = pingpong::client::do_ping(chan); error!(~"Sent ping"); let (_chan, _data) = pingpong::client::do_pong(chan); error!(~"Received pong"); } -fn server(+chan: pingpong::server::ping) { +fn server(chan: pingpong::server::ping) { let (chan, _data) = pingpong::server::do_ping(chan); error!(~"Received ping"); let _chan = pingpong::server::do_pong(chan); diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 77cc6b3e1b5..112aab597f0 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -59,7 +59,7 @@ fn square_from_char(c: char) -> square { } } -fn read_board_grid<rdr:'static + io::Reader>(+in: rdr) -> ~[~[square]] { +fn read_board_grid<rdr:'static + io::Reader>(in: rdr) -> ~[~[square]] { let in = @in as @io::Reader; let mut grid = ~[]; for in.each_line |line| { diff --git a/src/test/run-pass/issue-3176.rs b/src/test/run-pass/issue-3176.rs index 55d62a5bf8e..d22c7e82ad5 100644 --- a/src/test/run-pass/issue-3176.rs +++ b/src/test/run-pass/issue-3176.rs @@ -26,7 +26,8 @@ pub fn main() { c2.send(()); error!("child blocks"); let (p, c) = comm::stream(); - (p, p3).select(); + let mut tuple = (p, p3); + tuple.select(); c.send(()); }; error!("parent tries"); diff --git a/src/test/run-pass/issue-3656.rs b/src/test/run-pass/issue-3656.rs index b59810fc188..895e90beef4 100644 --- a/src/test/run-pass/issue-3656.rs +++ b/src/test/run-pass/issue-3656.rs @@ -24,7 +24,7 @@ struct KEYGEN { extern { // Bogus signature, just need to test if it compiles. - pub fn malloc(++data: KEYGEN); + pub fn malloc(data: KEYGEN); } pub fn main() { diff --git a/src/test/run-pass/iter-min-max.rs b/src/test/run-pass/iter-min-max.rs index a8831a9c5ad..5f427861e79 100644 --- a/src/test/run-pass/iter-min-max.rs +++ b/src/test/run-pass/iter-min-max.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn is_even(&&x: uint) -> bool { (x % 2u) == 0u } +fn is_even(x: uint) -> bool { (x % 2u) == 0u } pub fn main() { assert!([1u, 3u].min() == 1u); diff --git a/src/test/run-pass/liveness-move-in-loop.rs b/src/test/run-pass/liveness-move-in-loop.rs index 658885124c2..acdf388a8ff 100644 --- a/src/test/run-pass/liveness-move-in-loop.rs +++ b/src/test/run-pass/liveness-move-in-loop.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn take(+x: int) -> int {x} +fn take(x: int) -> int {x} fn the_loop() { let mut list = ~[]; diff --git a/src/test/run-pass/morestack5.rs b/src/test/run-pass/morestack5.rs index 1d232cc5cbd..e1561db8b91 100644 --- a/src/test/run-pass/morestack5.rs +++ b/src/test/run-pass/morestack5.rs @@ -12,7 +12,7 @@ extern mod std; -fn getbig(&&i: int) { +fn getbig(i: int) { if i != 0 { getbig(i - 1); } diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs index 1f908936aef..dafdd0fba48 100644 --- a/src/test/run-pass/morestack6.rs +++ b/src/test/run-pass/morestack6.rs @@ -62,7 +62,7 @@ pub fn main() { calllink09, calllink10 ]; - let rng = rand::rng(); + let mut rng = rand::rng(); for fns.each |f| { let f = *f; let sz = rng.next() % 256u32 + 256u32; diff --git a/src/test/run-pass/move-arg-2-unique.rs b/src/test/run-pass/move-arg-2-unique.rs index dbc73c20e6b..ed3cdc81c31 100644 --- a/src/test/run-pass/move-arg-2-unique.rs +++ b/src/test/run-pass/move-arg-2-unique.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn test(+foo: ~~[int]) { assert!((foo[0] == 10)); } +fn test(foo: ~~[int]) { assert!((foo[0] == 10)); } pub fn main() { let x = ~~[10]; diff --git a/src/test/run-pass/move-arg-2.rs b/src/test/run-pass/move-arg-2.rs index 5cc309d1a3e..fc909da8b03 100644 --- a/src/test/run-pass/move-arg-2.rs +++ b/src/test/run-pass/move-arg-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn test(+foo: @~[int]) { assert!((foo[0] == 10)); } +fn test(foo: @~[int]) { assert!((foo[0] == 10)); } pub fn main() { let x = @~[10]; diff --git a/src/test/run-pass/move-arg.rs b/src/test/run-pass/move-arg.rs index ca3a5509c5c..87db5cbe2f1 100644 --- a/src/test/run-pass/move-arg.rs +++ b/src/test/run-pass/move-arg.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn test(+foo: int) { assert!((foo == 10)); } +fn test(foo: int) { assert!((foo == 10)); } pub fn main() { let x = 10; test(x); } diff --git a/src/test/run-pass/move-nullary-fn.rs b/src/test/run-pass/move-nullary-fn.rs index eb4c5f871af..ab66bb93635 100644 --- a/src/test/run-pass/move-nullary-fn.rs +++ b/src/test/run-pass/move-nullary-fn.rs @@ -9,9 +9,9 @@ // except according to those terms. // Issue #922 -fn f2(+thing: @fn()) { } +fn f2(thing: @fn()) { } -fn f(+thing: @fn()) { +fn f(thing: @fn()) { f2(thing); } diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index ffd6903d7f7..8c26dfa1fac 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -40,7 +40,7 @@ impl ops::Not<Point> for Point { } impl ops::Index<bool,int> for Point { - fn index(&self, +x: &bool) -> int { + fn index(&self, x: &bool) -> int { if *x { self.x } else { self.y } } } diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs index 0efed2708f4..8698d1f39a8 100644 --- a/src/test/run-pass/option-unwrap.rs +++ b/src/test/run-pass/option-unwrap.rs @@ -23,7 +23,7 @@ impl Drop for dtor { } } -fn unwrap<T>(+o: Option<T>) -> T { +fn unwrap<T>(o: Option<T>) -> T { match o { Some(v) => v, None => fail!() diff --git a/src/test/run-pass/pass-by-copy.rs b/src/test/run-pass/pass-by-copy.rs index c3ab589b66c..c4f328940c4 100644 --- a/src/test/run-pass/pass-by-copy.rs +++ b/src/test/run-pass/pass-by-copy.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn magic(+x: A) { debug!(x); } -fn magic2(+x: @int) { debug!(x); } +fn magic(x: A) { debug!(x); } +fn magic2(x: @int) { debug!(x); } struct A { a: @int } diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs index c4ce1434165..5e2be7e6d08 100644 --- a/src/test/run-pass/pipe-bank-proto.rs +++ b/src/test/run-pass/pipe-bank-proto.rs @@ -48,12 +48,12 @@ macro_rules! move_it ( { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } } ) -fn switch<T:Owned,U>(+endp: pipes::RecvPacket<T>, - f: &fn(+v: Option<T>) -> U) -> U { +fn switch<T:Owned,U>(endp: pipes::RecvPacket<T>, + f: &fn(v: Option<T>) -> U) -> U { f(pipes::try_recv(endp)) } -fn move_it<T>(+x: T) -> T { x } +fn move_it<T>(x: T) -> T { x } macro_rules! follow ( { @@ -68,7 +68,7 @@ macro_rules! follow ( ); ) -fn client_follow(+bank: bank::client::login) { +fn client_follow(bank: bank::client::login) { use bank::*; let bank = client::login(bank, ~"theincredibleholk", ~"1234"); @@ -89,7 +89,7 @@ fn client_follow(+bank: bank::client::login) { )); } -fn bank_client(+bank: bank::client::login) { +fn bank_client(bank: bank::client::login) { use bank::*; let bank = client::login(bank, ~"theincredibleholk", ~"1234"); diff --git a/src/test/run-pass/pipe-peek.rs b/src/test/run-pass/pipe-peek.rs index 46fbb88aef2..985eaecdc78 100644 --- a/src/test/run-pass/pipe-peek.rs +++ b/src/test/run-pass/pipe-peek.rs @@ -22,11 +22,11 @@ proto! oneshot ( ) pub fn main() { - let (c, p) = oneshot::init(); + let mut (c, p) = oneshot::init(); - assert!(!pipes::peek(&p)); + assert!(!pipes::peek(&mut p)); oneshot::client::signal(c); - assert!(pipes::peek(&p)); + assert!(pipes::peek(&mut p)); } diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs index 69d87804b42..3c37371a537 100644 --- a/src/test/run-pass/pipe-pingpong-bounded.rs +++ b/src/test/run-pass/pipe-pingpong-bounded.rs @@ -40,7 +40,7 @@ mod pingpong { do pipes::entangle_buffer(buffer) |buffer, data| { data.ping.set_buffer(buffer); data.pong.set_buffer(buffer); - ptr::to_unsafe_ptr(&(data.ping)) + ptr::to_mut_unsafe_ptr(&mut (data.ping)) } } pub struct ping(server::pong); @@ -50,11 +50,11 @@ mod pingpong { use core::pipes::*; use core::ptr; - pub fn ping(+pipe: ping) -> pong { + pub fn ping(mut pipe: ping) -> pong { { - let b = pipe.reuse_buffer(); - let s = SendPacketBuffered(&b.buffer.data.pong); - let c = RecvPacketBuffered(&b.buffer.data.pong); + let mut b = pipe.reuse_buffer(); + let s = SendPacketBuffered(&mut b.buffer.data.pong); + let c = RecvPacketBuffered(&mut b.buffer.data.pong); let message = ::pingpong::ping(s); send(pipe, message); c @@ -72,11 +72,11 @@ mod pingpong { pub type ping = pipes::RecvPacketBuffered<::pingpong::ping, ::pingpong::Packets>; - pub fn pong(+pipe: pong) -> ping { + pub fn pong(mut pipe: pong) -> ping { { - let b = pipe.reuse_buffer(); - let s = SendPacketBuffered(&b.buffer.data.ping); - let c = RecvPacketBuffered(&b.buffer.data.ping); + let mut b = pipe.reuse_buffer(); + let s = SendPacketBuffered(&mut b.buffer.data.ping); + let c = RecvPacketBuffered(&mut b.buffer.data.ping); let message = ::pingpong::pong(s); send(pipe, message); c @@ -91,7 +91,7 @@ mod test { use core::pipes::recv; use pingpong::{ping, pong}; - pub fn client(+chan: ::pingpong::client::ping) { + pub fn client(chan: ::pingpong::client::ping) { use pingpong::client; let chan = client::ping(chan); return; @@ -100,7 +100,7 @@ mod test { error!("Received pong"); } - pub fn server(+chan: ::pingpong::server::ping) { + pub fn server(chan: ::pingpong::server::ping) { use pingpong::server; let ping(chan) = recv(chan); return; diff --git a/src/test/run-pass/pipe-pingpong-proto.rs b/src/test/run-pass/pipe-pingpong-proto.rs index d1198f3611d..5978438ef76 100644 --- a/src/test/run-pass/pipe-pingpong-proto.rs +++ b/src/test/run-pass/pipe-pingpong-proto.rs @@ -29,7 +29,7 @@ mod test { use core::pipes::recv; use pingpong::{ping, pong}; - pub fn client(+chan: ::pingpong::client::ping) { + pub fn client(chan: ::pingpong::client::ping) { use pingpong::client; let chan = client::ping(chan); @@ -38,7 +38,7 @@ mod test { error!(~"Received pong"); } - pub fn server(+chan: ::pingpong::server::ping) { + pub fn server(chan: ::pingpong::server::ping) { use pingpong::server; let ping(chan) = recv(chan); diff --git a/src/test/run-pass/pipe-presentation-examples.rs b/src/test/run-pass/pipe-presentation-examples.rs index 01f68929b90..fcfd77dab0a 100644 --- a/src/test/run-pass/pipe-presentation-examples.rs +++ b/src/test/run-pass/pipe-presentation-examples.rs @@ -1,4 +1,8 @@ // xfail-fast +// xfail-test + +// XFAIL'd because this is going to be revamped, and it's not compatible as +// written with the new mutability rules. // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at diff --git a/src/test/run-pass/platform_thread.rs b/src/test/run-pass/platform_thread.rs index 5e4830b0bbd..774f2470b3c 100644 --- a/src/test/run-pass/platform_thread.rs +++ b/src/test/run-pass/platform_thread.rs @@ -24,9 +24,15 @@ fn run(i: int) { return; } - do task::task().sched_mode(task::PlatformThread).unlinked().spawn { + let mut builder = task::task(); + builder.sched_mode(task::PlatformThread); + builder.unlinked(); + do builder.spawn { task::yield(); - do task::task().sched_mode(task::SingleThreaded).unlinked().spawn { + let mut builder = task::task(); + builder.sched_mode(task::SingleThreaded); + builder.unlinked(); + do builder.spawn { task::yield(); run(i - 1); task::yield(); diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 5b01d24aa8b..5255c13bead 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -633,7 +633,7 @@ impl TyVisitor for my_visitor { fn visit_closure_ptr(&self, _ck: uint) -> bool { true } } -fn get_tydesc_for<T>(&&_t: T) -> *TyDesc { +fn get_tydesc_for<T>(_t: T) -> *TyDesc { get_tydesc::<T>() } diff --git a/src/test/run-pass/regions-copy-closure.rs b/src/test/run-pass/regions-copy-closure.rs index 308528ef572..2e9ff88f96e 100644 --- a/src/test/run-pass/regions-copy-closure.rs +++ b/src/test/run-pass/regions-copy-closure.rs @@ -12,7 +12,7 @@ struct closure_box<'self> { cl: &'self fn(), } -fn box_it<'r>(+x: &'r fn()) -> closure_box<'r> { +fn box_it<'r>(x: &'r fn()) -> closure_box<'r> { closure_box {cl: x} } diff --git a/src/test/run-pass/regions-static-closure.rs b/src/test/run-pass/regions-static-closure.rs index 5221bc28fb8..eab057548ef 100644 --- a/src/test/run-pass/regions-static-closure.rs +++ b/src/test/run-pass/regions-static-closure.rs @@ -12,7 +12,7 @@ struct closure_box<'self> { cl: &'self fn(), } -fn box_it<'r>(+x: &'r fn()) -> closure_box<'r> { +fn box_it<'r>(x: &'r fn()) -> closure_box<'r> { closure_box {cl: x} } diff --git a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs index afed0bd9ac3..2a69b2ca017 100644 --- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs +++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs @@ -12,7 +12,7 @@ use core::cell::Cell; pub fn main() { test05(); } -fn test05_start(&&f: ~fn(int)) { +fn test05_start(f: ~fn(int)) { f(22); } diff --git a/src/test/run-pass/simd-type.rs b/src/test/run-pass/simd-type.rs new file mode 100644 index 00000000000..c3bcc9d0b7a --- /dev/null +++ b/src/test/run-pass/simd-type.rs @@ -0,0 +1,9 @@ +#[simd] +struct RGBA { + r: f32, + g: f32, + b: f32, + a: f32 +} + +fn main() {} diff --git a/src/test/run-pass/spawn.rs b/src/test/run-pass/spawn.rs index 63c2b7da38f..9a5131ef230 100644 --- a/src/test/run-pass/spawn.rs +++ b/src/test/run-pass/spawn.rs @@ -17,4 +17,4 @@ pub fn main() { task::spawn(|| child(10) ); } -fn child(&&i: int) { error!(i); assert!((i == 10)); } +fn child(i: int) { error!(i); assert!((i == 10)); } diff --git a/src/test/run-pass/spawn2.rs b/src/test/run-pass/spawn2.rs index e748a1636ea..642babb5a1e 100644 --- a/src/test/run-pass/spawn2.rs +++ b/src/test/run-pass/spawn2.rs @@ -11,7 +11,7 @@ pub fn main() { task::spawn(|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); } -fn child(&&args: (int, int, int, int, int, int, int, int, int)) { +fn child(args: (int, int, int, int, int, int, int, int, int)) { let (i1, i2, i3, i4, i5, i6, i7, i8, i9) = args; error!(i1); error!(i2); diff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs index 973897cd145..e06d09c564c 100644 --- a/src/test/run-pass/static-method-test.rs +++ b/src/test/run-pass/static-method-test.rs @@ -13,7 +13,7 @@ // A trait for objects that can be used to do an if-then-else // (No actual need for this to be static, but it is a simple test.) trait bool_like { - fn select<A>(b: Self, +x1: A, +x2: A) -> A; + fn select<A>(b: Self, x1: A, x2: A) -> A; } fn andand<T:bool_like + Copy>(x1: T, x2: T) -> T { @@ -21,38 +21,38 @@ fn andand<T:bool_like + Copy>(x1: T, x2: T) -> T { } impl bool_like for bool { - fn select<A>(&&b: bool, +x1: A, +x2: A) -> A { + fn select<A>(b: bool, x1: A, x2: A) -> A { if b { x1 } else { x2 } } } impl bool_like for int { - fn select<A>(&&b: int, +x1: A, +x2: A) -> A { + fn select<A>(b: int, x1: A, x2: A) -> A { if b != 0 { x1 } else { x2 } } } // A trait for sequences that can be constructed imperatively. trait buildable<A> { - fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> Self; + fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> Self; } impl<A> buildable<A> for @[A] { #[inline(always)] - fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> @[A] { + fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] { at_vec::build_sized(size, builder) } } impl<A> buildable<A> for ~[A] { #[inline(always)] - fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> ~[A] { + fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] { vec::build_sized(size, builder) } } #[inline(always)] -fn build<A, B: buildable<A>>(builder: &fn(push: &fn(+v: A))) -> B { +fn build<A, B: buildable<A>>(builder: &fn(push: &fn(v: A))) -> B { buildable::build_sized(4, builder) } diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs index 5427ee38b43..7ac74fd5217 100644 --- a/src/test/run-pass/struct-return.rs +++ b/src/test/run-pass/struct-return.rs @@ -16,8 +16,8 @@ mod rustrt { #[nolink] pub extern { - pub fn debug_abi_1(++q: Quad) -> Quad; - pub fn debug_abi_2(++f: Floats) -> Floats; + pub fn debug_abi_1(q: Quad) -> Quad; + pub fn debug_abi_2(f: Floats) -> Floats; } } diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs index b426212d872..0f0b82d7c21 100644 --- a/src/test/run-pass/task-comm-12.rs +++ b/src/test/run-pass/task-comm-12.rs @@ -12,12 +12,14 @@ extern mod std; pub fn main() { test00(); } -fn start(&&task_number: int) { debug!("Started / Finished task."); } +fn start(task_number: int) { debug!("Started / Finished task."); } fn test00() { let i: int = 0; let mut result = None; - do task::task().future_result(|+r| { result = Some(r); }).spawn { + let mut builder = task::task(); + builder.future_result(|r| result = Some(r)); + do builder.spawn { start(i) } diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index cf06deb1923..fd700475988 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -40,9 +40,9 @@ fn test00() { let mut results = ~[]; while i < number_of_tasks { let ch = po.chan(); - task::task().future_result(|+r| { - results.push(r); - }).spawn({ + let mut builder = task::task(); + builder.future_result(|r| results.push(r)); + builder.spawn({ let i = i; || test00_start(&ch, i, number_of_messages) }); diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs index a3c8dc554a6..798e9d37b55 100644 --- a/src/test/run-pass/task-comm-9.rs +++ b/src/test/run-pass/task-comm-9.rs @@ -27,8 +27,9 @@ fn test00() { let ch = p.chan(); let mut result = None; - do task::task().future_result(|+r| { result = Some(r); }).spawn - || { + let mut builder = task::task(); + builder.future_result(|r| result = Some(r)); + do builder.spawn { test00_start(&ch, number_of_messages); } diff --git a/src/test/run-pass/task-life-0.rs b/src/test/run-pass/task-life-0.rs index 3e27ffb4152..9885c5d6f3f 100644 --- a/src/test/run-pass/task-life-0.rs +++ b/src/test/run-pass/task-life-0.rs @@ -13,6 +13,6 @@ pub fn main() { task::spawn(|| child(~"Hello") ); } -fn child(&&s: ~str) { +fn child(s: ~str) { } diff --git a/src/test/run-pass/threads.rs b/src/test/run-pass/threads.rs index 288a23b855b..a72d3dd40f4 100644 --- a/src/test/run-pass/threads.rs +++ b/src/test/run-pass/threads.rs @@ -18,4 +18,4 @@ pub fn main() { debug!("main thread exiting"); } -fn child(&&x: int) { debug!(x); } +fn child(x: int) { debug!(x); } diff --git a/src/test/run-pass/unique-fn-arg-move.rs b/src/test/run-pass/unique-fn-arg-move.rs index bbb33560e32..4a6386244f1 100644 --- a/src/test/run-pass/unique-fn-arg-move.rs +++ b/src/test/run-pass/unique-fn-arg-move.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(+i: ~int) { +fn f(i: ~int) { assert!(*i == 100); } diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index 75d9979807b..2d916abf0da 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -11,7 +11,9 @@ pub fn main() { let mut result = None; - task::task().future_result(|+r| { result = Some(r); }).spawn(child); + let mut builder = task::task(); + builder.future_result(|r| { result = Some(r); }); + builder.spawn(child); error!("1"); task::yield(); error!("2"); diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index 51483121f50..f3ca5b12118 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -11,7 +11,9 @@ pub fn main() { let mut result = None; - task::task().future_result(|+r| { result = Some(r); }).spawn(child); + let mut builder = task::task(); + builder.future_result(|r| { result = Some(r); }); + builder.spawn(child); error!("1"); task::yield(); result.unwrap().recv(); |
