diff --git a/Makefile.in b/Makefile.in index fb36b4e1ac666..d78176e569999 100644 --- a/Makefile.in +++ b/Makefile.in @@ -249,7 +249,7 @@ endef # Same interface as above, but deletes rather than just listing the files. define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT - $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "Warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm -v $$MATCHES ; fi + $(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "Warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm $$MATCHES ; fi endef # We use a different strategy for LIST_ALL_OLD_GLOB_MATCHES_EXCEPT diff --git a/README.md b/README.md index f01ed1958c66c..30ad2bd112f8c 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,72 @@ This is a compiler for Rust, including standard libraries, tools and documentation. +## Quick Start -## Installation +### Windows -The Rust compiler currently must be built from a [tarball], unless you -are on Windows, in which case using the [installer][win-exe] is -recommended. +1. Download and use the [installer][win-exe]. +2. Read the [tutorial]. +2. Enjoy! -Since the Rust compiler is written in Rust, it must be built by -a precompiled "snapshot" version of itself (made in an earlier state -of development). As such, source builds require a connection to -the Internet, to fetch snapshots, and an OS that can execute the -available snapshot binaries. +> ***Note:*** Windows users should read the detailed +> [getting started][wiki-start] notes on the wiki. Even when using +> the binary installer the Windows build requires a MinGW installation, +> the precise details of which are not discussed here. + +[tutorial]: http://static.rust-lang.org/doc/tutorial.html +[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust +[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe + +### Linux / OS X + +1. Install the prerequisites (if not already installed) + * g++ 4.4 or clang++ 3.x + * python 2.6 or later (but not 3.x) + * perl 5.0 or later + * gnu make 3.81 or later + * curl +2. Download and build Rust + You can either download a [tarball] or build directly from the [repo]. + + To build from the [tarball] do: + + $ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz + $ tar -xzf rust-0.7.tar.gz + $ cd rust-0.7 + + Or to build from the [repo] do: + + $ git clone https://github.com/mozilla/rust.git + $ cd rust + + Now that you have Rust's source code, you can configure and build it: + + $ ./configure + $ make && make install + + You may need to use `sudo make install` if you do not normally have + permission to modify the destination directory. The install locations can + be adjusted by passing a `--prefix` argument to `configure`. Various other + options are also supported, pass `--help` for more information on them. + + When complete, `make install` will place several programs into + `/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the + API-documentation tool, and `rustpkg`, the Rust package manager and build + system. +3. Read the [tutorial]. +4. Enjoy! + +[repo]: https://github.com/mozilla/rust +[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz +[tutorial]: http://static.rust-lang.org/doc/tutorial.html + +## Notes + +Since the Rust compiler is written in Rust, it must be built by a +precompiled "snapshot" version of itself (made in an earlier state of +development). As such, source builds require a connection to the Internet, to +fetch snapshots, and an OS that can execute the available snapshot binaries. Snapshot binaries are currently built and tested on several platforms: @@ -25,42 +79,12 @@ Snapshot binaries are currently built and tested on several platforms: You may find that other platforms work, but these are our "tier 1" supported build environments that are most likely to work. -> ***Note:*** Windows users should read the detailed -> [getting started][wiki-start] notes on the wiki. Even when using -> the binary installer the Windows build requires a MinGW installation, -> the precise details of which are not discussed here. - -To build from source you will also need the following prerequisite -packages: - -* g++ 4.4 or clang++ 3.x -* python 2.6 or later (but not 3.x) -* perl 5.0 or later -* gnu make 3.81 or later -* curl - -Assuming you're on a relatively modern *nix system and have met the -prerequisites, something along these lines should work. - - $ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz - $ tar -xzf rust-0.7.tar.gz - $ cd rust-0.7 - $ ./configure - $ make && make install +Rust currently needs about 1.8G of RAM to build without swapping; if it hits +swap, it will take a very long time to build. -You may need to use `sudo make install` if you do not normally have -permission to modify the destination directory. The install locations -can be adjusted by passing a `--prefix` argument to -`configure`. Various other options are also supported, pass `--help` -for more information on them. +There is lots more documentation in the [wiki]. -When complete, `make install` will place several programs into -`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the -API-documentation tool, and `rustpkg`, the Rust package manager and build system. - -[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust -[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz -[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe +[wiki]: https://github.com/mozilla/rust/wiki ## License @@ -71,8 +95,3 @@ BSD-like licenses. See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details. -## More help - -The [tutorial] is a good starting point. - -[tutorial]: http://static.rust-lang.org/doc/tutorial.html diff --git a/doc/rust.md b/doc/rust.md index cbe239e21580e..e98edd229b8d5 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -573,8 +573,7 @@ The top level of this tree is a module that is anonymous (from the point of view The Rust compiler is always invoked with a single source file as input, and always produces a single output crate. The processing of that source file may result in other source files being loaded as modules. -Source files typically have the extension `.rs` but, by convention, -source files that represent crates have the extension `.rc`, called *crate files*. +Source files have the extension `.rs`. A Rust source file describes a module, the name and location of which -- in the module tree of the current crate -- are defined @@ -3286,7 +3285,7 @@ As an example, to see all the logs generated by the compiler, you would set you would set it to `rustc::metadata::creader`. To see just error logging use `rustc=0`. -Note that when compiling either `.rs` or `.rc` files that don't specify a +Note that when compiling source files that don't specify a crate name the crate is given a default name that matches the source file, with the extension removed. In that case, to turn on logging for a program compiled from, e.g. `helloworld.rs`, `RUST_LOG` should be set to `helloworld`. diff --git a/src/libextra/future.rs b/src/libextra/future.rs index 2d3da5bb96d1c..d8f21b460138e 100644 --- a/src/libextra/future.rs +++ b/src/libextra/future.rs @@ -60,6 +60,19 @@ impl Future { } } +impl Future { + /// Gets the value from this future, forcing evaluation. + pub fn unwrap(self) -> A { + let mut this = self; + this.get_ref(); + let state = replace(&mut this.state, Evaluating); + match state { + Forced(v) => v, + _ => fail!( "Logic error." ), + } + } +} + impl Future { pub fn get_ref<'a>(&'a mut self) -> &'a A { /*! @@ -179,6 +192,12 @@ mod test { assert_eq!(f.get(), ~"fail"); } + #[test] + fn test_interface_unwrap() { + let mut f = from_value(~"fail"); + assert_eq!(f.unwrap(), ~"fail"); + } + #[test] fn test_get_ref_method() { let mut f = from_value(22); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 86d30be7d4111..5e086f94f2867 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -13,15 +13,12 @@ use back::abi; use back::link::{mangle_internal_name_by_path_and_seq}; use lib::llvm::{llvm, ValueRef}; use middle::moves; -use middle::lang_items::ClosureExchangeMallocFnLangItem; use middle::trans::base::*; use middle::trans::build::*; -use middle::trans::callee; use middle::trans::common::*; use middle::trans::datum::{Datum, INIT, ByRef, ZeroMem}; use middle::trans::expr; use middle::trans::glue; -use middle::trans::machine; use middle::trans::type_of::*; use middle::ty; use util::ppaux::ty_to_str; @@ -508,52 +505,9 @@ pub fn make_opaque_cbox_take_glue( return bcx; } ast::OwnedSigil => { - /* hard case: fallthrough to code below */ + fail!("unique closures are not copyable") } } - - // ~fn requires a deep copy. - let ccx = bcx.ccx(); - let tcx = ccx.tcx; - let llopaquecboxty = Type::opaque_box(ccx).ptr_to(); - let cbox_in = Load(bcx, cboxptr); - do with_cond(bcx, IsNotNull(bcx, cbox_in)) |bcx| { - // Load the size from the type descr found in the cbox - let cbox_in = PointerCast(bcx, cbox_in, llopaquecboxty); - let tydescptr = GEPi(bcx, cbox_in, [0u, abi::box_field_tydesc]); - let tydesc = Load(bcx, tydescptr); - let tydesc = PointerCast(bcx, tydesc, ccx.tydesc_type.ptr_to()); - let sz = Load(bcx, GEPi(bcx, tydesc, [0u, abi::tydesc_field_size])); - - // Adjust sz to account for the rust_opaque_box header fields - let sz = Add(bcx, sz, machine::llsize_of(ccx, Type::box_header(ccx))); - - // Allocate memory, update original ptr, and copy existing data - let opaque_tydesc = PointerCast(bcx, tydesc, Type::i8p()); - let mut bcx = bcx; - let alloc_fn = langcall(bcx, None, - fmt!("allocation of type with sigil `%s`", - sigil.to_str()), - ClosureExchangeMallocFnLangItem); - let llresult = unpack_result!(bcx, callee::trans_lang_call( - bcx, - alloc_fn, - [opaque_tydesc, sz], - None)); - let cbox_out = PointerCast(bcx, llresult, llopaquecboxty); - call_memcpy(bcx, cbox_out, cbox_in, sz, 1); - Store(bcx, cbox_out, cboxptr); - - // Take the (deeply cloned) type descriptor - let tydesc_out = GEPi(bcx, cbox_out, [0u, abi::box_field_tydesc]); - let bcx = glue::take_ty(bcx, tydesc_out, ty::mk_type(tcx)); - - // Take the data in the tuple - let cdata_out = GEPi(bcx, cbox_out, [0u, abi::box_field_body]); - glue::call_tydesc_glue_full(bcx, cdata_out, tydesc, - abi::tydesc_field_take_glue, None); - bcx - } } pub fn make_opaque_cbox_drop_glue( diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index b717445a22f4e..ffe6d22d5814f 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -93,26 +93,6 @@ pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { } } -pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result { - let _icx = push_ctxt("take_ty_immediate"); - match ty::get(t).sty { - ty::ty_box(_) | ty::ty_opaque_box | - ty::ty_evec(_, ty::vstore_box) | - ty::ty_estr(ty::vstore_box) => { - incr_refcnt_of_boxed(bcx, v); - rslt(bcx, v) - } - ty::ty_uniq(_) => { - uniq::duplicate(bcx, v, t) - } - ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_estr(ty::vstore_uniq) => { - tvec::duplicate_uniq(bcx, v, t) - } - _ => rslt(bcx, v) - } -} - pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block { // NB: v is an *alias* of type t here, not a direct value. let _icx = push_ctxt("free_ty"); @@ -589,23 +569,15 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) -> block { ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => { incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx } - ty::ty_uniq(_) => { - let Result {bcx, val} = uniq::duplicate(bcx, Load(bcx, v), t); - Store(bcx, val, v); - bcx - } - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { - let Result {bcx, val} = tvec::duplicate_uniq(bcx, Load(bcx, v), t); - Store(bcx, val, v); - bcx - } ty::ty_evec(_, ty::vstore_slice(_)) | ty::ty_estr(ty::vstore_slice(_)) => { bcx } - ty::ty_closure(_) => { + ty::ty_closure(ty::ClosureTy { sigil: ast::BorrowedSigil, _ }) | + ty::ty_closure(ty::ClosureTy { sigil: ast::ManagedSigil, _ }) => { closure::make_closure_glue(bcx, v, t, take_ty) } + ty::ty_closure(ty::ClosureTy { sigil: ast::OwnedSigil, _ }) => bcx, ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => { let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box])); incr_refcnt_of_boxed(bcx, llbox); diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index be840f6a295dc..8aca10f9b92e2 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -130,23 +130,6 @@ pub fn alloc_vec(bcx: block, return rslt(bcx, vptr); } -pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result { - let _icx = push_ctxt("tvec::duplicate_uniq"); - - let fill = get_fill(bcx, get_bodyptr(bcx, vptr, vec_ty)); - let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); - let Result {bcx, val: newptr} = alloc_uniq_raw(bcx, unit_ty, fill, fill); - - let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty)); - let new_data_ptr = get_dataptr(bcx, get_bodyptr(bcx, newptr, vec_ty)); - base::call_memcpy(bcx, new_data_ptr, data_ptr, fill, 1); - - let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) { - iter_vec_raw(bcx, new_data_ptr, vec_ty, fill, glue::take_ty) - } else { bcx }; - return rslt(bcx, newptr); -} - pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> block { let _icx = push_ctxt("tvec::make_drop_glue_unboxed"); diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index 7e4554357c949..e9df83549e28d 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -14,11 +14,8 @@ use middle::trans::base::*; use middle::trans::build::*; use middle::trans::common::*; use middle::trans::datum::immediate_rvalue; -use middle::trans::datum; use middle::trans::glue; use middle::ty; -use middle::trans::machine::llsize_of; -use middle::trans::type_of; pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) -> block { @@ -37,30 +34,3 @@ pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) } } } - -pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result { - let _icx = push_ctxt("uniq::duplicate"); - - // Load the body of the source (*src) - let src_datum = immediate_rvalue(src_box, src_ty); - let body_datum = src_datum.box_body(bcx); - - // Malloc space in exchange heap and copy src into it - if ty::type_contents(bcx.tcx(), src_ty).contains_managed() { - let MallocResult { - bcx: bcx, - box: dst_box, - body: dst_body - } = malloc_general(bcx, body_datum.ty, heap_managed_unique); - body_datum.copy_to(bcx, datum::INIT, dst_body); - - rslt(bcx, dst_box) - } else { - let body_datum = body_datum.to_value_datum(bcx); - let llty = type_of(bcx.ccx(), body_datum.ty); - let size = llsize_of(bcx.ccx(), llty); - let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, body_datum.ty, heap_exchange, size); - body_datum.copy_to(bcx, datum::INIT, val); - Result { bcx: bcx, val: val } - } -} diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index f24bc002a2b1e..6fd06c951917d 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -21,7 +21,7 @@ the `clone` method. */ -use core::kinds::Freeze; +use std::kinds::Freeze; /// A common trait for cloning an object. pub trait Clone { diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 1bb0ff044fe98..0acd6fee57efe 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -382,19 +382,19 @@ mod pipesy { #[allow(non_camel_case_types)] pub mod oneshot { - priv use core::kinds::Send; + priv use std::kinds::Send; use ptr::to_mut_unsafe_ptr; pub fn init() -> (server::Oneshot, client::Oneshot) { - pub use core::pipes::HasBuffer; + pub use std::pipes::HasBuffer; - let buffer = ~::core::pipes::Buffer { - header: ::core::pipes::BufferHeader(), + let buffer = ~::std::pipes::Buffer { + header: ::std::pipes::BufferHeader(), data: __Buffer { - Oneshot: ::core::pipes::mk_packet::>() + Oneshot: ::std::pipes::mk_packet::>() }, }; - do ::core::pipes::entangle_buffer(buffer) |buffer, data| { + do ::std::pipes::entangle_buffer(buffer) |buffer, data| { data.Oneshot.set_buffer(buffer); to_mut_unsafe_ptr(&mut data.Oneshot) } @@ -403,23 +403,23 @@ mod pipesy { pub enum Oneshot { pub send(T), } #[allow(non_camel_case_types)] pub struct __Buffer { - Oneshot: ::core::pipes::Packet>, + Oneshot: ::std::pipes::Packet>, } #[allow(non_camel_case_types)] pub mod client { - priv use core::kinds::Send; + priv use std::kinds::Send; #[allow(non_camel_case_types)] pub fn try_send(pipe: Oneshot, x_0: T) -> - ::core::option::Option<()> { + ::std::option::Option<()> { { use super::send; let message = send(x_0); - if ::core::pipes::send(pipe, message) { - ::core::pipes::rt::make_some(()) - } else { ::core::pipes::rt::make_none() } + if ::std::pipes::send(pipe, message) { + ::std::pipes::rt::make_some(()) + } else { ::std::pipes::rt::make_none() } } } @@ -428,13 +428,13 @@ mod pipesy { { use super::send; let message = send(x_0); - ::core::pipes::send(pipe, message); + ::std::pipes::send(pipe, message); } } #[allow(non_camel_case_types)] pub type Oneshot = - ::core::pipes::SendPacketBuffered, + ::std::pipes::SendPacketBuffered, super::__Buffer>; } @@ -442,7 +442,7 @@ mod pipesy { pub mod server { #[allow(non_camel_case_types)] pub type Oneshot = - ::core::pipes::RecvPacketBuffered, + ::std::pipes::RecvPacketBuffered, super::__Buffer>; } } @@ -557,11 +557,11 @@ mod pipesy { #[allow(non_camel_case_types)] pub mod streamp { - priv use core::kinds::Send; + priv use std::kinds::Send; pub fn init() -> (server::Open, client::Open) { - pub use core::pipes::HasBuffer; - ::core::pipes::entangle() + pub use std::pipes::HasBuffer; + ::std::pipes::entangle() } #[allow(non_camel_case_types)] @@ -569,18 +569,18 @@ mod pipesy { #[allow(non_camel_case_types)] pub mod client { - priv use core::kinds::Send; + priv use std::kinds::Send; #[allow(non_camel_case_types)] pub fn try_data(pipe: Open, x_0: T) -> - ::core::option::Option> { + ::std::option::Option> { { use super::data; - let (s, c) = ::core::pipes::entangle(); + let (s, c) = ::std::pipes::entangle(); let message = data(x_0, s); - if ::core::pipes::send(pipe, message) { - ::core::pipes::rt::make_some(c) - } else { ::core::pipes::rt::make_none() } + if ::std::pipes::send(pipe, message) { + ::std::pipes::rt::make_some(c) + } else { ::std::pipes::rt::make_none() } } } @@ -588,21 +588,21 @@ mod pipesy { pub fn data(pipe: Open, x_0: T) -> Open { { use super::data; - let (s, c) = ::core::pipes::entangle(); + let (s, c) = ::std::pipes::entangle(); let message = data(x_0, s); - ::core::pipes::send(pipe, message); + ::std::pipes::send(pipe, message); c } } #[allow(non_camel_case_types)] - pub type Open = ::core::pipes::SendPacket>; + pub type Open = ::std::pipes::SendPacket>; } #[allow(non_camel_case_types)] pub mod server { #[allow(non_camel_case_types)] - pub type Open = ::core::pipes::RecvPacket>; + pub type Open = ::std::pipes::RecvPacket>; } } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index b9593d845a4cb..c8cde69197b23 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -773,6 +773,17 @@ impl, U: Iterator> Iterator for ChainIterator { } } +impl, U: DoubleEndedIterator> DoubleEndedIterator +for ChainIterator { + #[inline] + fn next_back(&mut self) -> Option { + match self.b.next_back() { + Some(x) => Some(x), + None => self.a.next_back() + } + } +} + /// An iterator which iterates two other iterators simultaneously // FIXME #6967: Dummy A & B parameters to get around type inference bug pub struct ZipIterator { @@ -828,6 +839,17 @@ impl<'self, A, B, T: Iterator> Iterator for MapIterator<'self, A, B, T> { } } +impl<'self, A, B, T: DoubleEndedIterator> DoubleEndedIterator +for MapIterator<'self, A, B, T> { + #[inline] + fn next_back(&mut self) -> Option { + match self.iter.next_back() { + Some(a) => Some((self.f)(a)), + _ => None + } + } +} + /// An iterator which filters the elements of `iter` with `predicate` pub struct FilterIterator<'self, A, T> { priv iter: T, @@ -854,6 +876,24 @@ impl<'self, A, T: Iterator> Iterator for FilterIterator<'self, A, T> { } } +impl<'self, A, T: DoubleEndedIterator> DoubleEndedIterator for FilterIterator<'self, A, T> { + #[inline] + fn next_back(&mut self) -> Option { + loop { + match self.iter.next_back() { + None => return None, + Some(x) => { + if (self.predicate)(&x) { + return Some(x); + } else { + loop + } + } + } + } + } +} + /// An iterator which uses `f` to both filter and map elements from `iter` pub struct FilterMapIterator<'self, A, B, T> { priv iter: T, @@ -879,6 +919,24 @@ impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, } } +impl<'self, A, B, T: DoubleEndedIterator> DoubleEndedIterator +for FilterMapIterator<'self, A, B, T> { + #[inline] + fn next_back(&mut self) -> Option { + loop { + match self.iter.next_back() { + None => return None, + Some(x) => { + match (self.f)(x) { + Some(y) => return Some(y), + None => () + } + } + } + } + } +} + /// An iterator which yields the current count and the element during iteration // FIXME #6967: Dummy A parameter to get around type inference bug pub struct EnumerateIterator { @@ -1135,6 +1193,20 @@ impl<'self, A, T: Iterator> Iterator for PeekIterator<'self, A, T> { } } +impl<'self, A, T: DoubleEndedIterator> DoubleEndedIterator for PeekIterator<'self, A, T> { + #[inline] + fn next_back(&mut self) -> Option { + let next = self.iter.next_back(); + + match next { + Some(ref a) => (self.f)(a), + None => () + } + + next + } +} + /// An iterator which just modifies the contained state throughout iteration. pub struct UnfoldrIterator<'self, A, St> { priv f: &'self fn(&mut St) -> Option, @@ -1526,4 +1598,53 @@ mod tests { it.next(); assert_eq!(it.invert().transform(|&x| x).collect::<~[int]>(), ~[16, 14, 12, 10, 8, 6]); } + + #[test] + fn test_double_ended_map() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut it = xs.iter().transform(|&x| x * -1); + assert_eq!(it.next(), Some(-1)); + assert_eq!(it.next(), Some(-2)); + assert_eq!(it.next_back(), Some(-6)); + assert_eq!(it.next_back(), Some(-5)); + assert_eq!(it.next(), Some(-3)); + assert_eq!(it.next_back(), Some(-4)); + assert_eq!(it.next(), None); + } + + #[test] + fn test_double_ended_filter() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut it = xs.iter().filter(|&x| *x & 1 == 0); + assert_eq!(it.next_back().unwrap(), &6); + assert_eq!(it.next_back().unwrap(), &4); + assert_eq!(it.next().unwrap(), &2); + assert_eq!(it.next_back(), None); + } + + #[test] + fn test_double_ended_filter_map() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None }); + assert_eq!(it.next_back().unwrap(), 12); + assert_eq!(it.next_back().unwrap(), 8); + assert_eq!(it.next().unwrap(), 4); + assert_eq!(it.next_back(), None); + } + + #[test] + fn test_double_ended_chain() { + let xs = [1, 2, 3, 4, 5]; + let ys = ~[7, 9, 11]; + let mut it = xs.iter().chain_(ys.iter()).invert(); + assert_eq!(it.next().unwrap(), &11) + assert_eq!(it.next().unwrap(), &9) + assert_eq!(it.next_back().unwrap(), &1) + assert_eq!(it.next_back().unwrap(), &2) + assert_eq!(it.next_back().unwrap(), &3) + assert_eq!(it.next_back().unwrap(), &4) + assert_eq!(it.next_back().unwrap(), &5) + assert_eq!(it.next_back().unwrap(), &7) + assert_eq!(it.next_back(), None) + } } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index ab17c5f175a47..8e7f49464ffc2 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -12,7 +12,7 @@ use clone::Clone; use container::Container; -use core::cmp::{Ord, Eq}; +use std::cmp::{Ord, Eq}; use ops::{Add, Sub, Mul, Div, Rem, Neg}; use option::{None, Option, Some}; use char; diff --git a/src/libstd/rt/context.rs b/src/libstd/rt/context.rs index 09ba869549fd0..b30a55978f742 100644 --- a/src/libstd/rt/context.rs +++ b/src/libstd/rt/context.rs @@ -209,6 +209,6 @@ fn align_down(sp: *mut uint) -> *mut uint { // XXX: ptr::offset is positive ints only #[inline] pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { - use core::sys::size_of; + use std::sys::size_of; (ptr as int + count * (size_of::() as int)) as *mut T } diff --git a/src/libstd/std.rs b/src/libstd/std.rs index 03b895b38601a..cbf00f43c61b9 100644 --- a/src/libstd/std.rs +++ b/src/libstd/std.rs @@ -206,16 +206,6 @@ pub mod rt; // 'std' so that macro-expanded references to std::error and such // can be resolved within libstd. #[doc(hidden)] -mod core { - pub use clone; - pub use cmp; - pub use condition; - pub use option; - pub use kinds; - pub use sys; - pub use pipes; -} -#[doc(hidden)] mod std { pub use clone; pub use cmp; diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index df6f77fd6cef3..822b005de37a2 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -411,7 +411,7 @@ pub fn check_integrity(trie: &TrieNode) { #[cfg(test)] mod test_map { use super::*; - use core::option::{Some, None}; + use option::{Some, None}; use uint; #[test]